From 97bd69daf028bec2f7d7f4fbd8feb49486fb4577 Mon Sep 17 00:00:00 2001 From: Dean Sanner Date: Thu, 3 Jan 2013 10:16:18 -0600 Subject: Basic devtree support Simple devtree support for Sapphire in SPless mode Change-Id: I4a70bfc5cd3eb3dbd1b443869c046c789f98cc95 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/3739 Tested-by: Jenkins Server Reviewed-by: Daniel M. Crowell Reviewed-by: A. Patrick Williams III --- src/include/kernel/misc.H | 2 + src/include/sys/misc.h | 5 +- src/include/usr/devtree/devtree_reasoncodes.H | 43 ++ src/include/usr/devtree/devtreeif.H | 51 ++ src/include/usr/hbotcompid.H | 10 +- src/include/usr/initservice/initserviceif.H | 5 +- src/include/usr/intr/interrupt.H | 40 ++ src/include/usr/isteps/istep21list.H | 1 + src/kernel/misc.C | 5 +- src/kernel/shutdown.S | 47 +- src/kernel/syscall.C | 1 + src/lib/syscall_misc.C | 8 +- src/makefile | 3 +- src/usr/devtree/bld_devtree.C | 427 +++++++++++++ src/usr/devtree/devtree.C | 711 +++++++++++++++++++++ src/usr/devtree/devtree.H | 332 ++++++++++ src/usr/devtree/makefile | 35 + src/usr/hwpf/hwp/start_payload/start_payload.C | 46 +- src/usr/initservice/baseinitsvc/initservice.C | 11 +- src/usr/initservice/baseinitsvc/initservice.H | 49 +- src/usr/intr/intrrp.C | 18 + src/usr/intr/intrrp.H | 32 - src/usr/makefile | 2 +- .../targeting/common/xmltohb/attribute_types.xml | 6 +- 24 files changed, 1788 insertions(+), 102 deletions(-) create mode 100644 src/include/usr/devtree/devtree_reasoncodes.H create mode 100644 src/include/usr/devtree/devtreeif.H create mode 100644 src/usr/devtree/bld_devtree.C create mode 100644 src/usr/devtree/devtree.C create mode 100644 src/usr/devtree/devtree.H create mode 100644 src/usr/devtree/makefile (limited to 'src') diff --git a/src/include/kernel/misc.H b/src/include/kernel/misc.H index 544df7c88..42cfd3fa0 100644 --- a/src/include/kernel/misc.H +++ b/src/include/kernel/misc.H @@ -45,6 +45,8 @@ namespace KernelMisc extern uint64_t g_payload_base; /** @brief Address from base of payload entry-point. */ extern uint64_t g_payload_entry; + /** @brief Address from base of payload data pointer. */ + extern uint64_t g_payload_data; /** @fn in_kernel_mode * @brief Determine if the code is currently in kernel mode or not. diff --git a/src/include/sys/misc.h b/src/include/sys/misc.h index f3e89e4e7..a73398efa 100644 --- a/src/include/sys/misc.h +++ b/src/include/sys/misc.h @@ -95,10 +95,13 @@ extern "C" * @param[in] i_payload_base The base address (target HRMOR) of the payload. * @param[in] i_payload_entry The offset from base address of the payload * entry-point. + * @param[in] i_payload_data Data pointer fo the payload. For standalone + * Saphire this is the devtree */ extern "C" void shutdown(uint64_t i_status, uint64_t i_payload_base, - uint64_t i_payload_entry); + uint64_t i_payload_entry, + uint64_t i_payload_data); #endif /** @enum ProcessorCoreType diff --git a/src/include/usr/devtree/devtree_reasoncodes.H b/src/include/usr/devtree/devtree_reasoncodes.H new file mode 100644 index 000000000..c996ebca3 --- /dev/null +++ b/src/include/usr/devtree/devtree_reasoncodes.H @@ -0,0 +1,43 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/devtree/devtree_reasoncodes.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __DEVTREE_REASONCODES_H +#define __DEVTREE_REASONCODES_H + +#include + +namespace DEVTREE +{ + enum DevtreeModuleId + { + MOD_DEVTREE_INVALID = 0x00, /**< Zero is invalid module id */ + MOD_DEVTREE_BLD_MEM = 0x01, + }; + + enum DevtreeReasonCode + { + RC_ATTR_MEMSIZE_GET_FAIL = DEVTREE_COMP_ID | 0x01, + RC_ATTR_MEMBASE_GET_FAIL = DEVTREE_COMP_ID | 0x02, + }; +}; + +#endif diff --git a/src/include/usr/devtree/devtreeif.H b/src/include/usr/devtree/devtreeif.H new file mode 100644 index 000000000..e6c068e88 --- /dev/null +++ b/src/include/usr/devtree/devtreeif.H @@ -0,0 +1,51 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/include/usr/devtree/devtreeif.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2012,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +#ifndef __DEVTREE_IF_H +#define __DEVTREE_IF_H + +#include + + +namespace DEVTREE +{ + + /** + * @brief Build flattened dev tree for Sapphire + * + * @return errlHndl_t NULL on success + */ + errlHndl_t build_flatdevtree( void ); + + /** + * @brief Get the address of the flattened dev tree for Sapphire + * + * @return uint64_t - Address if valid, else NULL + */ + uint64_t get_flatdevtree_phys_addr( void ); + + + + +}; // end namespace DEVTREE + +#endif diff --git a/src/include/usr/hbotcompid.H b/src/include/usr/hbotcompid.H index 0484715f1..994aac1de 100644 --- a/src/include/usr/hbotcompid.H +++ b/src/include/usr/hbotcompid.H @@ -265,6 +265,7 @@ const char KERNEL_COMP_NAME[] = "kernel"; //@{ const compId_t IBSCOM_COMP_ID = 0x1C00; const char IBSCOM_COMP_NAME[] = "ibscom"; +//@} /** @name VPD @@ -291,7 +292,6 @@ const compId_t IPC_COMP_ID = 0x1F00; const char IPC_COMP_NAME[] = "ipc"; //@} - /** @name HSVC * Host Services component * For the code running under PHYP @@ -300,6 +300,14 @@ const char IPC_COMP_NAME[] = "ipc"; const compId_t HSVC_COMP_ID = 0x2000; const char HSVC_COMP_NAME[] = "hsvc"; +/** @name DEVTREE + * DEVTREE component + */ +//@{ +const compId_t DEVTREE_COMP_ID = 0x2100; +const char DEVTREE_COMP_NAME[] = "devtree"; +//@} + /** @name RESERVED * Reserved component ID. x3100 is the component ID * of FipS ERRL component. Due to our use of diff --git a/src/include/usr/initservice/initserviceif.H b/src/include/usr/initservice/initserviceif.H index f09433e15..77db81ea4 100644 --- a/src/include/usr/initservice/initserviceif.H +++ b/src/include/usr/initservice/initserviceif.H @@ -84,6 +84,7 @@ bool unregisterShutdownEvent(msg_q_t i_msgQ); * payload. * @param[in] i_payload_entry - The offset from base address of the * payload entry-point. + * @param[in] i_payload_data - Pointer to payload data (if needed) * * @return Nothing * @@ -91,8 +92,8 @@ bool unregisterShutdownEvent(msg_q_t i_msgQ); */ void doShutdown ( uint64_t i_status, uint64_t i_payload_base = 0, - uint64_t i_payload_entry = 0 ) NO_RETURN; - + uint64_t i_payload_entry = 0, + uint64_t i_payload_data = 0) NO_RETURN; } #endif diff --git a/src/include/usr/intr/interrupt.H b/src/include/usr/intr/interrupt.H index cf129712a..f41f8ccf6 100644 --- a/src/include/usr/intr/interrupt.H +++ b/src/include/usr/intr/interrupt.H @@ -33,6 +33,37 @@ namespace TARGETING namespace INTR { + /** + * cpu PIR register + */ + struct PIR_t + { + union + { + uint32_t word; + struct + { + //P8: + uint32_t reserved:19; //!< zeros + uint32_t nodeId:3; //!< node (0-3) + uint32_t chipId:3; //!< chip pos on node (0-5) + uint32_t coreId:4; //!< Core number (1-6,9-14)? + uint32_t threadId:3; //!< Thread number (0-7) + } PACKED; + }; + PIR_t(uint32_t i_word = 0) : word(i_word) {} + + PIR_t operator= (uint32_t i_word) + { + word = i_word; + return word; + } + + bool operator< (const PIR_t& r) const + { + return word < r.word; + } + }; /** * External Interrupt Types (XISR) @@ -165,6 +196,15 @@ namespace INTR */ errlHndl_t enablePsiIntr(TARGETING::Target * i_target); + /** + * Return the interrupt presenter for requested target/thread + * @param[in] i_ex The target EX + * @param[in] i_thread Which thread on EX (0-7) + * @return 64 bit address for the interrupt present addr + */ + uint64_t getIntpAddr(const TARGETING::Target * i_ex, + uint8_t i_thread); + }; #endif diff --git a/src/include/usr/isteps/istep21list.H b/src/include/usr/isteps/istep21list.H index 0d0f6108a..7b4bfb8e1 100644 --- a/src/include/usr/isteps/istep21list.H +++ b/src/include/usr/isteps/istep21list.H @@ -107,6 +107,7 @@ const DepModInfo g_istep21Dependancies = { { DEP_LIB(libstart_payload.so), DEP_LIB(libruntime.so), + DEP_LIB(libdevtree.so), { 0 }, } }; diff --git a/src/kernel/misc.C b/src/kernel/misc.C index 542e34c64..9e19674ad 100644 --- a/src/kernel/misc.C +++ b/src/kernel/misc.C @@ -38,7 +38,8 @@ #include extern "C" - void kernel_shutdown(size_t, uint64_t, uint64_t, uint64_t) NO_RETURN; + void kernel_shutdown(size_t, uint64_t, uint64_t, uint64_t, + uint64_t) NO_RETURN; extern HB_Descriptor kernel_hbDescriptor; @@ -47,6 +48,7 @@ namespace KernelMisc uint64_t g_payload_base = 0; uint64_t g_payload_entry = 0; + uint64_t g_payload_data = 0; void shutdown() { @@ -139,6 +141,7 @@ namespace KernelMisc kernel_shutdown(CpuManager::getCpuCount(), g_payload_base, g_payload_entry, + g_payload_data, l_lowestPIR); } } diff --git a/src/kernel/shutdown.S b/src/kernel/shutdown.S index bb7657318..74492f37d 100644 --- a/src/kernel/shutdown.S +++ b/src/kernel/shutdown.S @@ -1,25 +1,25 @@ -# IBM_PROLOG_BEGIN_TAG -# This is an automatically generated prolog. +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. # -# $Source: src/kernel/shutdown.S $ +# $Source: src/kernel/shutdown.S $ # -# IBM CONFIDENTIAL +# IBM CONFIDENTIAL # -# COPYRIGHT International Business Machines Corp. 2012 +# COPYRIGHT International Business Machines Corp. 2012,2013 # -# p1 +# p1 # -# Object Code Only (OCO) source materials -# Licensed Internal Code Source Materials -# IBM HostBoot Licensed Internal Code +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code # -# The source code for this program is not published or other- -# wise divested of its trade secrets, irrespective of what has -# been deposited with the U.S. Copyright Office. +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. # -# Origin: 30 +# Origin: 30 # -# IBM_PROLOG_END_TAG +# IBM_PROLOG_END_TAG .include "kernel/ppcconsts.S" #define KERNEL_BARRIER(addr, count, temp) \ @@ -64,7 +64,8 @@ ;// @param[in] r3 - CPU count - Number of active CPUs. ;// @param[in] r4 - Payload Base ;// @param[in] r5 - Payload Entry - ;// @param[in] r6 - Last thread to enter payload. + ;// @param[in] r6 - Payload Data + ;// @param[in] r7 - Last thread to enter payload. ;// .global kernel_shutdown kernel_shutdown: @@ -72,16 +73,16 @@ kernel_shutdown: li r10, 1 rotldi r10, r10, 63 ;// Retrieve existing HRMOR. - mfspr r7, HRMOR + mfspr r0, HRMOR ;// Determine physical address of shutdown_barrier. lis r8, kernel_shutdown_barriers@h ori r8, r8, kernel_shutdown_barriers@l - or r8, r8, r7 ;// Apply HRMOR. + or r8, r8, r0 ;// Apply HRMOR. or r8, r8, r10 ;// Apply EA[0] = 1. ;// Determine physical address of EA[0]=1 mode instruction. lis r9, kernel_shutdown_ea0_1_mode@h ori r9, r9, kernel_shutdown_ea0_1_mode@l - or r9, r9, r7 ;// Apply HRMOR. + or r9, r9, r0 ;// Apply HRMOR. or r9, r9, r10 ;// Apply EA[0] = 1. ;// Jump to enter EA[0] = 1 mtlr r9 @@ -110,11 +111,11 @@ kernel_shutdown_ea0_1_mode: KERNEL_BARRIER(r8, r3, r11) ;// "Barrier" 4: - ;// Increment counter as leaving, except PIR == r6 waits. + ;// Increment counter as leaving, except PIR == r7 waits. addi r8, r8, 8 - ;// Check for PIR == r6. + ;// Check for PIR == r7. mfspr r10, PIR - cmp cr0, r10, r6 + cmp cr0, r10, r7 beq 3f ;// Increment thread count. 1: @@ -130,10 +131,12 @@ kernel_shutdown_ea0_1_mode: ;// Save MSR, move to HSRR1. mfmsr r10 mtspr HSRR1, r10 + ;// Move payload data to r3 + mr r3,r6 ;// Jump to entry point. Causes HSRR0 -> NIA, HSSR1 -> MSR. hrfid - ;// PIR == r6 waits here for all others to leave. + ;// PIR == r7 waits here for all others to leave. 3: subi r3, r3, 1 1: diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index 1c9b62ab6..be2b51d59 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -650,6 +650,7 @@ namespace Systemcalls uint64_t status = static_cast(TASK_GETARG0(t)); KernelMisc::g_payload_base = static_cast(TASK_GETARG1(t)); KernelMisc::g_payload_entry = static_cast(TASK_GETARG2(t)); + KernelMisc::g_payload_data = static_cast(TASK_GETARG3(t)); CpuManager::requestShutdown(status); TASK_SETRTN(t, 0); } diff --git a/src/lib/syscall_misc.C b/src/lib/syscall_misc.C index f2b50bb01..c972292f9 100644 --- a/src/lib/syscall_misc.C +++ b/src/lib/syscall_misc.C @@ -30,12 +30,14 @@ using namespace Systemcalls; void shutdown(uint64_t i_status, uint64_t i_payload_base, - uint64_t i_payload_entry) + uint64_t i_payload_entry, + uint64_t i_payload_data) { - _syscall3(MISC_SHUTDOWN, + _syscall4(MISC_SHUTDOWN, reinterpret_cast(i_status), reinterpret_cast(i_payload_base), - reinterpret_cast(i_payload_entry)); + reinterpret_cast(i_payload_entry), + reinterpret_cast(i_payload_data)); } ProcessorCoreType cpu_core_type() diff --git a/src/makefile b/src/makefile index 98c1301ef..fb8c225a9 100644 --- a/src/makefile +++ b/src/makefile @@ -57,7 +57,8 @@ EXTENDED_MODULES = targeting ecmddatabuffer fapi hwp plat \ core_activate dram_initialization edi_ei_initialization \ establish_system_smp occ\ nest_chiplets start_payload thread_activate slave_sbe \ - attn runtime ibscom dump tod_init secureboot_ext + attn runtime ibscom dump tod_init secureboot_ext \ + devtree TESTCASE_MODULES = cxxtest testtrace testerrl testdevicefw testsyslib \ testscom testxscom testtargeting testinitservice testkernel \ diff --git a/src/usr/devtree/bld_devtree.C b/src/usr/devtree/bld_devtree.C new file mode 100644 index 000000000..85d2d0773 --- /dev/null +++ b/src/usr/devtree/bld_devtree.C @@ -0,0 +1,427 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/devtree/bld_devtree.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/* $IBMCopyrightBlock: + IBM Confidential + + OCO Source Materials + + 5733-907 + + (C) Copyright IBM Corp. 2011 + + The source code for this program is not published or other- + wise divested of its trade secrets, irrespective of what has + been deposited with the U.S. Copyright Office. +$ */ + +#include +#include +#include +#include +#include +#include +#include +#include "devtree.H" +#include //THIRTYTWO_GB +#include + + +trace_desc_t *g_trac_devtree = NULL; +TRAC_INIT(&g_trac_devtree, "DEVTREE", 4096); + +namespace DEVTREE +{ +using namespace TARGETING; + +enum BuildConstants +{ + DEVTREE_DATA_ADDR =0xFF00000, /* 256MB - 1MB*/ + DEVTREE_SPACE_SIZE =0x10000, /*64KB*/ + XSCOM_NODE_SHIFT =38, /*Node pos is 25, so 63-25=38*/ + XSCOM_CHIP_SHIFT =35, /*Chip pos is 28, so 63-28=35*/ + CHIPID_NODE_SHIFT =3, /*CHIPID is NNNCCC, shift 3*/ + PHB0_MASK =0x80, + MAX_PHBs = 3, /*Max PHBs per chip is 3*/ +}; + + +errlHndl_t bld_fdt_cpu(devTree * i_dt) +{ + errlHndl_t errhdl = NULL; + const char* cpuNodeName = "PowerPC,POWER8"; + const char* cpuIntrName = "interrupt-controller"; + const char* xscomNodeName = "xscom"; + const char* todNodeName = "chiptod"; + const char* pciNodeName = "pbcq"; + const char* lpcNodeName = "lpc"; + const uint32_t THREADPERCORE = 8; + + /* Find the / node and add a cpus node under it. */ + dtOffset_t rootNode = i_dt->findNode("/"); + dtOffset_t cpusNode = i_dt->addNode(rootNode, "cpus"); + + // Grab a system object to work with + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + uint64_t l_xscomBaseAddr = + sys->getAttr(); + + + /* Add the # address & size cell properties to /cpus. */ + i_dt->addPropertyCell32(cpusNode, "#address-cells", 1); + i_dt->addPropertyCell32(cpusNode, "#size-cells", 0); + + uint32_t segmentSizes[4] = { 0x1c, 0x28, 0xffffffff, 0xffffffff }; + uint32_t segmentPageSizes[] = + { + 12, 0x0, 3, /* 4k SLB page size, L,LP = 0,x1, 3 page size encodings */ + 12, 0x0, /* 4K PTE page size, L,LP = 0,x0 */ + 16, 0x7, /* 64K PTE page size, L,LP = 1,x7 */ + 24, 0x38, /* 16M PTE page size, L,LP = 1,x38 */ + 16, 0x110, 2, /* 64K SLB page size, L,LP = 1,x1, 2 page size encodings*/ + 16, 0x1, /* 64K PTE page size, L,LP = 1,x1 */ + 24, 0x8, /* 16M PTE page size, L,LP = 1,x8 */ + 20, 0x130, 1, /* 1M SLB page size, L,LP = 1,x3, 1 page size encoding */ + 20, 0x2, /* 1M PTE page size, L,LP = 1,x2 */ + 24, 0x100, 1, /* 16M SLB page size, L,LP = 1,x0, 1 page size encoding */ + 24, 0x0, /* 16M PTE page size, L,LP = 1,x0 */ + 34, 0x120, 1, /* 16G SLB page size, L,LP = 1,x2, 1 page size encoding */ + 34, 0x3 /* 16G PTE page size, L,LP = 1,x3 */ + }; + + + // Get all functional proc chip targets + TARGETING::TargetHandleList l_cpuTargetList; + getAllChips(l_cpuTargetList, TYPE_PROC); + + for ( size_t proc = 0; (!errhdl) && (proc < l_cpuTargetList.size()); proc++) + { + const TARGETING::Target * l_pProc = l_cpuTargetList[proc]; + + uint32_t l_fabId = l_pProc->getAttr(); + uint32_t l_procPos = l_pProc->getAttr(); + uint32_t l_chipid = (l_fabId << CHIPID_NODE_SHIFT) + l_procPos; + + /* Find calculate the Xscom addr for this chip and add it */ + uint64_t l_xscomAddr = l_xscomBaseAddr + + (static_cast(l_chipid) << XSCOM_CHIP_SHIFT); + + dtOffset_t xscomNode = i_dt->addNode(rootNode, xscomNodeName, + l_xscomAddr); + + uint64_t xscom_prop[2] = { l_xscomAddr, THIRTYTWO_GB}; + i_dt->addPropertyCells64(xscomNode, "reg", xscom_prop, 2); + const char* xscom_compatStrs[] = {"ibm,xscom","ibm,power8-xscom",NULL}; + i_dt->addPropertyCell32(xscomNode, "#address-cells", 1); + i_dt->addPropertyCell32(xscomNode, "#size-cells", 1); + i_dt->addPropertyCell32(xscomNode, "ibm,chip-id", l_chipid); + i_dt->addPropertyStrings(xscomNode, "compatible", xscom_compatStrs); + + + /*ChipTod*/ + uint32_t l_todInfo = 0x40000; /*Chip tod Scom addr*/ + dtOffset_t todNode = i_dt->addNode(xscomNode, todNodeName, l_todInfo); + const char* tod_compatStrs[] = {"ibm,power-chiptod", + "ibm,power8-chiptod", NULL}; + i_dt->addPropertyStrings(todNode, "compatible", tod_compatStrs); + uint32_t tod_prop[2] = { l_todInfo, 0x34 }; //# of scoms in range + i_dt->addPropertyCells32(todNode, "reg", tod_prop, 2); + + if(l_chipid == 0x0) //Master chip + { + i_dt->addProperty(todNode, "primary"); //TODO -- get from ATTR + + uint32_t l_lpcInfo = 0xB0020; /*ECCB FW addr*/ + dtOffset_t lpcNode = i_dt->addNode(xscomNode,lpcNodeName,l_lpcInfo); + i_dt->addPropertyString(lpcNode, "compatible", "ibm,power8-lpc"); + uint32_t lpc_prop[2] = { l_lpcInfo, 0x4 }; //# of scoms in range + i_dt->addPropertyCells32(lpcNode, "reg", lpc_prop, 2); + } + + /*PCIE*/ + uint8_t l_phbActive = + l_pProc->getAttr(); + //TARGETING::ATTR_PROC_PCIE_LANE_EQUALIZATION_type l_laneEq = + // l_pProc->getAttr(); + uint32_t l_laneEq[] = {0,0,0,0}; + + TRACFCOMP( g_trac_devtree, "Chip %X PHB Active mask %X", + l_chipid, l_phbActive); + + for(uint32_t l_phb =0; l_phb < MAX_PHBs; l_phb++) + { + if(!(l_phbActive & (PHB0_MASK>>l_phb))) + { + continue; + } + + TRACFCOMP( g_trac_devtree, "Adding PHB %d", l_phb); + + /*PHB is active, add to Xscom map*/ + uint32_t l_peInfo = 0x02012000 + (l_phb * 0x400); + uint32_t l_pciInfo = 0x09012000 + (l_phb * 0x400); + uint32_t l_spciInfo = 0x09013c00 + (l_phb * 0x40); + dtOffset_t pcieNode = i_dt->addNode(xscomNode,pciNodeName,l_peInfo); + const char* pcie_compatStrs[] = {"ibm,power8-pbcq", NULL}; + i_dt->addPropertyStrings(pcieNode, "compatible", pcie_compatStrs); + uint32_t pcie_prop[6] = { l_peInfo, 0x20, //# of scoms in range + l_pciInfo, 0x5, //# of scoms in range + l_spciInfo, 0x15}; //# of scoms in range + i_dt->addPropertyCells32(pcieNode, "reg", pcie_prop, 6); + i_dt->addPropertyCell32(pcieNode, "ibm,phb-index", l_phb); + i_dt->addPropertyCell32(pcieNode, "ibm,lane-eq", l_laneEq[l_phb]); + } + + TARGETING::TargetHandleList l_exlist; + getChildChiplets( l_exlist, l_pProc, TYPE_CORE ); + for (size_t core = 0; core < l_exlist.size(); core++) + { + const TARGETING::Target * l_ex = l_exlist[core]; + if(l_ex->getAttr().functional != true) + { + continue; //Not functional + } + + /* TODO -- need to add cache info */ + + /* Add a dev node for each cpu core. The unit address is the + *interrupt server number of the first thread of the core. + */ + + /* Proc ID Reg is N NNCC CPPP PTTT Where + NNN is node number + CCC is Chip + PPPP is the core number + TTT is Thread num + */ + uint32_t l_coreNum = l_ex->getAttr(); + INTR::PIR_t pir(0); + pir.nodeId = l_fabId; + pir.chipId = l_procPos; + pir.coreId = l_coreNum; + + TRACFCOMP( g_trac_devtree, "Added pir[%x] node %d proc %d core %d", + pir.word, l_fabId, l_procPos, l_coreNum ); + + cpusNode = i_dt->findNode("/cpus"); + dtOffset_t cpuNode = i_dt->addNode(cpusNode, cpuNodeName, + pir.word); + i_dt->addPropertyString(cpuNode, "device_type", "cpu"); + i_dt->addPropertyString(cpuNode, "status", "okay"); + i_dt->addPropertyCell32(cpuNode, "reg", pir.word); + i_dt->addPropertyCell32(cpuNode, "d-cache-size", 0x10000); + i_dt->addPropertyCell32(cpuNode, "i-cache-size", 0x8000); + i_dt->addPropertyCell32(cpuNode, "d-cache-line-size", 128); + i_dt->addPropertyCell32(cpuNode, "i-cache-line-size", 128); + i_dt->addPropertyCell32(cpuNode, "ibm,dfp", 1); + i_dt->addPropertyCell32(cpuNode, "ibm,vmx", 2); + i_dt->addPropertyCell32(cpuNode, "timebase-frequency", 512000000); + i_dt->addPropertyCell32(cpuNode, "clock-frequency", 2000000000); + i_dt->addPropertyCell32(cpuNode, "ibm,pir", pir.word); + i_dt->addPropertyCell32(cpuNode, "ibm,chip-id", l_chipid); + i_dt->addPropertyCells32(cpuNode, "ibm,processor-segment-sizes", + segmentSizes, + sizeof(segmentSizes) / sizeof(uint32_t)); + i_dt->addPropertyCells32(cpuNode, "ibm,segment-page-sizes", + segmentPageSizes, + sizeof(segmentPageSizes)/sizeof(uint32_t)); + i_dt->addPropertyCell32(cpuNode, "ibm,slb-size", 32); + + uint32_t interruptServerNum[THREADPERCORE]; + for(size_t i = 0; i < THREADPERCORE ; i++) + { + pir.threadId = i; + interruptServerNum[i] = pir.word; + } + + i_dt->addPropertyCells32(cpuNode, "ibm,ppc-interrupt-server#s", + interruptServerNum, THREADPERCORE); + + //IBASE ADDRESS + uint64_t l_ibase = INTR::getIntpAddr(l_ex, 0); + + rootNode = i_dt->findNode("/"); + dtOffset_t intNode = i_dt->addNode(rootNode, cpuIntrName, l_ibase); + const char* intr_compatStrs[] = {"ibm,ppc-xicp", "ibm,power8-xicp", + NULL}; + i_dt->addPropertyStrings(intNode, "compatible", intr_compatStrs); + uint32_t int_serv[2] = { interruptServerNum[0], THREADPERCORE}; + i_dt->addPropertyCells32(intNode, "ibm,interrupt-server-ranges", + int_serv, 2); + i_dt->addPropertyCell32(intNode, "#address-cells", 0); + i_dt->addPropertyCell32(intNode, "#interrupt-cells", 1); + i_dt->addPropertyString(intNode, "device_type", + "PowerPC-External-Interrupt-Presentation"); + uint64_t intr_prop[THREADPERCORE][2]; + for(size_t i=0; i < THREADPERCORE; i++) + { + intr_prop[i][0] = INTR::getIntpAddr(l_ex, i); + intr_prop[i][1] = 0x1000; + } + i_dt->addPropertyCells64(intNode, "reg", + reinterpret_cast(intr_prop), + sizeof(intr_prop) / sizeof(uint64_t)); + + /* TODO add associativity*/ + } + } + + return errhdl; +} + +errlHndl_t bld_fdt_mem(devTree * i_dt) +{ + errlHndl_t errhdl = NULL; + bool rc; + + do + { + + /* Find the / node and add a memory node(s) under it. */ + dtOffset_t rootNode = i_dt->findNode("/"); + + // Grab a system object to work with + TARGETING::Target* sys = NULL; + TARGETING::targetService().getTopLevelTarget(sys); + + // Get all functional proc chip targets + TARGETING::TargetHandleList l_cpuTargetList; + getAllChips(l_cpuTargetList, TYPE_PROC); + + for ( size_t proc = 0; + (!errhdl) && (proc < l_cpuTargetList.size()); proc++ ) + { + const TARGETING::Target * l_pProc = l_cpuTargetList[proc]; + + uint64_t l_bases[8] = {0,}; + uint64_t l_sizes[8] = {0,}; + rc = l_pProc->tryGetAttr(l_bases); + if(!rc) + { + /*@ + * @errortype + * @reasoncode DEVTREE::RC_ATTR_MEMBASE_GET_FAIL + * @moduleid DEVTREE::MOD_DEVTREE_BLD_MEM + * @userdata1 Return code from ATTR_GET + * @userdata2 Attribute Id that failed + * @devdesc Error retrieving attribute + */ + errhdl=new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_DEVTREE_BLD_MEM, + RC_ATTR_MEMBASE_GET_FAIL, + rc, + ATTR_PROC_MEM_BASES); + break; + } + + rc = l_pProc->tryGetAttr(l_sizes); + if(!rc) + { + /*@ + * @errortype + * @reasoncode DEVTREE::RC_ATTR_MEMSIZE_GET_FAIL + * @moduleid DEVTREE::MOD_DEVTREE_BLD_MEM + * @userdata1 Return code from ATTR_GET + * @userdata2 Attribute Id that failed + * @devdesc Error retrieving attribute + */ + errhdl=new ERRORLOG::ErrlEntry(ERRORLOG::ERRL_SEV_UNRECOVERABLE, + MOD_DEVTREE_BLD_MEM, + RC_ATTR_MEMSIZE_GET_FAIL, + rc, + ATTR_PROC_MEM_SIZES); + break; + } + + for (size_t i=0; i< 8; i++) + { + if(l_sizes[i]) //non zero means that there is memory present + { + dtOffset_t memNode = i_dt->addNode(rootNode, "memory", + l_bases[i]); + i_dt->addPropertyString(memNode, "device_type","memory"); + uint64_t propertyCells[2] = {l_bases[i],l_sizes[i]}; + i_dt->addPropertyCells64(memNode, "reg", propertyCells, 2); + + /*TODO -- add core affinity*/ + + /*TODO -- add VPD*/ + } + } + } + }while(0); + return errhdl; +} + +errlHndl_t bld_fdt_io(devTree * i_dt) +{ + errlHndl_t errhdl = NULL; + + + + return errhdl; +} + +errlHndl_t build_flatdevtree( void ) +{ + errlHndl_t errhdl = NULL; + devTree * dt = &Singleton::instance(); + + do + { + + TRACFCOMP( g_trac_devtree, "---devtree init---" ); + dt->initialize(DEVTREE_DATA_ADDR, DEVTREE_SPACE_SIZE); + + TRACFCOMP( g_trac_devtree, "---devtree cpu ---" ); + errhdl = bld_fdt_cpu(dt); + if(errhdl) + { + break; + } + + TRACFCOMP( g_trac_devtree, "---devtree mem ---" ); + errhdl = bld_fdt_mem(dt); + if(errhdl) + { + break; + } + + TRACFCOMP( g_trac_devtree, "---devtree io ---" ); + errhdl = bld_fdt_io(dt); + if(errhdl) + { + break; + } + }while(0); + + return errhdl; +} + + +uint64_t get_flatdevtree_phys_addr() +{ + return Singleton::instance().getBlobPhys(); +} + +} diff --git a/src/usr/devtree/devtree.C b/src/usr/devtree/devtree.C new file mode 100644 index 000000000..562bf876c --- /dev/null +++ b/src/usr/devtree/devtree.C @@ -0,0 +1,711 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/devtree/devtree.C $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/* $IBMCopyrightBlock: + IBM Confidential + + OCO Source Materials + + 5733-907 + + (C) Copyright IBM Corp. 2011 + + The source code for this program is not published or other- + wise divested of its trade secrets, irrespective of what has + been deposited with the U.S. Copyright Office. +$ */ +#include +#include +#include +#include "devtree.H" +#include +#include + +extern trace_desc_t *g_trac_devtree; + +namespace DEVTREE +{ + +uint64_t devTree::getBlobPhys() +{ + return mPhysAddr; +} + +uint32_t devTree::getSize() +{ + return mHeader->totalSize; +} + +void devTree::initialize(uint64_t i_addr, size_t i_maxSize) +{ + /* Initialize the device tree header. */ + mMaxSize = i_maxSize; + mPhysAddr = i_addr; + mSpace= static_cast + (mm_block_map(reinterpret_cast(mPhysAddr), + mMaxSize)); + memset(mSpace, 0, mMaxSize); + mNextPhandle = 1; + + TRACFCOMP( g_trac_devtree, "FDT located @ v:%p p:0x%x", mSpace, mPhysAddr); + + mHeader->magicNumber = DT_MAGIC; + mHeader->totalSize = sizeof(*mHeader) + (sizeof(dtReserveEntry_t) * 2); + mHeader->offsetStruct = mHeader->totalSize; + mHeader->offsetStrings = mHeader->totalSize; + mHeader->offsetReservedMemMap = sizeof(*mHeader); + mHeader->version = DT_CUR_VERSION; + mHeader->lastCompatVersion = DT_COMPAT_VERSION; + mHeader->bootCpuId = 0; + mHeader->sizeStrings = 0; + mHeader->sizeStruct = 0; + + /* Create the initial root node. */ + uint32_t* curWord = getStructSectionAtOffset(0); + *curWord++ = DT_BEGIN_NODE; + *curWord++ = 0; + *curWord++ = DT_END_NODE; + *curWord = DT_END; + + /* Adjust offsets and sizes to account for the root node we just added*/ + uint32_t structSizeAdded = sizeof(uint32_t) * 4; + mHeader->offsetStrings += structSizeAdded; + mHeader->sizeStruct += structSizeAdded; + mHeader->totalSize += structSizeAdded; + + /* Setup the memory reserve map to include the region that + Hostboot places the SLW and OCC images*/ + dtReserveEntry* reserveMemMap = (dtReserveEntry*) + (mSpace + mHeader->offsetReservedMemMap); + reserveMemMap->address = 0x0A000000; /*160MB-192MB*/; + reserveMemMap->size = MEGABYTE * 32; + + /* Add the standard root node properties. */ + dtOffset_t rootNode = findNode("/"); + addPropertyCell32(rootNode, "#address-cells", 2); + addPropertyCell32(rootNode, "#size-cells", 2); + addPropertyString(rootNode, "compatible", "ibm,powernv"); + + addPropertyString(rootNode, "model", "P8_Sim"); + + addNode(rootNode, "chosen"); + + // Add the initial vpd and location code nodes. + addProperty(rootNode, "ibm,vpd"); + addProperty(rootNode, "ibm,loc-code"); +} + +void devTree::setBootCpu(uint32_t pir) +{ + mHeader->bootCpuId = pir; +} + +dtOffset_t devTree::findNode(const char* nodePath) +{ + /* Get structure section and start out with the name of first node*/ + uint32_t* curWord = getStructSectionAtOffset(0); + dtOffset_t curOffset = 0; + + if(strlen(nodePath) == 1) + { + if(nodePath[0] == '/') + { + return 0; + } + else + { + return DT_INVALID_OFFSET; + } + } + + nodePath++; + int nodeNestLevel = 0; + curWord += 2; + curOffset += 8; + do + { + nodeNestLevel = 0; + /* Figure out how long the name of the current portion + of the path we're looking for is. */ + int currentPathLength = 0; + while(nodePath[currentPathLength] && + (nodePath[currentPathLength] != '/')) + { + currentPathLength++; + } + int done = 0; + do + { + switch(*curWord) + { + case DT_BEGIN_NODE: + { + if(nodeNestLevel == 0) + { + if(memcmp(curWord+1, nodePath, currentPathLength) == 0) + { + if(nodePath[currentPathLength] == NULL) + { + return curOffset; + } + else + { + done = 1; + } + } + } + + nodeNestLevel++; + + /* Figure out how far to advance to get past this node entry + Start by skipping over the node name. */ + int nodeSkipWords = getNodeTagAndNameWords(curOffset); + curWord += nodeSkipWords; + curOffset += nodeSkipWords * 4; + } + break; + + case DT_END_NODE: + { + if(nodeNestLevel == 0) + { + return DT_INVALID_OFFSET; + } + else + { + nodeNestLevel--; + /* Skip over the node end tag. */ + curWord++; + curOffset += 4; + } + } + break; + + case DT_PROP: + { + /* Skip over the property. */ + curWord++; + int propSkiWords = ((*curWord + 3) / 4) + 2; + curWord += propSkiWords; + curOffset += (propSkiWords + 1) * 4; + } + break; + + case DT_NOP: + { + curWord++; + curOffset += 4; + } + break; + + case DT_END: + return DT_INVALID_OFFSET; + break; + + default: + return DT_INVALID_OFFSET; + break; + } + } + while(!done); + nodePath += currentPathLength + 1; + } + while(*nodePath != NULL); + + /* We should never get here. */ + return DT_INVALID_OFFSET; +} + +dtOffset_t devTree::addNode(dtOffset_t parentNodeOffset, const char* nodeName) +{ + uint32_t* curWord = getStructSectionAtOffset(parentNodeOffset); + int skipWords = getNodeTagAndNameWords(parentNodeOffset); + + curWord += skipWords; + dtOffset_t newNodeOffset = parentNodeOffset + (skipWords * 4); + + /* There is a FDT rule that nodes must be after properties + so skip over any properties. */ + while(*curWord == DT_PROP) + { + int propertyWords = getPropertyWords(newNodeOffset); + curWord += propertyWords; + newNodeOffset += propertyWords * 4; + } + + size_t newNodeNameLength = strlen(nodeName); + int newNodeNameWords = (newNodeNameLength + 4) / 4; + insertStructSpace(newNodeOffset, newNodeNameWords + 2); + + *curWord++ = DT_BEGIN_NODE; + for(int i = 0; i < newNodeNameWords; ++i) + { + *curWord = 0; + memcpy(curWord, nodeName + (i * 4), + newNodeNameLength < 4 ? newNodeNameLength : 4); + if(newNodeNameLength < 4) + { + newNodeNameLength = 0; + } + else + { + newNodeNameLength -= 4; + } + curWord++; + } + + *curWord = DT_END_NODE; + + /* Always tack on a pHandle to each new node*/ + uint32_t newPhandle = mNextPhandle++; + addPropertyCell32(newNodeOffset, "phandle", newPhandle); + + return newNodeOffset; +} + +dtOffset_t devTree::addNode(dtOffset_t parentNodeOffset, + const char* nodeName, uint64_t unitAddress) +{ + char nodeNameWithUnitAddress[1024]; + sprintf(nodeNameWithUnitAddress, "%s@%lx", nodeName, unitAddress); + return addNode(parentNodeOffset, nodeNameWithUnitAddress); +} + +void devTree::addProperty(dtOffset_t parentNodeOffset, const char* propertyName) +{ + uint32_t* curWord = getStructSectionAtOffset(parentNodeOffset); + int skipWords = getNodeTagAndNameWords(parentNodeOffset); + + curWord += skipWords; + dtOffset_t newPropertyOffset = parentNodeOffset + (skipWords * 4); + insertStructSpace(newPropertyOffset, 3); + + *curWord++ = DT_PROP; + *curWord++ = 0; + *curWord++ = addString(propertyName); +} + +void devTree::addPropertyString(dtOffset_t parentNodeOffset, + const char* propertyName, + const char* propertyData) +{ + uint32_t* curWord = getStructSectionAtOffset(parentNodeOffset); + int skipWords = getNodeTagAndNameWords(parentNodeOffset); + + curWord += skipWords; + dtOffset_t newPropertyOffset = parentNodeOffset + (skipWords * 4); + size_t newPropertyDataLength = strlen(propertyData); + int newPropertyDataWords = (newPropertyDataLength + 4) / 4; + insertStructSpace(newPropertyOffset, newPropertyDataWords + 3); + + *curWord++ = DT_PROP; + *curWord++ = newPropertyDataLength + 1; + *curWord++ = addString(propertyName); + + for(int i = 0; i < newPropertyDataWords; ++i) + { + *curWord = 0; + memcpy(curWord, propertyData + (i * 4), + newPropertyDataLength < 4 ? newPropertyDataLength : 4); + if(newPropertyDataLength < 4) + { + newPropertyDataLength = 0; + } + else + { + newPropertyDataLength -= 4; + } + curWord++; + } +} + +void devTree::addPropertyBytes(dtOffset_t parentNodeOffset, + const char* propertyName, + const uint8_t* propertyData, + uint32_t numBytes) +{ + uint32_t* curWord = getStructSectionAtOffset(parentNodeOffset); + int skipWords = getNodeTagAndNameWords(parentNodeOffset); + + curWord += skipWords; + dtOffset_t newPropertyOffset = parentNodeOffset + (skipWords * 4); + size_t newPropertyDataLength = numBytes; + int newPropertyDataWords = (newPropertyDataLength + 3) / 4; + insertStructSpace(newPropertyOffset, newPropertyDataWords + 3); + + *curWord++ = DT_PROP; + *curWord++ = newPropertyDataLength; + *curWord++ = addString(propertyName); + + for(int i = 0; i < newPropertyDataWords; ++i) + { + *curWord = 0; + memcpy(curWord, propertyData + (i * 4), + newPropertyDataLength < 4 ? newPropertyDataLength : 4); + if(newPropertyDataLength < 4) + { + newPropertyDataLength = 0; + } + else + { + newPropertyDataLength -= 4; + } + curWord++; + } +} + +void devTree::addPropertyStrings(dtOffset_t parentNodeOffset, + const char* propertyName, + const char** propertyData) +{ + uint32_t* curWord = getStructSectionAtOffset(parentNodeOffset); + int skipWords = getNodeTagAndNameWords(parentNodeOffset); + + size_t totalDataSize = 0; + int numStrings = 0; + /* Figure out the total size of the data in the property. */ + for(int stringIndex = 0; + propertyData[stringIndex] && *propertyData[stringIndex]; stringIndex++) + { + totalDataSize += strlen(propertyData[stringIndex]) + 1; + numStrings++; + } + + curWord += skipWords; + dtOffset_t newPropertyOffset = parentNodeOffset + (skipWords * 4); + size_t newPropertyDataLength = totalDataSize; + int newPropertyDataWords = (newPropertyDataLength + 3) / 4; + insertStructSpace(newPropertyOffset, newPropertyDataWords + 3); + + *curWord++ = DT_PROP; + *curWord++ = newPropertyDataLength ; + *curWord++ = addString(propertyName); + + for(int i = 0; i < newPropertyDataWords; ++i) + { + *(curWord + i) = 0; + } + + char* target = (char*)curWord; + for(int stringIndex = 0; stringIndex < numStrings; stringIndex++) + { + size_t curStringLen = strlen(propertyData[stringIndex]); + memcpy(target, propertyData[stringIndex], curStringLen); + target += curStringLen + 1; + } +} + +void devTree::addPropertyCell32(dtOffset_t parentNodeOffset, + const char* propertyName, + const uint32_t cell) +{ + uint32_t cells[1] = { cell }; + addPropertyCells32(parentNodeOffset, propertyName, cells, 1); +} + +void devTree::addPropertyCell64(dtOffset_t parentNodeOffset, + const char* propertyName, + const uint64_t cell) +{ + uint64_t cells[1] = { cell }; + addPropertyCells64(parentNodeOffset, propertyName, cells, 1); +} + +void devTree::addPropertyCells32(dtOffset_t parentNodeOffset, + const char* propertyName, + uint32_t cells[], uint32_t numCells) +{ + uint32_t* curWord = getStructSectionAtOffset(parentNodeOffset); + int skipWords = getNodeTagAndNameWords(parentNodeOffset); + + curWord += skipWords; + dtOffset_t newPropertyOffset = parentNodeOffset + (skipWords * 4); + int newPropertyDataLength = numCells * 4; + int newPropertyDataWords = numCells; + insertStructSpace(newPropertyOffset, newPropertyDataWords + 3); + + *curWord++ = DT_PROP; + *curWord++ = newPropertyDataLength; + *curWord++ = addString(propertyName); + + for(uint32_t i = 0; i < numCells; ++i) + { + *curWord++ = cells[i]; + } +} + +void devTree::addPropertyCells64(dtOffset_t parentNodeOffset, + const char* propertyName, + uint64_t cells[], uint32_t numCells) +{ + uint32_t* curWord = getStructSectionAtOffset(parentNodeOffset); + int skipWords = getNodeTagAndNameWords(parentNodeOffset); + + curWord += skipWords; + dtOffset_t newPropertyOffset = parentNodeOffset + (skipWords * 4); + int newPropertyDataLength = numCells * 8; + int newPropertyDataWords = numCells * 2; + insertStructSpace(newPropertyOffset, newPropertyDataWords + 3); + + *curWord++ = DT_PROP; + *curWord++ = newPropertyDataLength; + *curWord++ = addString(propertyName); + + for(uint32_t i = 0; i < numCells; ++i) + { + *curWord++ = cells[i] >> 32; + *curWord++ = cells[i]; + } +} + +int devTree::getNodeTagAndNameWords(dtOffset_t nodeOffset) +{ + size_t nodeNameAndTagWords = 1; + uint32_t* curWord = getStructSectionAtOffset(nodeOffset); + nodeNameAndTagWords += (strlen((char*)(curWord + 1)) + 4) / 4; + return nodeNameAndTagWords; +} + +void devTree::insertStructSpace(uint32_t offset, int numNewWords) +{ + uint32_t* firstWord = getStructSectionAtOffset(0); + int numCurrentWords = mHeader->sizeStruct / 4; + /* Mode the string section out of the way first. */ + shiftStringsSection(numNewWords * 4); + /* Now insert space into the struct section. */ + assert((mHeader->totalSize + (numNewWords * 4)) < mMaxSize); + mHeader->sizeStruct += numNewWords * 4; + mHeader->totalSize += numNewWords * 4; + + uint32_t* srcWord = firstWord + numCurrentWords - 1; + uint32_t* tgtWord = firstWord + numCurrentWords + numNewWords - 1; + int numCopyWords = numCurrentWords - (offset / 4); + while(numCopyWords--) + { + *tgtWord = *srcWord; + tgtWord--; + srcWord--; + }; +} + +void devTree::shiftStringsSection(int shiftSize) +{ + /* We always move it forward so copy it from the end to the beginning. */ + uint32_t stringSectionSize = mHeader->sizeStrings; + char* src = mSpace + mHeader->offsetStrings; + char* tgt = src + shiftSize; + + memmove(tgt, src, stringSectionSize); + + mHeader->offsetStrings += shiftSize; + + /* Clear out the area we just shifted out of so that it's easier to + debug the blob. */ + memset(src, 0, shiftSize); +} + +int devTree::getPropertyWords(int propertyOffset) +{ + int propertyWords = 3; + uint32_t* curWord = getStructSectionAtOffset(propertyOffset); + curWord++; /* Skip over the DT_PROP tag */ + propertyWords += (*curWord + 3) / 4; + return propertyWords; +} + +dtOffset_t devTree::addString(const char *string) +{ + dtOffset_t stringOffset = 0; + size_t stringSize = strlen(string) + 1; + char* stringSection = mSpace + mHeader->offsetStrings; + uint32_t stringSectionSize = mHeader->sizeStrings; + + /* Search for the string as long as we know it could still be there. */ + while(stringSize <= (stringSectionSize - stringOffset)) + { + if(memcmp(stringSection, string, stringSize) == 0) + { + return stringOffset; + } + else + { + size_t curStringLength = strlen(stringSection) + 1; + stringOffset += curStringLength; + stringSection += curStringLength; + } + } + + /* We didn't find a string to reuse so tack this one on the end. */ + stringOffset = mHeader->sizeStrings; + memcpy(mSpace + mHeader->offsetStrings + stringOffset, string, stringSize); + assert((mHeader->totalSize + stringSize) < mMaxSize); + mHeader->sizeStrings += stringSize; + mHeader->totalSize += stringSize; + return stringOffset; +} + +bool devTree::locateStringOffset(const char* string, uint32_t& stringOffset) +{ + bool foundStringOffset = false; + stringOffset = 0; + size_t stringSize = strlen(string) + 1; + char* stringSection = mSpace + mHeader->offsetStrings; + uint32_t stringSectionSize = mHeader->sizeStrings; + + /* Search for the string as long as we know it could still be there. */ + while(stringSize <= (stringSectionSize - stringOffset)) + { + if(memcmp(stringSection, string, stringSize) == 0) + { + foundStringOffset = true; + break; + } + else + { + size_t curStringLength = strlen(stringSection) + 1; + stringOffset += curStringLength; + stringSection += curStringLength; + } + } + + return foundStringOffset; +} + +void* devTree::findProperty(dtOffset_t nodeOffset, const char* propertyName) +{ + uint32_t nameOffset = 0; + void *propertyData = NULL; + + if(locateStringOffset(propertyName, nameOffset)) + { + uint32_t* curWord = getStructSectionAtOffset(nodeOffset); + int skipWords = getNodeTagAndNameWords(nodeOffset); + + curWord += skipWords; + dtOffset_t curOffset = nodeOffset + (skipWords * 4); + + while(*curWord == DT_PROP) + { + /* Check if this is the property we are searching for. */ + if(*(curWord + 2) == nameOffset) + { + /* It is, we found it. */ + return (void*)(curWord + 3); + } + else + { + int propertyWords = getPropertyWords(curOffset); + curWord += propertyWords; + curOffset += propertyWords * 4; + } + } + } + + return propertyData; +} + +uint32_t devTree::getPhandle(dtOffset_t nodeOffset) +{ + uint32_t* phandlePtr = (uint32_t*) findProperty(nodeOffset, "phandle"); + if(phandlePtr) + { + return *phandlePtr; + } + + /* We didn't find a phandle, so we need to add one. */ + uint32_t newPhandle = mNextPhandle++; + addPropertyCell32(nodeOffset, "phandle", newPhandle); + return newPhandle; +} + +void devTree::appendPropertyBytes(dtOffset_t parentNode, + const char* propertyName, + const uint8_t* propertyData, + uint32_t numBytes) +{ + uint32_t nameOffset = 0; + + if(locateStringOffset(propertyName, nameOffset)) + { + uint32_t* curWord = getStructSectionAtOffset(parentNode); + int skipWords = getNodeTagAndNameWords(parentNode); + + curWord += skipWords; + dtOffset_t curOffset = parentNode + (skipWords * 4); + + while(*curWord == DT_PROP) + { + /* Check if this is the property we are searching for. */ + if(*(curWord + 2) == nameOffset) + { + /* It is, we found it. */ + uint32_t curPropertyDataLength = *(curWord + 1); + *(curWord + 1) = curPropertyDataLength + numBytes; + uint8_t* newDataLocation = ((uint8_t*)(curWord + 3)) + + curPropertyDataLength; + uint32_t curPropertyDataWords = (curPropertyDataLength + 3) / 4; + uint32_t newPropertyDataWords = (curPropertyDataLength + + numBytes + 3) / 4; + uint32_t propertyDataWordsToAdd = newPropertyDataWords + - curPropertyDataWords; + if(propertyDataWordsToAdd) + { + uint32_t insertOffset =curOffset + + ((3 + curPropertyDataWords) * 4); + insertStructSpace(insertOffset, propertyDataWordsToAdd); + } + memcpy(newDataLocation, propertyData, numBytes); + break; + } + else + { + int propertyWords = getPropertyWords(curOffset); + curWord += propertyWords; + curOffset += propertyWords * 4; + } + } + } +} + + +/******************** +Internal Methods +********************/ + +/** + * @brief Constructor +*/ +devTree::devTree() +:mSpace(NULL), mMaxSize(0) +{ + //Nothing right now... +} + +/** + * @brief Destructor + */ +devTree::~devTree() +{ + mm_block_unmap(mSpace); +} + +} diff --git a/src/usr/devtree/devtree.H b/src/usr/devtree/devtree.H new file mode 100644 index 000000000..1056ed304 --- /dev/null +++ b/src/usr/devtree/devtree.H @@ -0,0 +1,332 @@ +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/devtree/devtree.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ +/* $IBMCopyrightBlock: + IBM Confidential + + OCO Source Materials + + 5733-907 + + (C) Copyright IBM Corp. 2011 + + The source code for this program is not published or other- + wise divested of its trade secrets, irrespective of what has + been deposited with the U.S. Copyright Office. +$ */ +#include + +#ifndef _DEVTREE_H +#define _DEVTREE_H + +namespace DEVTREE +{ +typedef size_t dtOffset_t; + + + /** + * The devtree class that does the actual work of + * generating and manipulating the devtree + * + */ + class devTree + { + public: + + /** + * Initialize the FDT at address and size + * @param[in] i_addr Physical address to place FDT at + * @param[in] i_maxSize Size of FDT + */ + void initialize(uint64_t i_addr, size_t i_maxSize); + + /** + * Find given node (e.g. "/lpc") in the FDT + * @param[in] nodePath NULL terminated string of the path + * @return dtOffset_t into FDT of node location + */ + dtOffset_t findNode(const char* nodePath); + + /** + * Find and return a pointer to a property within a node + * @param[in] nodeOffset Offset into FDT to start looking + * @param[in] propertyName NULL terminated string of the property + to get + * @return void* pointer to dtOffset_t into FDT of node location + */ + void* findProperty(dtOffset_t nodeOffset, const char* propertyName); + + /** + * Add a new node under the parent node + * @param[in] parentNode Offset to parent node + * @param[in] nodeName NULL terminated string of node to add + * @return dtOffset_t into FDT of node location + */ + dtOffset_t addNode(dtOffset_t parentNode, const char* nodeName); + + /** + * Add a new node under the parent node with address + * @param[in] parentNode Offset to parent node + * @param[in] nodeName NULL terminated string of node to add + * @param[in] unitAddress Address of the node + * @return dtOffset_t into FDT of node location + */ + dtOffset_t addNode(dtOffset_t parentNode, const char* nodeName, + uint64_t unitAddress); + + /** + * Add a property to a node with no data + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + */ + void addProperty(dtOffset_t parentNode, const char* propertyName); + + /** + * Add a property to a node with free form bytes + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] propertyData Data to add + * @param[in] numBytes Number of data bytes + */ + void addPropertyBytes(dtOffset_t parentNode, const char* propertyName, + const uint8_t* propertyData, uint32_t numBytes); + + /** + * Add a property to a node with string data + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] propertyData NULL terminated string data + */ + void addPropertyString(dtOffset_t parentNode, const char* propertyName, + const char* propertyData); + + /** + * Add a property to a node with array of strings + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] propertyData NULL terminated array of strings, last + * string must be NULL + */ + void addPropertyStrings(dtOffset_t parentNode, const char* propertyName, + const char** propertyData); + + /** + * Add a property to a node with a 32 bit "cell" (aka uint32_t data) + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] cell Data to add + */ + void addPropertyCell32(dtOffset_t parentNode, const char* propertyName, + const uint32_t cell); + + /** + * Add a property to a node with a 64 bit "cell" (aka uint64_t data) + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] cell Data to add + */ + void addPropertyCell64(dtOffset_t parentNode, const char* propertyName, + const uint64_t cell); + + /** + * Add a property to a node with a 32 bit array of "cells" + * (aka uint32_t data) + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] cells Array of uint32_t data + * @param[in] numCells Number of cells + */ + void addPropertyCells32(dtOffset_t parentNode, const char* propertyName, + uint32_t cells[], uint32_t numCells); + + /** + * Add a property to a node with a 64 bit array of "cells" + * (aka uint64_t data) + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] cells Array of uint64_t data + * @param[in] numCells Number of cells + */ + void addPropertyCells64(dtOffset_t parentNode, const char* propertyName, + uint64_t cells[], uint32_t numCells); + + /** + * Return the physical "blob" address to the start of the FDT + * @return uin64_t to the start of the FDT memory + */ + uint64_t getBlobPhys(); + + /** + * Each devtree node has a "handle" number. This function returns the + * handle number for given node. + * @param[in] nodeOffset Offset to node + * @return uin32_t Handle number for node + */ + uint32_t getPhandle(dtOffset_t nodeOffset); + + /** + * Append bytes to a property + * @param[in] parentNode Offset to node to add property to + * @param[in] propertyName NULL terminated string of property name + * @param[in] propertyData Data to add + * @param[in] numBytes Number of data bytes + */ + void appendPropertyBytes(dtOffset_t parentNode, + const char* propertyName, + const uint8_t* propertyData, + uint32_t numBytes); + + /** + * Return the current size of the FDT (not max) + * @return uin32_t Size of the FDT + */ + uint32_t getSize(); + + + protected: + /*Constructor*/ + devTree(); + + /*Destructor*/ + ~devTree(); + + /** + * Get the internal struct section at node offset + * @param[in] offset Offset to node + * @return uin32_t* pointer to struct section + */ + inline uint32_t* getStructSectionAtOffset(dtOffset_t offset); + + /** + * Utility function to get the length fo the tag/name words for + * given node + * @param[in] nodeOffset Offset to node + * @return int Words consumed by tag/name in FDT + */ + int getNodeTagAndNameWords(dtOffset_t nodeOffset); + + /** + * Utility function to get the length fo the tag/name words for + * given node + * @param[in] nodeOffset Offset to node + * @return int Words consumed by tag/name in FDT + */ + void insertStructSpace(uint32_t offset, int numNewWords); + + /** + * Utility function to shift the string section + * @param[in] shiftSize Amount to shift + */ + void shiftStringsSection(int shiftSize); + + /** + * Get number of words for property + * @param[in] propertyOffset Offset of property + * @return int Words consumed by Property + */ + int getPropertyWords(int propertyOffset); + + /** + * Utility function to add String to string table + * @param[in] string NULL terminated string to add + * @return dtOffset_t Offset string was added at + */ + dtOffset_t addString(const char *string); + + /** + * Set the boot CPU PIR into FDT + * @param[in] pir PIR value for boot processor + */ + void setBootCpu(uint32_t pir); + + /** + * Utility function to locate string in string table + * @param[in] string NULL terminated string to find + * @param[out] stringOffset Offset if found + * @return bool True if found + */ + bool locateStringOffset(const char* string, uint32_t& stringOffset); + + + private: + + enum Constants { + DT_MAGIC =0xd00dfeed, + DT_CUR_VERSION =0x11, + DT_COMPAT_VERSION =0x10, + + DT_BEGIN_NODE =0x1, + DT_END_NODE =0x2, + DT_PROP =0x3, + DT_NOP =0x4, + DT_END =0x9, + DT_INVALID_OFFSET =0xFFFFFFFF, + + }; + + + typedef struct dtHeader + { + uint32_t magicNumber; + uint32_t totalSize; + uint32_t offsetStruct; + uint32_t offsetStrings; + uint32_t offsetReservedMemMap; + uint32_t version; + uint32_t lastCompatVersion; + uint32_t bootCpuId; + uint32_t sizeStrings; + uint32_t sizeStruct; + } + dtHeader_t; + + typedef struct dtReserveEntry + { + uint64_t address; + uint64_t size; + } + dtReserveEntry_t; + + + + union + { + dtHeader_t* mHeader; + char* mSpace; + }; + uint32_t mNextPhandle; + size_t mMaxSize; + uint64_t mPhysAddr; + + // let my testcase poke around + friend class devTreeTest; + + }; + + + + uint32_t* devTree::getStructSectionAtOffset(dtOffset_t offset) + { + return (uint32_t*) (mSpace + mHeader->offsetStruct + offset); + } +} +#endif /* _DEVTREE_H */ diff --git a/src/usr/devtree/makefile b/src/usr/devtree/makefile new file mode 100644 index 000000000..8c727229a --- /dev/null +++ b/src/usr/devtree/makefile @@ -0,0 +1,35 @@ +# IBM_PROLOG_BEGIN_TAG +# This is an automatically generated prolog. +# +# $Source: src/usr/devtree/makefile $ +# +# IBM CONFIDENTIAL +# +# COPYRIGHT International Business Machines Corp. 2012,2013 +# +# p1 +# +# Object Code Only (OCO) source materials +# Licensed Internal Code Source Materials +# IBM HostBoot Licensed Internal Code +# +# The source code for this program is not published or otherwise +# divested of its trade secrets, irrespective of what has been +# deposited with the U.S. Copyright Office. +# +# Origin: 30 +# +# IBM_PROLOG_END_TAG + +# +# The runtime module provides code to handle manipulating data +# for the host. For example, verifying HDAT fields and writing +# attribute data for HostServices. +# + +ROOTPATH = ../../.. +MODULE = devtree + +OBJS = devtree.o bld_devtree.o + +include ${ROOTPATH}/config.mk diff --git a/src/usr/hwpf/hwp/start_payload/start_payload.C b/src/usr/hwpf/hwp/start_payload/start_payload.C index 1a8619307..3c06db171 100644 --- a/src/usr/hwpf/hwp/start_payload/start_payload.C +++ b/src/usr/hwpf/hwp/start_payload/start_payload.C @@ -65,6 +65,7 @@ #include "start_payload.H" #include +#include // Uncomment these files as they become available: // #include "host_start_payload/host_start_payload.H" @@ -119,6 +120,7 @@ void* call_host_runtime_setup( void *io_pArgs ) do { + // Need to load up the runtime module if it isn't already loaded if ( !VFS::module_is_loaded( "libruntime.so" ) ) { @@ -199,18 +201,32 @@ void* call_host_runtime_setup( void *io_pArgs ) } break; } - - // Write the HostServices attributes into mainstore - l_err = RUNTIME::populate_attributes(); - if ( l_err ) + else if( TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind) { - TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, - "Could not populate attributes" ); - // break from do loop if error occured - break; + // Write the devtree out + l_err = DEVTREE::build_flatdevtree(); + if ( l_err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "Could not build dev tree" ); + // break from do loop if error occured + break; + } + } + else + { + // Write the HostServices attributes into mainstore + l_err = RUNTIME::populate_attributes(); + if ( l_err ) + { + TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, + "Could not populate attributes" ); + // break from do loop if error occured + break; + } } - // - Update HDAT with tpmd logs + // - Update HDAT/DEVTREE with tpmd logs } while(0); @@ -331,6 +347,7 @@ errlHndl_t callShutdown ( void ) errlHndl_t err = NULL; uint64_t payloadBase = 0x0; uint64_t payloadEntry = 0x0; + uint64_t payloadData = 0x0; bool istepModeFlag = false; uint64_t status = SHUTDOWN_STATUS_GOOD; @@ -417,13 +434,22 @@ errlHndl_t callShutdown ( void ) break; } + // Load payload data if in SAPPHIRE mode + TARGETING::ATTR_PAYLOAD_KIND_type payload_kind + = sys->getAttr(); + if( TARGETING::PAYLOAD_KIND_SAPPHIRE == payload_kind ) + { + payloadData = DEVTREE::get_flatdevtree_phys_addr(); + } + // do the shutdown. TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace, "callShutdown finished, shutdown = 0x%x.", status ); INITSERVICE::doShutdown( status, payloadBase, - payloadEntry ); + payloadEntry, + payloadData); } while( 0 ); diff --git a/src/usr/initservice/baseinitsvc/initservice.C b/src/usr/initservice/baseinitsvc/initservice.C index 4e8dd8aa9..e3ca0160b 100644 --- a/src/usr/initservice/baseinitsvc/initservice.C +++ b/src/usr/initservice/baseinitsvc/initservice.C @@ -617,11 +617,13 @@ void InitService::registerBlock(void* i_vaddr, uint64_t i_size, void doShutdown ( uint64_t i_status, uint64_t i_payload_base, - uint64_t i_payload_entry ) + uint64_t i_payload_entry, + uint64_t i_payload_data) { Singleton::instance().doShutdown( i_status, i_payload_base, - i_payload_entry ); + i_payload_entry, + i_payload_data); while(1) { @@ -631,7 +633,8 @@ void doShutdown ( uint64_t i_status, void InitService::doShutdown(uint64_t i_status, uint64_t i_payload_base, - uint64_t i_payload_entry) + uint64_t i_payload_entry, + uint64_t i_payload_data) { int l_rc = 0; errlHndl_t l_err = NULL; @@ -682,7 +685,7 @@ void InitService::doShutdown(uint64_t i_status, l_rb_iter++; } - shutdown(i_status, i_payload_base, i_payload_entry); + shutdown(i_status, i_payload_base, i_payload_entry, i_payload_data); } bool InitService::registerShutdownEvent(msg_q_t i_msgQ, diff --git a/src/usr/initservice/baseinitsvc/initservice.H b/src/usr/initservice/baseinitsvc/initservice.H index 1457dc48d..795afae27 100644 --- a/src/usr/initservice/baseinitsvc/initservice.H +++ b/src/usr/initservice/baseinitsvc/initservice.H @@ -1,25 +1,25 @@ -// IBM_PROLOG_BEGIN_TAG -// This is an automatically generated prolog. -// -// $Source: src/usr/initservice/baseinitsvc/initservice.H $ -// -// IBM CONFIDENTIAL -// -// COPYRIGHT International Business Machines Corp. 2011 -// -// p1 -// -// Object Code Only (OCO) source materials -// Licensed Internal Code Source Materials -// IBM HostBoot Licensed Internal Code -// -// The source code for this program is not published or other- -// wise divested of its trade secrets, irrespective of what has -// been deposited with the U.S. Copyright Office. -// -// Origin: 30 -// -// IBM_PROLOG_END +/* IBM_PROLOG_BEGIN_TAG */ +/* This is an automatically generated prolog. */ +/* */ +/* $Source: src/usr/initservice/baseinitsvc/initservice.H $ */ +/* */ +/* IBM CONFIDENTIAL */ +/* */ +/* COPYRIGHT International Business Machines Corp. 2011,2013 */ +/* */ +/* p1 */ +/* */ +/* Object Code Only (OCO) source materials */ +/* Licensed Internal Code Source Materials */ +/* IBM HostBoot Licensed Internal Code */ +/* */ +/* The source code for this program is not published or otherwise */ +/* divested of its trade secrets, irrespective of what has been */ +/* deposited with the U.S. Copyright Office. */ +/* */ +/* Origin: 30 */ +/* */ +/* IBM_PROLOG_END_TAG */ #ifndef __BASEINITSVC_INITSERVICE_H #define __BASEINITSVC_INITSERVICE_H @@ -207,6 +207,8 @@ public: * payload. * @param[in] i_payload_entry - The offset from base address of the * payload entry-point. + * @param[in] i_payload_entry - HRMOR adjusted address of any payload data + * placed in r3 * * @return Nothing * @note This calls registered services to notify them of shutdown and it @@ -214,7 +216,8 @@ public: */ void doShutdown ( uint64_t i_status, uint64_t i_payload_base = 0, - uint64_t i_payload_entry = 0 ); + uint64_t i_payload_entry = 0, + uint64_t i_payload_data = 0); protected: diff --git a/src/usr/intr/intrrp.C b/src/usr/intr/intrrp.C index 8838d22cf..11339dbc6 100644 --- a/src/usr/intr/intrrp.C +++ b/src/usr/intr/intrrp.C @@ -1619,6 +1619,7 @@ void IntrRp::cleanCheck() } } + //---------------------------------------------------------------------------- // External interfaces //---------------------------------------------------------------------------- @@ -1831,3 +1832,20 @@ errlHndl_t INTR::enablePsiIntr(TARGETING::Target * i_target) return err; } +uint64_t INTR::getIntpAddr(const TARGETING::Target * i_ex, uint8_t i_thread) +{ + const TARGETING::Target * l_proc = getParentChip(i_ex); + uint64_t l_intB =l_proc->getAttr(); + + PIR_t pir(0); + pir.nodeId = l_proc->getAttr(); + pir.chipId = l_proc->getAttr(); + pir.coreId = i_ex->getAttr(); + pir.threadId = i_thread; + + return (l_intB+ InterruptMsgHdlr::mmio_offset( + pir.word & (InterruptMsgHdlr::P8_PIR_THREADID_MSK | + InterruptMsgHdlr::P8_PIR_COREID_MSK))); +} + + diff --git a/src/usr/intr/intrrp.H b/src/usr/intr/intrrp.H index c4301e7eb..a05bff542 100644 --- a/src/usr/intr/intrrp.H +++ b/src/usr/intr/intrrp.H @@ -43,38 +43,6 @@ namespace TARGETING namespace INTR { - /** - * cpu PIR register - */ - struct PIR_t - { - union - { - uint32_t word; - struct - { - //P8: - uint32_t reserved:19; //!< zeros - uint32_t nodeId:3; //!< node (0-3) - uint32_t chipId:3; //!< chip pos on node (0-5) - uint32_t coreId:4; //!< Core number (1-6,9-14)? - uint32_t threadId:3; //!< Thread number (0-7) - } PACKED; - }; - PIR_t(uint32_t i_word = 0) : word(i_word) {} - - PIR_t operator= (uint32_t i_word) - { - word = i_word; - return word; - } - - bool operator< (const PIR_t& r) const - { - return word < r.word; - } - }; - /** * Make an XISR value * @param[in] i_node The PIR node id (0-7) diff --git a/src/usr/makefile b/src/usr/makefile index 1bad2ebe7..5855729f0 100644 --- a/src/usr/makefile +++ b/src/usr/makefile @@ -30,6 +30,6 @@ SUBDIRS = example.d trace.d cxxtest.d testcore.d errl.d devicefw.d \ scom.d xscom.d targeting.d initservice.d hwpf.d \ ecmddatabuffer.d pnor.d i2c.d vfs.d fsi.d hwas.d fsiscom.d \ intr.d pore.d util.d mbox.d diag.d vpd.d scan.d \ - runtime.d ibscom.d dump.d secureboot.d + runtime.d ibscom.d dump.d secureboot.d devtree.d include ${ROOTPATH}/config.mk diff --git a/src/usr/targeting/common/xmltohb/attribute_types.xml b/src/usr/targeting/common/xmltohb/attribute_types.xml index 5ecc7ecf5..b8123c422 100644 --- a/src/usr/targeting/common/xmltohb/attribute_types.xml +++ b/src/usr/targeting/common/xmltohb/attribute_types.xml @@ -2030,9 +2030,13 @@ 2 - NONE + SAPPHIRE 3 + + NONE + 4 + UNKNOWN -- cgit v1.2.1