diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-07-02 15:36:20 +1000 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-07-02 15:36:20 +1000 |
commit | 1d880992fd8c8457a2d990ac6622cfd58fb1b261 (patch) | |
tree | c4c843b12e96b5612c315db5a23c5da1a900618c /doc | |
download | skiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.zip skiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.tar.gz skiboot-1d880992fd8c8457a2d990ac6622cfd58fb1b261.tar.bz2 |
Initial commit of Open Source release
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'doc')
-rw-r--r-- | doc/device-tree.txt | 516 | ||||
-rw-r--r-- | doc/error-logging.txt | 384 | ||||
-rw-r--r-- | doc/overview.txt | 116 | ||||
-rw-r--r-- | doc/pci-slot-properties.txt | 17 | ||||
-rw-r--r-- | doc/vpd-properties.txt | 19 | ||||
-rw-r--r-- | doc/xscom-node-bindings.txt | 57 |
6 files changed, 1109 insertions, 0 deletions
diff --git a/doc/device-tree.txt b/doc/device-tree.txt new file mode 100644 index 0000000..a0e4457 --- /dev/null +++ b/doc/device-tree.txt @@ -0,0 +1,516 @@ +/* + * Sapphire device-tree requirements + * + * Version: 0.2.1 + * + * This documents the generated device-tree requirements, this is based on + * a commented device-tree dump obtained from a DT generated by Sapphire + * itself from an HDAT. + */ + +/* + * General comments: + * + * - skiboot does not require nodes to have phandle properties, but + * if you have them then *all* nodes must have them including the + * root of the device-tree (currently a HB bug !). It is recommended + * to have them since they are needed to represent the cache levels. + * + * NOTE: The example tree below only has phandle properties for + * nodes that are referenced by other nodes. This is *not* correct + * and is purely done for keeping this document smaller, make sure + * to follow the rule above. + * + * - Only the "phandle" property is required. Sapphire also generates + * a "linux,phandle" for backward compatibility but doesn't require + * it as an input + * + * - Any property not specifically documented must be put in "as is" + * + * - All ibm,chip-id properties contain a HW chip ID which correspond + * on P8 to the PIR value shifted right by 7 bits, ie. it's a 6-bit + * value made of a 3-bit node number and a 3-bit chip number. + * + * - Unit addresses (@xxxx part of node names) should if possible use + * lower case hexadecimal to be consistent with what skiboot does + * and to help some stupid parsers out there... + */ + +/* + * Version history + * + * 2013/10/08 : Version 0.1 + * + * 2013/10/09 : Version 0.2 + * + * - Add comment about case of unit addresses + * - Add missing lpc node definition + * - Add example UART node on LPC + * - Remove "status" property from PSI xsco nodes + * + * 2014/03/26 : Version 0.2.1 + * + * - Fix cpus/xxx/ibm,pa-features to be a byte array + */ + +/dts-v1/; + + +/* + * Here are the reserve map entries. They should exactly match the + * reserved-ranges property of the root node (see documentation + * of that property) + */ + +/memreserve/ 0x00000007fe600000 0x0000000000100000; +/memreserve/ 0x00000007fe200000 0x0000000000100000; +/memreserve/ 0x0000000031e00000 0x00000000003e0000; +/memreserve/ 0x0000000031000000 0x0000000000e00000; +/memreserve/ 0x0000000030400000 0x0000000000c00000; +/memreserve/ 0x0000000030000000 0x0000000000400000; +/memreserve/ 0x0000000400000000 0x0000000000600450; + +/* Root node */ +/ { + /* + * "compatible" properties are string lists (ASCII strings separated by + * \0 characters) indicating the overall compatibility from the more + * specific to the least specific. + * + * The root node compatible property *must* contain "ibm,powernv" for + * Linux to have the powernv platform match the machine. It is recommended + * to add a slightly more precise property (first in order) indicating more + * precisely the board type. We don't currently do that in HDAT based + * setups but will. + * + * The standard naming is "vendor,name" so in your case, something like + * + * compatible = "goog,rhesus","ibm,powernv"; + * + * would work. Or even better: + * + * compatible = "goog,rhesus-v1","goog,rhesus","ibm,powernv"; + */ + compatible = "ibm,powernv"; + + /* mandatory */ + #address-cells = <0x2>; + #size-cells = <0x2>; + + /* User visible board name (will be shown in /proc/cpuinfo) */ + model = "Machine Name"; + + /* + * The reserved-names and reserve-names properties work hand in hand. The first one + * is a list of strings providing a "name" for each entry in the second one using + * the traditional "vendor,name" format. + * + * The reserved-ranges property contains a list of ranges, each in the form of 2 cells + * of address and 2 cells of size (64-bit x2 so each entry is 4 cells) indicating + * regions of memory that are reserved and must not be overwritten by skiboot or + * subsequently by the Linux Kernel. + * + * Corresponding entries must also be created in the "reserved map" part of the flat + * device-tree (which is a binary list in the header of the fdt). + * + * Unless a component (skiboot or Linux) specifically knows about a region (usually + * based on its name) and decides to change or remove it, all these regions are + * passed as-is to Linux and to subsequent kernels accross kexec and are kept + * preserved. + * + * NOTE: Do *NOT* copy the entries below, they are just an example and are actually + * created by skiboot itself. They represent the SLW image as "detected" by reading + * the PBA BARs and skiboot own memory allocations. + * + * I would recommend that you put in there the SLW and OCC (or HOMER as one block + * if that's how you use it) and any additional memory you want to preserve such + * as FW log buffers etc... + */ + + reserved-names = "ibm,slw-image", "ibm,slw-image", "ibm,firmware-stacks", "ibm,firmware-data", "ibm,firmware-heap", "ibm,firmware-code", "memory@400000000"; + reserved-ranges = <0x7 0xfe600000 0x0 0x100000 0x7 0xfe200000 0x0 0x100000 0x0 0x31e00000 0x0 0x3e0000 0x0 0x31000000 0x0 0xe00000 0x0 0x30400000 0x0 0xc00000 0x0 0x30000000 0x0 0x400000 0x4 0x0 0x0 0x600450>; + + /* Mandatory */ + cpus { + #address-cells = <0x1>; + #size-cells = <0x0>; + + /* + * The following node must exist for each *core* in the system. The unit + * address (number after the @) is the hexadecimal HW CPU number (PIR value) + * of thread 0 of that core. + */ + PowerPC,POWER8@20 { + /* mandatory/standard properties */ + device_type = "cpu"; + 64-bit; + 32-64-bridge; + graphics; + general-purpose; + + /* + * The "status" property indicate whether the core is functional. It's + * a string containing "okay" for a good core or "bad" for a non-functional + * one. You can also just ommit the non-functional ones from the DT + */ + status = "okay"; + + /* + * This is the same value as the PIR of thread 0 of that core + * (ie same as the @xx part of the node name) + */ + reg = <0x20>; + + /* same as above */ + ibm,pir = <0x20>; + + /* chip ID of this core */ + ibm,chip-id = <0x0>; + + /* + * interrupt server numbers (aka HW processor numbers) of all threads + * on that core. This should have 8 numbers and the first one should + * have the same value as the above ibm,pir and reg properties + */ + ibm,ppc-interrupt-server#s = <0x20 0x21 0x22 0x23 0x24 0x25 0x26 0x27>; + + /* + * This is the "architected processor version" as defined in PAPR. Just + * stick to 0x0f000004 for P8 and things will be fine + */ + cpu-version = <0x0f000004>; + + /* + * These are various definitions of the page sizes and segment sizes + * supported by the MMU, those values are fine for P8 for now + */ + ibm,processor-segment-sizes = <0x1c 0x28 0xffffffff 0xffffffff>; + ibm,processor-page-sizes = <0xc 0x10 0x18 0x22>; + ibm,segment-page-sizes = <0xc 0x0 0x3 0xc 0x0 0x10 0x7 0x18 0x38 0x10 0x110 0x2 0x10 0x1 0x18 0x8 0x18 0x100 0x1 0x18 0x0 0x22 0x120 0x1 0x22 0x3>; + + /* + * Similarily that might need to be reviewed later but will do for now... + */ + ibm,pa-features = [0x6 0x0 0xf6 0x3f 0xc7 0x0 0x80 0xc0]; + + /* SLB size, use as-is */ + ibm,slb-size = <0x20>; + + /* VSX support, use as-is */ + ibm,vmx = <0x2>; + + /* DFP support, use as-is */ + ibm,dfp = <0x2>; + + /* PURR/SPURR support, use as-is */ + ibm,purr = <0x1>; + ibm,spurr = <0x1>; + + /* + * Old-style core clock frequency. Only create this property if the frequency fits + * in a 32-bit number. Do not create it if it doesn't + */ + clock-frequency = <0xf5552d00>; + + /* + * mandatory: 64-bit version of the core clock frequency, always create this + * property. + */ + ibm,extended-clock-frequency = <0x0 0xf5552d00>; + + /* Timebase freq has a fixed value, always use that */ + timebase-frequency = <0x1e848000>; + + /* Same */ + ibm,extended-timebase-frequency = <0x0 0x1e848000>; + + /* Use as-is, values might need to be adjusted but that will do for now */ + reservation-granule-size = <0x80>; + d-tlb-size = <0x800>; + i-tlb-size = <0x0>; + tlb-size = <0x800>; + d-tlb-sets = <0x4>; + i-tlb-sets = <0x0>; + tlb-sets = <0x4>; + d-cache-block-size = <0x80>; + i-cache-block-size = <0x80>; + d-cache-size = <0x10000>; + i-cache-size = <0x8000>; + i-cache-sets = <0x4>; + d-cache-sets = <0x8>; + performance-monitor = <0x0 0x1>; + + /* + * optional: phandle of the node representing the L2 cache for this core, + * note: it can also be named "next-level-cache", Linux will support both + * and Sapphire doesn't currently use those properties, just passes them + * along to Linux + */ + l2-cache = < 0x4 >; + }; + + /* + * Cache nodes. Those are siblings of the processor nodes under /cpus and + * represent the various level of caches. + * + * The unit address (and reg property) is mostly free-for-all as long as + * there is no collisions. On HDAT machines we use the following encoding + * which I encourage you to also follow to limit surprises: + * + * L2 : (0x20 << 24) | PIR (PIR is PIR value of thread 0 of core) + * L3 : (0x30 << 24) | PIR + * L3.5 : (0x35 << 24) | PIR + * + * In addition, each cache points to the next level cache via its + * own "l2-cache" (or "next-level-cache") property, so the core node + * points to the L2, the L2 points to the L3 etc... + */ + + l2-cache@20000020 { + phandle = <0x4>; + device_type = "cache"; + reg = <0x20000020>; + status = "okay"; + cache-unified; + d-cache-sets = <0x8>; + i-cache-sets = <0x8>; + d-cache-size = <0x80000>; + i-cache-size = <0x80000>; + l2-cache = <0x5>; + }; + + l3-cache@30000020 { + phandle = <0x5>; + device_type = "cache"; + reg = <0x30000020>; + status = "bad"; + cache-unified; + d-cache-sets = <0x8>; + i-cache-sets = <0x8>; + d-cache-size = <0x800000>; + i-cache-size = <0x800000>; + }; + + }; + + /* + * Interrupt presentation controller (ICP) nodes + * + * There is some flexibility as to how many of these are presents since + * a given node can represent multiple ICPs. When generating from HDAT we + * chose to create one per core + */ + interrupt-controller@3ffff80020000 { + /* Mandatory */ + compatible = "IBM,ppc-xicp", "IBM,power8-icp"; + interrupt-controller; + #address-cells = <0x0>; + #interrupt-cells = <0x1>; + device_type = "PowerPC-External-Interrupt-Presentation"; + + /* + * Range of HW CPU IDs represented by that node. In this example + * the core starting at PIR 0x20 and 8 threads, which corresponds + * to the CPU node of the example above. The property in theory + * supports multiple ranges but Linux doesn't. + */ + ibm,interrupt-server-ranges = <0x20 0x8>; + + /* + * For each server in the above range, the physical address of the + * ICP register block and its size. Since the root node #address-cells + * and #size-cells properties are both "2", each entry is thus + * 2 cells address and 2 cells size (64-bit each). + */ + reg = <0x3ffff 0x80020000 0x0 0x1000 0x3ffff 0x80021000 0x0 0x1000 0x3ffff 0x80022000 0x0 0x1000 0x3ffff 0x80023000 0x0 0x1000 0x3ffff 0x80024000 0x0 0x1000 0x3ffff 0x80025000 0x0 0x1000 0x3ffff 0x80026000 0x0 0x1000 0x3ffff 0x80027000 0x0 0x1000>; + }; + + /* + * The "memory" nodes represent physical memory in the system. They + * do not represent DIMMs, memory controllers or Centaurs, thus will + * be expressed separately. + * + * In order to be able to handle affinity propertly, we require that + * a memory node is created for each range of memory that has a different + * "affinity", which in practice means for each chip since we don't + * support memory interleaved accross multiple chips on P8. + * + * Additionally, it is *not* required that one chip = one memory node, + * it is perfectly acceptable to break down the memory of one chip into + * multiple memory nodes (typically skiboot does that if the two MCs + * are not interlaved). + */ + memory@0 { + device_type = "memory"; + + /* + * We support multiple entries in the ibm,chip-id property for + * memory nodes in case the memory is interleaved accross multiple + * chips but that shouldn't happen on P8 + */ + ibm,chip-id = <0x0>; + + /* The "reg" property is 4 cells, as usual for a child of + * the root node, 2 cells of address and 2 cells of size + */ + reg = <0x0 0x0 0x4 0x0>; + }; + + /* + * The XSCOM node. This is the closest thing to a "chip" node we have. + * there must be one per chip in the system (thus a DCM has two) and + * while it represents the "parent" of various devices on the PIB/PCB + * that we want to expose, it is also used to store all sort of + * miscellaneous per-chip information on HDAT based systems (such + * as VPDs). + */ + xscom@3fc0000000000 { + /* standard & mandatory */ + #address-cells = <0x1>; + #size-cells = <0x1>; + scom-controller; + compatible = "ibm,xscom", "ibm,power8-xscom"; + + /* The chip ID as usual ... */ + ibm,chip-id = <0x0>; + + /* The base address of xscom for that chip */ + reg = <0x3fc00 0x0 0x8 0x0>; + + /* + * This comes from HDAT and I *think* is the raw content of the + * module VPD eeprom (and thus doesn't have a standard ASCII keyword + * VPD format). We don't currently use it though ... + */ + ibm,module-vpd = < ... big pile of binary data ... >; + + /* PSI host bridge XSCOM register set */ + psihb@2010900 { + reg = <0x2010900 0x20>; + compatible = "ibm,power8-psihb-x", "ibm,psihb-x"; + }; + + /* Chip TOD XSCOM register set */ + chiptod@40000 { + reg = <0x40000 0x34>; + compatible = "ibm,power-chiptod", "ibm,power8-chiptod"; + + /* + * Create that property with no value if this chip has + * the Primary TOD in the topology. If it has the secondary + * one (backup master ?) use "secondary". + */ + primary; + }; + + /* NX XSCOM register set */ + nx@2010000 { + reg = <0x2010000 0x4000>; + compatible = "ibm,power-nx", "ibm,power8-nx"; + }; + + /* + * PCI "PE Master" XSCOM register set for each active PHB + * + * For now, do *not* create these if the PHB isn't connected, + * clocked, or the PHY/HSS not configured. + */ + pbcq@2012000 { + reg = <0x2012000 0x20 0x9012000 0x5 0x9013c00 0x15>; + compatible = "ibm,power8-pbcq"; + + /* Indicate the PHB index on the chip, ie, 0,1 or 2 */ + ibm,phb-index = <0x0>; + + /* Create that property to use the IBM-style "A/B" dual input + * slot presence detect mechanism. + */ + ibm,use-ab-detect; + + /* + * TBD: Lane equalization values. Not currently used by + * skiboot but will have to be sorted out + */ + ibm,lane_eq = <0x0>; + }; + + pbcq@2012400 { + reg = <0x2012400 0x20 0x9012400 0x5 0x9013c40 0x15>; + compatible = "ibm,power8-pbcq"; + ibm,phb-index = <0x1>; + ibm,use-ab-detect; + ibm,lane_eq = <0x0>; + }; + + /* + * Here's the LPC bus. Ideally each chip has one but in + * practice it's ok to only populate the ones actually + * used for something. This is not an exact representation + * of HW, in that case we would have eccb -> opb -> lpc, + * but instead we just have an lpc node and the address is + * the base of the ECCB register set for it + * + * Devices on the LPC are represented as children nodes, + * see example below for a standard UART. + */ + lpc@b0020 { + /* + * Empty property indicating this is the primary + * LPC bus. It will be used for the default UART + * if any and this is the bus that will be used + * by Linux as the virtual 64k of IO ports + */ + primary; + + /* + * 2 cells of address, the first one indicates the + * address type, see below + */ + #address-cells = <0x2>; + #size-cells = <0x1>; + reg = <0xb0020 0x4>; + compatible = "ibm,power8-lpc"; + + /* + * Example device: a UART on IO ports. + * + * LPC address have 2 cells. The first cell is the + * address type as follow: + * + * 0 : LPC memory space + * 1 : LPC IO space + * 2: LPC FW space + * + * (This corresponds to the OPAL_LPC_* arguments + * passed to the opal_lpc_read/write functions) + * + * The unit address follows the old ISA convention + * for open firmware which prefixes IO ports with "i". + * + * (This is not critical and can be 1,3f8 if that's + * problematic to generate) + */ + serial@i3f8 { + reg = <0x1 0x3f8 8>; + compatible = "ns16550", "pnpPNP,501"; + + /* Baud rate generator base frequency */ + clock-frequency = < 1843200 >; + + /* Default speed to use */ + current-speed = < 115200 >; + + /* Historical, helps Linux */ + device_type = "serial"; + + /* + * Indicate which chip ID the interrupt + * is routed to (we assume it will always + * be the "host error interrupt" (aka + * "TPM interrupt" of that chip). + */ + ibm,irq-chip-id = <0x0>; + } + }; + }; +}; diff --git a/doc/error-logging.txt b/doc/error-logging.txt new file mode 100644 index 0000000..a29d368 --- /dev/null +++ b/doc/error-logging.txt @@ -0,0 +1,384 @@ +How to log errors on Sapphire and POWERNV: +========================================= + +Currently the errors reported by POWERNV/Sapphire (OPAL) interfaces +are in free form, where as errors reported by FSP is in standard Platform +Error Log (PEL) format. For out-of band management via IPMI interfaces, +it is necessary to push down the errors to FSP via mailbox +(reported by POWERNV/Sapphire) in PEL format. + +PEL size can vary from 2K-16K bytes, fields of which needs to populated +based on the kind of event and error that needs to be reported. +All the information needed to be reported as part of the error, is +passed by user using the error-logging interfaces outlined below. +Following which, PEL structure is generated based on the input and +then passed on to FSP. + +Error logging interfaces in Sapphire: +==================================== + +Interfaces are provided for the user to log/report an error in Sapphire. +Using these interfaces relevant error information is collected and later +converted to PEL format and then pushed to FSP. + +Step 1: To report an error, invoke opal_elog_create() with required argument. + + struct opal_errorlog *opal_elog_create(int reason_code); + + Each error/event that needs to be reported should do so with its + unique 32 bit reason code/SRC. Based on this SRC, relevant information + around that error/event is gathered from look-up table and updated + into the error log buffer. + + Parameters: + + int reason_code: Reason for failure as stated in include/fsp-elog.h + for Sapphire + Eg: Reason code for code-update failures can be + OPAL_RC_CU_INIT -> Initialisation failure + OPAL_RC_CU_FLASH -> Flash failure + + Following info is gathered from the look-up table in fsp-elog_write.c + and is pre-defined for a given error. + + uint8_t opal_error_event_type: Classification of error/events + type reported on OPAL + /* Platform Events/Errors: Report Machine Check Interrupt */ + #define OPAL_PLATFORM_ERR_EVT 0x01 + /* INPUT_OUTPUT: Report all I/O related events/errors */ + #define OPAL_INPUT_OUTPUT_ERR_EVT 0x02 + /* RESOURCE_DEALLOC: Hotplug events and errors */ + #define OPAL_RESOURCE_DEALLOC_ERR_EVT 0x03 + /* MISC: Miscellanous error */ + #define OPAL_MISC_ERR_EVT 0x04 + + uint16_t component_id: Component ID of Sapphire component as + listed in include/fsp-elog.h + + uint8_t subsystem_id: ID of the sub-system reporting error. + /* OPAL Subsystem IDs listed for reporting events/errors */ + #define OPAL_PROCESSOR_SUBSYSTEM 0x10 + #define OPAL_MEMORY_SUBSYSTEM 0x20 + #define OPAL_IO_SUBSYSTEM 0x30 + #define OPAL_IO_DEVICES 0x40 + #define OPAL_CEC_HARDWARE 0x50 + #define OPAL_POWER_COOLING 0x60 + #define OPAL_MISC 0x70 + #define OPAL_SURVEILLANCE_ERR 0x7A + #define OPAL_PLATFORM_FIRMWARE 0x80 + #define OPAL_SOFTWARE 0x90 + #define OPAL_EXTERNAL_ENV 0xA0 + + uint8_t event_severity: Severity of the event/error to be reported + #define OPAL_INFO 0x00 + #define OPAL_RECOVERED_ERR_GENERAL 0x10 + + /* 0x2X series is to denote set of Predictive Error */ + /* 0x20 Generic predictive error */ + #define OPAL_PREDICTIVE_ERR_GENERAL 0x20 + /* 0x21 Predictive error, degraded performance */ + #define OPAL_PREDICTIVE_ERR_DEGRADED_PERF 0x21 + /* 0x22 Predictive error, fault may be corrected after reboot */ + #define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_REBOOT 0x22 + /* + * 0x23 Predictive error, fault may be corrected after reboot, + * degraded performance + */ + #define OPAL_PREDICTIVE_ERR_FAULT_RECTIFY_BOOT_DEGRADE_PERF 0x23 + /* 0x24 Predictive error, loss of redundancy */ + #define OPAL_PREDICTIVE_ERR_LOSS_OF_REDUNDANCY 0x24 + + /* 0x4X series for Unrecoverable Error */ + /* 0x40 Generic Unrecoverable error */ + #define OPAL_UNRECOVERABLE_ERR_GENERAL 0x40 + /* 0x41 Unrecoverable error bypassed with degraded performance */ + #define OPAL_UNRECOVERABLE_ERR_DEGRADE_PERF 0x41 + /* 0x44 Unrecoverable error bypassed with loss of redundancy */ + #define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY 0x44 + /* 0x45 Unrecoverable error bypassed with loss of redundancy and performance */ + #define OPAL_UNRECOVERABLE_ERR_LOSS_REDUNDANCY_PERF 0x45 + /* 0x48 Unrecoverable error bypassed with loss of function */ + #define OPAL_UNRECOVERABLE_ERR_LOSS_OF_FUNCTION 0x48 + + #define OPAL_ERROR_PANIC 0x50 + + uint8_t event_subtype: Event Sub-type + #define OPAL_NA 0x00 + #define OPAL_MISCELLANEOUS_INFO_ONLY 0x01 + #define OPAL_PREV_REPORTED_ERR_RECTIFIED 0x10 + #define OPAL_SYS_RESOURCES_DECONFIG_BY_USER 0x20 + #define OPAL_SYS_RESOURCE_DECONFIG_PRIOR_ERR 0x21 + #define OPAL_RESOURCE_DEALLOC_EVENT_NOTIFY 0x22 + #define OPAL_CONCURRENT_MAINTENANCE_EVENT 0x40 + #define OPAL_CAPACITY_UPGRADE_EVENT 0x60 + #define OPAL_RESOURCE_SPARING_EVENT 0x70 + #define OPAL_DYNAMIC_RECONFIG_EVENT 0x80 + #define OPAL_NORMAL_SYS_PLATFORM_SHUTDOWN 0xD0 + #define OPAL_ABNORMAL_POWER_OFF 0xE0 + + uint8_t opal_srctype: SRC type, value should be OPAL_SRC_TYPE_ERROR. + SRC refers to System Reference Code. + It is 4 byte hexa-decimal number that reflects the + current system state. + Eg: BB821010, + 1st byte -> BB -> SRC Type + 2nd byte -> 82 -> Subsystem + 3rd, 4th byte -> Component ID and Reason Code + SRC needs to be generated on the fly depending on the state + of the system. All the parameters needed to generate a SRC + should be provided during reporting of an event/error. + + + uint32_t reason_code: Reason for failure as stated in include/fsp-elog.h + for Sapphire + Eg: Reason code for code-update failures can be + OPAL_RC_CU_INIT -> Initialisation failure + OPAL_RC_CU_FLASH -> Flash failure + + +Step 2: Multiple extended user dumps can be appened to error log + using the below interface. + + int opal_elog_update_user_dump(struct opal_errorlog *buf, unsigned char *data, + uint32_t tag, uint16_t size) + + Parameters: + struct opal_errorlog *buf: + struct opal_errorlog *buf: struct opal_errorlog pointer returned + by opal_elog_create() call. + + unsigned char *data: Pointer to the dump data + + uint32_t tag: Unique value to identify the data. + Ideal to have ASCII value for 4-byte string. + + uint16_t size: Size of the dump data. + +Step 3: Once all the data for an error is logged in, the error needs to be + committed in FSP. + + rc = elog_fsp_commit(buf); + Value of 0 is returned on success. + +In the process of committing an error to FSP, log info is first internally +converted to PEL format and then pushed to the FSP. All the errors logged +in Sapphire are again pushed up to POWERNV platform by the FSP and all the errors +reported by Sapphire and POWERNV are logged in FSP. + +If the user does not intend to dump various user data sections, but just +log the error with some amount of description around that error, theb can do +so using just the simple error logging interface + +log_simple_error(uint32_t reason_code, char *fmt, ...); + +Eg: log_simple_error(OPAL_RC_SURVE_STATUS, + "SURV: Error retreiving surveillance status: %d\n", + err_len); + +Using the reason code, an error log is generated with the information derived +from the look-up table, populated and committed to FSP. All of it +is done with just one call. + +Note: +==== +* For more information regarding error logging and PEL format + refer to PAPR doc and P7 PEL and SRC PLDD document. + +* Refer to include/opal.h for all the error logging + interface parameters and include/fsp-pel.h for PEL + structures. + +Sample error logging: +=================== +void report_error(int index) +{ + struct opal_errorlog *buf; + int rc; + char data1[] = "This is a sample user defined data section1"; + char data2[] = "Error logging sample. These are dummy errors. Section 2"; + char data3[] = "Sample error Sample error Sample error Sample error \ + Sample error abcdefghijklmnopqrstuvwxyz"; + int tag; + + printf("ELOG: In machine check report error index: %d\n", index); + + /* To report an error, create an error log with relevant information + * struct opal_errorlog *opal_elog_create(int reason_code); + * Call returns a pre-allocated buffer of type 'struct opal_errorlog' + * buffer with relevant fields updated. + */ + + buf = opal_elog_create(OPAL_RC_CHIP_MASTER); + if (buf == NULL) { + printf("ELOG: Error getting buffer.\n"); + return; + } + + /* In case of user wanting to add multiple sections of various dump data + * for better debug, data sections can be added using this interface + * int opal_elog_update_user_dump(struct opal_errorlog *buf, unsigned char *data, + * uint32_t tag, uint16_t size) + */ + /* tag -> unqiue ascii tag to identify a particular data dump section */ + tag = 0x4b4b4b4b; + rc = opal_elog_update_user_dump(buf, data1, tag, sizeof(data1)); + printf("ELOG: User data updated. rc : %d \n", rc); + + tag = 0x4c4c4c4c; + rc = opal_elog_update_user_dump(buf, data2, tag, sizeof(data2)); + printf("ELOG: User data updated. rc : %d \n", rc); + + tag = 0x4d4d4d4d; + rc = opal_elog_update_user_dump(buf, data3, tag, sizeof(data3)); + printf("ELOG: User data updated. rc : %d \n", rc); + + /* Once all info is updated, ready to be sent to FSP */ + printf("ELOG:commit to FSP\n"); + rc = elog_fsp_commit(buf); + if (rc != 0) + printf("ELOG: Re-try error logging\n"); +} + + Sample output PEL dump got from FSP: + =================================== + $ errl -d -x 0x53D5EA83 + | 00000000 50480030 01004000 20131126 05064700 PH.0..@. .....G. | + | 00000010 20131126 05064790 4B000109 00000000 .....G.K....... | + | 00000020 00000000 00000000 B0000003 53D5EA83 ............S... | + | 00000030 55480018 01004000 20000000 00000000 UH....@. ....... | + | 00000040 00002000 01005300 50530050 01004000 .. ...S.PS.P..@. | + | 00000050 02000008 00000048 00000080 00000000 .......H........ | + | 00000060 00000000 00000000 01234567 22220222 .........#Eg""." | + | 00000070 34560123 98768920 42423832 34303132 4V.#.v. BB824012 | + | 00000080 20202020 20202020 20202020 20202020 | + | 00000090 20202020 20202020 4548004C 01004000 EH.L..@. | + | 000000A0 38323436 2D4C3243 30363033 37374100 8246-L2C060377A. | + | 000000B0 00000000 00000000 00000000 00000000 ................ | + | 000000C0 00000000 00000000 00000000 00000000 ................ | + | 000000D0 00000000 00000000 00000000 05064700 ..............G. | + | 000000E0 00000000 4D54001C 01004000 38323436 ....MT....@.8246 | + | 000000F0 2D4C3243 30363033 37374100 00000000 -L2C060377A..... | + | 00000100 5544003C 01004000 4B4B4B4B 00340000 UD....@.KKKK.4.. | + | 00000110 54686973 20697320 61207361 6D706C65 This is a sample | + | 00000120 20757365 72206465 66696E65 64206461 user defined da | + | 00000130 74612073 65637469 6F6E3100 55440048 ta section1.UD.H | + | 00000140 01004000 4C4C4C4C 00400000 4572726F ..@.LLLL.@..Erro | + | 00000150 72206C6F 6767696E 67207361 6D706C65 r logging sample | + | 00000160 2E205468 65736520 61726520 64756D6D . These are dumm | + | 00000170 79206572 726F7273 2E205365 6374696F y errors. Sectio | + | 00000180 6E203200 55440071 01004000 4D4D4D4D n 2.UD.q..@.MMMM | + | 00000190 00690000 53616D70 6C652065 72726F72 .i..Sample error | + | 000001A0 2053616D 706C6520 6572726F 72205361 Sample error Sa | + | 000001B0 6D706C65 20657272 6F722053 616D706C mple error Sampl | + | 000001C0 65206572 726F7220 09090909 2053616D e error .... Sam | + | 000001D0 706C6520 6572726F 72206162 63646566 ple error abcdef | + | 000001E0 6768696A 6B6C6D6E 6F707172 73747576 ghijklmnopqrstuv | + | 000001F0 7778797A 00 wxyz. | + |------------------------------------------------------------------------------| + | Platform Event Log - 0x53D5EA83 | + |------------------------------------------------------------------------------| + | Private Header | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Created by : 4000 | + | Created at : 11/26/2013 05:06:47 | + | Committed at : 11/26/2013 05:06:47 | + | Creator Subsystem : Unknown - 0x0000004B | + | CSSVER : | + | Platform Log Id : 0xB0000003 | + | Entry Id : 0x53D5EA83 | + | Total Log Size : 644 | + |------------------------------------------------------------------------------| + | User Header | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Log Committed by : 4000 | + | Subsystem : Memory Subsystem | + | Event Scope : Unknown - 0x00000000 | + | Event Severity : Informational Event | + | Event Type : Not Applicable | + | Return Code : 0x00000000 | + | Action Flags : Report to Operating System | + | Action Status : Sent to Hypervisor | + |------------------------------------------------------------------------------| + | Primary System Reference Code | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Created by : 4000 | + | SRC Format : 0x80 | + | SRC Version : 0x02 | + | Virtual Progress SRC : False | + | I5/OS Service Event Bit : False | + | Hypervisor Dump Initiated: False | + | Power Control Net Fault : False | + | | + | Valid Word Count : 0x08 | + | Reference Code : BB824012 | + | Hex Words 2 - 5 : 00000080 00000000 00000000 00000000 | + | Hex Words 6 - 9 : 01234567 22220222 34560123 98768920 | + | | + |------------------------------------------------------------------------------| + | Extended User Header | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Created by : 4000 | + | Reporting Machine Type : 8246-L2C | + | Reporting Serial Number : 060377A | + | FW Released Ver : | + | FW SubSys Version : | + | Common Ref Time : 00/00/0000 05:06:47 | + | Symptom Id Len : 0 | + | Symptom Id : | + |------------------------------------------------------------------------------| + | Machine Type/Model & Serial Number | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Created by : 4000 | + | Machine Type Model : 8246-L2C | + | Serial Number : 060377A | + |------------------------------------------------------------------------------| + | User Defined Data | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Created by : 4000 | + | | + | 00000000 4B4B4B4B 00340000 54686973 20697320 KKKK.4..This is | + | 00000010 61207361 6D706C65 20757365 72206465 a sample user de | + | 00000020 66696E65 64206461 74612073 65637469 fined data secti | + | 00000030 6F6E3100 on1. | + | | + |------------------------------------------------------------------------------| + | User Defined Data | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Created by : 4000 | + | | + | 00000000 4C4C4C4C 00400000 4572726F 72206C6F LLLL.@..Error lo | + | 00000010 6767696E 67207361 6D706C65 2E205468 gging sample. Th | + | 00000020 65736520 61726520 64756D6D 79206572 ese are dummy er | + | 00000030 726F7273 2E205365 6374696F 6E203200 rors. Section 2. | + | | + |------------------------------------------------------------------------------| + | User Defined Data | + |------------------------------------------------------------------------------| + | Section Version : 1 | + | Sub-section type : 0 | + | Created by : 4000 | + | | + | 00000000 4D4D4D4D 00690000 53616D70 6C652065 MMMM.i..Sample e | + | 00000010 72726F72 2053616D 706C6520 6572726F rror Sample erro | + | 00000020 72205361 6D706C65 20657272 6F722053 r Sample error S | + | 00000030 616D706C 65206572 726F7220 09090909 ample error .... | + | 00000040 2053616D 706C6520 6572726F 72206162 Sample error ab | + | 00000050 63646566 6768696A 6B6C6D6E 6F707172 cdefghijklmnopqr | + | 00000060 73747576 7778797A 00 stuvwxyz. | + | | + |------------------------------------------------------------------------------| + diff --git a/doc/overview.txt b/doc/overview.txt new file mode 100644 index 0000000..760f391 --- /dev/null +++ b/doc/overview.txt @@ -0,0 +1,116 @@ +skiboot overview +================ + +skiboot is firmware, loaded by the FSP. Along with loading the bootloader, +it provides some runtime services to the OS (typically Linux). + +Source layout +------------- +asm/ small amount, mainly entry points +ccan/ bits from CCAN +core/ common code among machines. +doc/ not enough here +external/ tools to run external of sapphire. +hdata/ all stuff going to/from FSP +hw/ drivers for things & fsp things. +include/ headers! +libc/ tiny libc, from SLOF +libfdt/ straight device tree lib +libpore/ to manipulate PORE engine. + +We have a spinlock implementation in asm/lock.S +Entry points are detailed in asm/head.S +The main C entry point is in core/init.c: main_cpu_entry() + +Binaries +-------- +The following binaries are built: + +skiboot.lid: is the actual lid. objdump out +skiboot.elf: is the elf binary of it, lid comes from this +skiboot.map: plain map of symbols + +Booting +------- + +On boot, every thread of execution jumps to a single entry point in skiboot +so we need to do some magic to ensure we init things properly and don't stomp +on each other. We choose a master thread, putting everybody else into a +spinloop. + +Essentially, we do this by doing an atomic fetch and inc and whoever gets 0 +gets to be the master. + +When we enter skiboot we also get a memory location in a register which +is the location of a device tree for the system. We fatten out the device +tree, turning offsets into real pointers and manipulating it where needed. +We re-flatten the device tree before booting the OS (Linux). + +The main entry point is main_cpu_entry() in core/init.c, this is a carefully +ordered init of things. The sequence is relatively well documented there. + +OS interface +------------ + +Skiboot maintains its own stack for each CPU. We do not have an ABI like +"may use X stack on OS stack", we entirely keep to our own stack space. +The OS (Linux) calling skiboot will never use any OS stack space and the OS +does not need to call skiboot with a valid stack. + +We define an array of stacks, one for each CPU. On entry to skiboot, +we can find out stack by multiplying our CPU number by the stack size and +adding that to the address of the stack area. + +At the bottom of each stack area is a per CPU data structure, which we +can get to by chopping off the LSBs of the stack pointer. + +The OPAL interface is a generic message queue. The Linux side of things +can be found in linux/arch/powerpc/platform/powernv/opal-*.c + +Interrupts +---------- + +We don't handle interrupts in skiboot. + +In the future we may have to change to process machine check interrupts +during boot. + +We do not have timer interrupts. + + +Memory +------ + +We initially occupy a chunk of memory, "heap". We pass to the OS (Linux) +a reservation of what we occupy (including stacks). + +In the source file include/config.h we include a memory map. This is +manually generated, not automatically generated. + +We use CCAN for a bunch of helper code, turning on things like DEBUG_LOCKS +and DEBUG_MALLOC as these are not a performance issue for us, and we like +to be careful. + +In include/config.h there are defines for turning on extra tracing. +OPAL is what we name the interface from skiboot to OS (Linux). + +Each CPU gets a 16k stack, which is probably more than enough. Stack +should be used sparingly though. + +Important memory locations: + +SKIBOOT_BASE - where we sit + +HEAP_BASE, +HEAP_SIZE - the location and size for heap. We reserve 4MB for + initial allocations. + +There is also SKIBOOT_SIZE (manually calculated) and DEVICE_TREE_MAX_SIZE, +which is largely historical. + +Skiboot log +----------- + +There is a circular log buffer that skiboot maintains. This can be +accessed either from the FSP or through /dev/mem or through a debugfs +patch that's currently floating around. diff --git a/doc/pci-slot-properties.txt b/doc/pci-slot-properties.txt new file mode 100644 index 0000000..7aeac3f --- /dev/null +++ b/doc/pci-slot-properties.txt @@ -0,0 +1,17 @@ + +PCI Slot Properties Description +=============================== + +The following properties have been added to the PCI Device Tree Node +for the PCI Slot: + +ibm,slot-location-code System location code string for the slot connector +ibm,slot-pluggable Boolean indicating whether the slot is pluggable +ibm,slot-power-ctl Boolean indicating whether the slot has power control +ibm,slot-wired-lanes The number of hardware lanes that are wired +ibm,slot-connector-type The type of connector present +ibm,slot-card-desc The height/length of the slot +ibm,slot-card-mech Value indicating slot mechanicals and orientation +ibm,slot-pwr-led-ctl Presence of slot power led, and controlling entity +ibm,slot-attn-led-ctl Presence of slot ATTN led, and controlling entity + diff --git a/doc/vpd-properties.txt b/doc/vpd-properties.txt new file mode 100644 index 0000000..ae18a7f --- /dev/null +++ b/doc/vpd-properties.txt @@ -0,0 +1,19 @@ +VPD properties Description +========================== + +/vpd : VPD root node +Node name : <FRU description>@<Resource ID> +ibm,vpd : VPD data (binary blob) +ccin : Customer Card Identification Number +fru-type : FRU type label (two byte ASCII Char) +fru-number : FRU Stocking Part Number +ibm,loc-code : Location code +part-number : Part Number +serial-number : Serial Number +ibm,chip-id : Process ID +size : DIMM Size (applicable for DIMM VPD only) + +Child Node: +=========== +A child node inherits its parent's VPD information except for the +fru-type and location code. diff --git a/doc/xscom-node-bindings.txt b/doc/xscom-node-bindings.txt new file mode 100644 index 0000000..0c2545e --- /dev/null +++ b/doc/xscom-node-bindings.txt @@ -0,0 +1,57 @@ +XSCOM regions +============= + +The top-level xscom nodes specify the mapping range from the 64-bit address +space into the PCB address space. + +There's one mapping range per chip xscom, therefore one node per mapping range. + +/ +/xscom@<chip-base-address-0>/ +/xscom@<chip-base-address-1>/ +… +/xscom@<chip-base-address-n>/ + +- where <chip-base-address-n> is the xscom base address with the gcid-specific + bits (for chip n) OR-ed in. + +Each xscom node has the following properties: + + * #address-cells = 1 + * #size-cells = 1 + * reg = <base-address[#parent-address-cells] size[#parent-size-cells]> + * ibm,chip-id = gcid + * compatible = "ibm,xscom", "ibm,power8-scom" / "ibm,power7-xscom" + + +Chiplet endpoints +================= + +One sub-node per endpoint. Endpoints are defined by their (port, +endpoint-address) data on the PCB, and are named according to their endpoint +types: + +/xscom@<chip-base-address>/ +/xscom@<chip-base-address>/chiptod@<endpoint-addr> +/xscom@<chip-base-address>/lpc@<endpoint-addr> + +- where the <endpoint-addr> is a single address (as distinct from the current + (gcid,base) format), consisting of the SCOM port and SCOM endpoint bits in + their 31-bit address format. + +Each endpoint node has the following properties: + + * reg = <endpoint-address[#parent-address-cells] size[#parent-size-cells]> + * compatible - depends on endpoint type, eg "ibm,power8-chiptod" + +The endpoint address specifies the address on the PCB. So, to calculate the +MMIO address for a PCB register: + + mmio_addr = <xscom-base-addr> | (pcb_addr[1:27] << 4) + | (pcb_addr[28:31] << 3) + +Where: + + - xscom-base-addr is the address from the first two cells of the parent + node's reg property + - pcb_addr is the first cell of the endpoint's reg property |