diff options
author | Zane Shelley <zshelle@us.ibm.com> | 2017-07-18 19:59:52 -0500 |
---|---|---|
committer | Martha Broyles <mbroyles@us.ibm.com> | 2017-07-20 17:10:34 -0400 |
commit | 237557e36673c70772d163913581cb9dfd83c96d (patch) | |
tree | aa1b47403ae7afa64b256045622ba70b8f4ed248 /src | |
parent | 7cdcf4db35261a60df8a10ac06ce24d587b7626b (diff) | |
download | talos-occ-237557e36673c70772d163913581cb9dfd83c96d.tar.gz talos-occ-237557e36673c70772d163913581cb9dfd83c96d.zip |
FIRDATA: fixed structure alignment in firdata code
Change-Id: I13b03ee6fd21b96eebeb0f141ab294b24ccad6f8
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43293
Reviewed-by: Caleb N. Palmer <cnpalmer@us.ibm.com>
Reviewed-by: Benjamin J. Weisenbeck <bweisenb@us.ibm.com>
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Reviewed-by: Martha Broyles <mbroyles@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/occ_405/firdata/firData.c | 13 | ||||
-rw-r--r-- | src/occ_405/firdata/homerData_common.h | 91 | ||||
-rw-r--r-- | src/occ_405/firdata/pnorData_common.h | 33 |
3 files changed, 76 insertions, 61 deletions
diff --git a/src/occ_405/firdata/firData.c b/src/occ_405/firdata/firData.c index 03b822b..299f92b 100644 --- a/src/occ_405/firdata/firData.c +++ b/src/occ_405/firdata/firData.c @@ -805,7 +805,11 @@ void FirData_addTrgtsToPnor( FirData_t * io_fd ) memset(&l_existBits, 0x00, sizeof(FirData_existBits_t) ); /* Point past HOMER header to first chiplet info */ - uint8_t *l_bytePtr = io_fd->hBuf + sizeof(HOMER_Data_t); + /* The HOMER_Data_t struct may have some padding added after the struct + * to ensure the HOMER_Chip_t structs are 4-byte word aligned. */ + uint32_t sz_word = sizeof(uint32_t); + uint32_t pad = (sz_word - (sizeof(HOMER_Data_t) % sz_word)) % sz_word; + uint8_t *l_bytePtr = io_fd->hBuf + sizeof(HOMER_Data_t) + pad; HOMER_Chip_t *l_chipPtr = NULL; TRAC_INFO("AddTgtsMain:numChips:%d", io_fd->hData->chipCount); @@ -1265,8 +1269,11 @@ int32_t FirData_init( FirData_t * io_fd, break; } - /* Now, skip chip sections. */ - reglist = io_fd->hBuf + sz_hData; + /* Now, skip chip sections. Note that the HOMER_Data_t struct may have + * some padding added after the struct to ensure the HOMER_Chip_t + * structs are 4-byte word aligned. */ + uint32_t pad = (sz_u32 - (sz_hData % sz_u32)) % sz_u32; + reglist = io_fd->hBuf + sz_hData + pad; HOMER_Chip_t *l_chiptPtr = NULL; /* Need to skip over chip list **/ diff --git a/src/occ_405/firdata/homerData_common.h b/src/occ_405/firdata/homerData_common.h index 9b09086..66aa53a 100644 --- a/src/occ_405/firdata/homerData_common.h +++ b/src/occ_405/firdata/homerData_common.h @@ -52,9 +52,21 @@ * - Register address lists - These lists vary in size depending on the number * of register addresses needed in each list. The list counts are stored in * HOMER_Data_t::regCounts. Order of the lists must match the array indexes - * HOMER_Data_t::regCounts, which are specified in TrgtType_t and + * of HOMER_Data_t::regCounts, which are specified in TrgtType_t and * RegType_t. * + * - Chip specific address list - This is a list of HOMER_ChipSpecAddr_t + * structs and will vary in size depending on the number of register + * addresses that are specific to a certain chip or DD level. The number of + * entries in this list is stored in HOMER_Data_t::ecDepCounts. + * + * IMPORTANT NOTE: All of the structs used here are packed. Therefore, we must + * ensure the variables within the struct are byte aligned. Meaning each + * uint32_t within the struct must be 4-byte aligned and each uint16_t must + * be 2-byte aligned. This also means the structs must always start on a + * 4-bye word boundary to maintain alignment. This is required due to the + * limitations of the PPE42/SRAM hardware. + * * Note that FIRs and indirect-SCOM FIRs characterize a set of registers to * capture. In addition to capturing the FIR (or ID FIR), the OCC will need to * capture the following addresses for each type: @@ -79,6 +91,7 @@ typedef enum } HOMER_Version_t; /** PNOR information contained within the HOMER data. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t pnorOffset; /** Physical offset of FIRDATA in PNOR */ @@ -90,25 +103,26 @@ typedef struct __attribute__((packed)) /** HOMER data header information containing hardware configurations and * register counts. */ +/* NOTE: This structure may, or may not, be 4-byte word aligned. It all depends + * on the size of regCounts, which will change based on the number of + * target types and register types we support. When reading/writing this + * data ensure that proper padding has been added after this structure so + * that subsequent structures are 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t header; /** Magic number to indicate valid data and version */ - uint8_t chipCount; /** Number of configured chips per node */ + uint32_t chipCount : 8; /** Number of configured chips per node */ + uint32_t ecDepCounts : 8; /** Number of regs that are EC dependent */ + uint32_t iplState : 1; /** See IplState_t. */ + uint32_t reserved : 15; - uint8_t iplState : 1; /** See IplState_t. */ - uint8_t reserved : 7; + /** Information regarding the PNOR location and size. */ + HOMER_PnorInfo_t pnorInfo; /** Contains number of registers per type for each target type. */ uint8_t regCounts[TRGT_MAX][REG_MAX]; - /** Number of regs that are dependent on EC level **/ - /** (these registers follow the normal register list) **/ - uint8_t ecDepCounts; - - /** Information regarding the PNOR location and size. */ - HOMER_PnorInfo_t pnorInfo; - } HOMER_Data_t; /** @return An initialized HOMER_Data_t struct. */ @@ -133,20 +147,20 @@ typedef enum } HOMER_ChipType_t; /** Information for each configured chip. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t fsiBaseAddr; /** FSI base address for the chip. */ - uint16_t chipType : 4; /** Chip type (see HOMER_ChipType_t) */ - uint16_t chipPos : 6; /** Chip position relative to the node. */ - uint16_t reserved : 6; - - uint8_t chipEcLevel; /** EC level for this chip */ + uint32_t chipType : 4; /** Chip type (see HOMER_ChipType_t) */ + uint32_t chipPos : 6; /** Chip position relative to the node. */ + uint32_t chipEcLevel : 8; /** EC level for this chip */ + uint32_t reserved : 14; } HOMER_Chip_t; - /** Used for Registers that have EC level dependencies */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t chipType : 4; /** See HOMER_ChipType_t. */ @@ -160,7 +174,6 @@ typedef struct __attribute__((packed)) } HOMER_ChipSpecAddr_t; - /** @return An initialized HOMER_Chip_t struct. */ static inline HOMER_Chip_t HOMER_getChip( HOMER_ChipType_t i_type ) { @@ -175,6 +188,7 @@ static inline HOMER_Chip_t HOMER_getChip( HOMER_ChipType_t i_type ) /*----------------------------------------------------------------------------*/ /** Information specific to a P9 Nimbus processor chip. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t isMaster : 1; /** 1 if this is the master PROC, 0 otherwise */ @@ -188,10 +202,10 @@ typedef struct __attribute__((packed)) uint32_t mcsMask : 4; /** Mask of configured MCS units (0-3) */ uint32_t mcaMask : 8; /** Mask of configured MCA units (0-7) */ - uint16_t cappMask : 2; /** Mask of configured CAPP units (0-1) */ - uint16_t pecMask : 3; /** Mask of configured PEC units (0-2) */ - uint16_t phbMask : 6; /** Mask of configured PHB units (0-5) */ - uint16_t reserved : 5; + uint32_t cappMask : 2; /** Mask of configured CAPP units (0-1) */ + uint32_t pecMask : 3; /** Mask of configured PEC units (0-2) */ + uint32_t phbMask : 6; /** Mask of configured PHB units (0-5) */ + uint32_t reserved : 21; } HOMER_ChipNimbus_t; @@ -206,6 +220,7 @@ static inline HOMER_ChipNimbus_t HOMER_initChipNimbus() /*----------------------------------------------------------------------------*/ /** Information specific to a P9 Cumulus processor chip. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t isMaster : 1; /** 1 if this is the master PROC, 0 otherwise */ @@ -219,10 +234,10 @@ typedef struct __attribute__((packed)) uint32_t miMask : 4; /** Mask of configured MI units (0-3) */ uint32_t dmiMask : 8; /** Mask of configured DMI units (0-7) */ - uint16_t cappMask : 2; /** Mask of configured CAPP units (0-1) */ - uint16_t pecMask : 3; /** Mask of configured PEC units (0-2) */ - uint16_t phbMask : 6; /** Mask of configured PHB units (0-5) */ - uint16_t reserved : 5; + uint32_t cappMask : 2; /** Mask of configured CAPP units (0-1) */ + uint32_t pecMask : 3; /** Mask of configured PEC units (0-2) */ + uint32_t phbMask : 6; /** Mask of configured PHB units (0-5) */ + uint32_t reserved : 21; } HOMER_ChipCumulus_t; @@ -237,10 +252,11 @@ static inline HOMER_ChipCumulus_t HOMER_initChipCumulus() /*----------------------------------------------------------------------------*/ /** Information specific to a Centaur memory buffer chip. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { - uint8_t mbaMask : 2; /** Mask of configured MBA units (0-1) */ - uint8_t reserved : 6; + uint32_t mbaMask : 2; /** Mask of configured MBA units (0-1) */ + uint32_t reserved : 30; } HOMER_ChipCentaur_t; @@ -252,23 +268,4 @@ static inline HOMER_ChipCentaur_t HOMER_initChipCentaur() return c; } -/** @brief Chip information inserted into HOMER data section after header - * - * There is basically an array of these after the initial HOMER - * section (HOMER_Data_t). The register info then follows. - */ -typedef struct __attribute__((packed)) -{ - HOMER_Chip_t hChipType; /* Nimbus, Centaur, EC Level, etc...*/ - - union - { - HOMER_ChipNimbus_t hChipN; - HOMER_ChipCumulus_t hChipC; - HOMER_ChipCentaur_t hChipM; - }; - -} HOMER_ChipInfo_t; - - #endif /* __homerData_common_h */ diff --git a/src/occ_405/firdata/pnorData_common.h b/src/occ_405/firdata/pnorData_common.h index faf14c0..3037e39 100644 --- a/src/occ_405/firdata/pnorData_common.h +++ b/src/occ_405/firdata/pnorData_common.h @@ -44,6 +44,13 @@ * - A list of all regular registers (PNOR_Reg_t). * - A list of all indirect-SCOM registers (PNOR_IdReg_t). * + * IMPORTANT NOTE: All of the structs used here are packed. Therefore, we must + * ensure the variables within the struct are byte aligned. Meaning each + * uint32_t within the struct must be 4-byte aligned and each uint16_t must + * be 2-byte aligned. This also means the structs must always start on a + * 4-bye word boundary to maintain alignment. This is required due to the + * limitations of the PPE42/SRAM hardware. + * * The PNOR has limited data space. So the following rules will apply: * - Any registers with the value of zero will not be captured. * - Registers with SCOM errors will not be captured, however, the number @@ -70,14 +77,15 @@ typedef enum } PNOR_Version_t; /** PNOR data header information. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t header; /** Magic number to indicate valid data and version */ - uint16_t trgts : 12; /** Number of targets with register data */ - uint16_t full : 1; /** 1 if PNOR data is full and data incomplete */ - uint16_t iplState : 1; /** See enum IplState_t */ - uint16_t reserved : 2; + uint32_t trgts : 12; /** Number of targets with register data */ + uint32_t full : 1; /** 1 if PNOR data is full and data incomplete */ + uint32_t iplState : 1; /** See enum IplState_t */ + uint32_t reserved : 18; } PNOR_Data_t; @@ -101,16 +109,17 @@ typedef enum } PNOR_Trgt_RegLimits_t; /** Information for each target with SCOM data. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { - uint32_t chipPos : 6; /** Parent chip position relative to the node */ - uint32_t unitPos : 5; /** Unit position relative to the parent chip */ - uint32_t regs : 9; /** Number of normal registers */ - uint32_t idRegs : 4; /** Number of indirect-SCOM registers */ - uint32_t scomErrs : 8; /** Number of SCOM errors detected */ + uint32_t chipPos : 6; /** Parent chip position relative to the node */ + uint32_t unitPos : 5; /** Unit position relative to the parent chip */ + uint32_t regs : 9; /** Number of normal registers */ + uint32_t idRegs : 4; /** Number of indirect-SCOM registers */ + uint32_t scomErrs : 8; /** Number of SCOM errors detected */ - uint8_t trgtType : 6; /** Target type. See enum TrgtType_t */ - uint8_t reserved : 2; + uint32_t trgtType : 6; /** Target type. See enum TrgtType_t */ + uint32_t reserved : 26; } PNOR_Trgt_t; @@ -132,6 +141,7 @@ static inline PNOR_Trgt_t PNOR_getTrgt( uint32_t i_trgtType, uint32_t i_chipPos, }; /** Information for a normal register. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint32_t addr; /** 32-bit address */ @@ -140,6 +150,7 @@ typedef struct __attribute__((packed)) } PNOR_Reg_t; /** Information for an indirect-SCOM register. */ +/* NOTE: This structure is 4-byte word aligned. */ typedef struct __attribute__((packed)) { uint64_t addr; /** 64-bit address */ |