Skip to content

Commit

Permalink
FIRDATA: fixed structure alignment in firdata code
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
zane131 authored and marthabroyles committed Jul 20, 2017
1 parent 7cdcf4d commit 237557e
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 61 deletions.
13 changes: 10 additions & 3 deletions src/occ_405/firdata/firData.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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 **/
Expand Down
91 changes: 44 additions & 47 deletions src/occ_405/firdata/homerData_common.h
Expand Up @@ -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:
Expand All @@ -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 */
Expand All @@ -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. */
Expand All @@ -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. */
Expand All @@ -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 )
{
Expand All @@ -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 */
Expand All @@ -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;

Expand All @@ -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 */
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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 */
33 changes: 22 additions & 11 deletions src/occ_405/firdata/pnorData_common.h
Expand Up @@ -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
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -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 */
Expand All @@ -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 */
Expand Down

0 comments on commit 237557e

Please sign in to comment.