diff options
author | Prachi Gupta <pragupta@us.ibm.com> | 2017-07-14 08:15:16 -0500 |
---|---|---|
committer | William A. Bryan <wilbryan@us.ibm.com> | 2017-07-21 16:26:20 -0400 |
commit | f301809e56b82fe61260a15f437183976db9ef75 (patch) | |
tree | daf1faba0c01d7e0c6ca818b05dddfcc987047d0 /src/occ_405 | |
parent | fda31eb85acb9aa8dee9741848ad9740f54e2f63 (diff) | |
download | talos-occ-f301809e56b82fe61260a15f437183976db9ef75.tar.gz talos-occ-f301809e56b82fe61260a15f437183976db9ef75.zip |
rt_xstop_analysis: move firdata code from occ_405 to occ_gpe0
Change-Id: Idaafd3bd9d40cfce4afd7b5d3308cd376f443967
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/43242
Reviewed-by: Zane C. Shelley <zshelle@us.ibm.com>
Reviewed-by: ILYA SMIRNOV <ismirno@us.ibm.com>
Reviewed-by: Brian J. Stegmiller <bjs@us.ibm.com>
Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Tested-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/occ_405')
30 files changed, 0 insertions, 6667 deletions
diff --git a/src/occ_405/firdata/ast_mboxdd.c b/src/occ_405/firdata/ast_mboxdd.c deleted file mode 100644 index 064bcca..0000000 --- a/src/occ_405/firdata/ast_mboxdd.c +++ /dev/null @@ -1,326 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/ast_mboxdd.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -/** - * @file ast_mboxdd.C - * - * @brief Implementation of the PNOR Accesser using the AST MBOX protocol - */ - -/*****************************************************************************/ -// I n c l u d e s -/*****************************************************************************/ -#include <native.h> -#include <norflash.h> -#include <ast_mboxdd.h> -#include <lpc.h> - -errorHndl_t writeRegSIO(uint8_t i_regAddr, uint8_t i_data) -{ - errorHndl_t l_err = NO_ERROR; - - do { - size_t reg_size = sizeof(uint8_t); - - /* Write out the register address */ - l_err = lpc_write( LPC_TRANS_IO, SIO_ADDR_REG_2E, - &i_regAddr, - reg_size ); - if( l_err ) { break; } - - /* Write out the register data */ - l_err = lpc_write( LPC_TRANS_IO, SIO_DATA_REG_2F, - &i_data, - reg_size ); - if( l_err ) { break; } - - } while(0); - - return l_err; -} - -errorHndl_t readRegSIO(uint8_t i_regAddr, uint8_t* o_data) -{ - errorHndl_t l_err = NO_ERROR; - - do { - size_t reg_size = sizeof(uint8_t); - - /* Write out the register address */ - l_err = lpc_write( LPC_TRANS_IO, SIO_ADDR_REG_2E, - &i_regAddr, - reg_size ); - if( l_err ) { break; } - - /* Read in the register data */ - l_err = lpc_read( LPC_TRANS_IO, SIO_DATA_REG_2F, - o_data, - reg_size ); - if( l_err ) { break; } - - } while(0); - - return l_err; -} - -errorHndl_t mboxOut(uint64_t i_addr, uint8_t i_byte) -{ - size_t len = sizeof(i_byte); - - return lpc_write( LPC_TRANS_IO, - i_addr + MBOX_IO_BASE, - &i_byte, - len ); -} - -errorHndl_t mboxIn(uint64_t i_addr, uint8_t *o_byte) -{ - size_t len = sizeof(uint8_t); - - return lpc_read( LPC_TRANS_IO, - i_addr + MBOX_IO_BASE, - o_byte, - len ); -} - -errorHndl_t doMessage( astMbox_t *io_mbox, mboxMessage_t *io_msg ) -{ - uint8_t* l_data = (uint8_t*)io_msg; - errorHndl_t l_err = NO_ERROR; - uint8_t l_stat1; - uint32_t l_loops = 0; - bool l_prot_error = false; - int i; - - io_msg->iv_seq = io_mbox->iv_mboxMsgSeq++; - - do - { - /* Write message out */ - for (i = 0; i < BMC_MBOX_DATA_REGS && !l_err; i++) - { - l_err = mboxOut(i, l_data[i]); - } - - if ( l_err ) - { - break; - } - - /* Clear status1 response bit as it was just set via reg write*/ - l_err = mboxOut(MBOX_STATUS_1, MBOX_STATUS1_RESP); - - if ( l_err ) - { - break; - } - - /* Ping BMC */ - l_err = mboxOut(MBOX_HOST_CTRL, MBOX_CTRL_INT_SEND); - - if ( l_err ) - { - break; - } - - /* Wait for response */ - while ( l_loops++ < MBOX_MAX_RESP_WAIT_US && !l_err ) - { - l_err = mboxIn(MBOX_STATUS_1, &l_stat1); - - if ( l_err ) - { - TRAC_ERR("doMessage error from MBOX_STATUS_1"); - break; - } - - if ( l_stat1 & MBOX_STATUS1_RESP ) - { - break; - } - sleep(1000); - } - - if ( l_err ) - { - TRAC_ERR( "Got error waiting for response !"); - break; - } - - if ( !(l_stat1 & MBOX_STATUS1_RESP) ) - { - TRAC_ERR( "Timeout waiting for response !"); - - // Don't try to interrupt the BMC anymore - l_err = mboxOut(MBOX_HOST_CTRL, 0); - if ( l_err) - { - //Note the command failed - TRAC_ERR( "Error communicating with MBOX daemon"); - TRAC_ERR( "Mbox status 1 reg: %x", l_stat1); - } - - // Tell the code below that we generated the error - // (not an LPC error) - l_prot_error = true; - break; - } - - /* Clear status */ - l_err = mboxOut(MBOX_STATUS_1, MBOX_STATUS1_RESP); - if (l_err) - { - TRAC_ERR( "Got error clearing status"); - break; - } - - // Remember some message fields before they get overwritten - // by the response - uint8_t old_seq = io_msg->iv_seq; - - // Read response - for (i = 0; i < BMC_MBOX_DATA_REGS && !l_err; i++) - { - l_err = mboxIn(i, &l_data[i]); - } - - if ( l_err ) - { - TRAC_ERR( "Got error reading response !"); - break; - } - - if (old_seq != io_msg->iv_seq) - { - TRAC_ERR( "bad sequence number in mbox message, got %d want %d", - io_msg->iv_seq, old_seq); - l_err = -1; - break; - } - - if (io_msg->iv_resp != MBOX_R_SUCCESS) - { - TRAC_ERR( "BMC mbox command failed with err %d", - io_msg->iv_resp); - l_err = -1; - // Tell code below that we generated the error (not an LPC error) - l_prot_error = true; - break; - } - - } - while(0); - - // If we got an LPC error, commit it and generate our own - if ( l_err && !l_prot_error ) - { - l_err = -1; - } - - return l_err; -} - -errorHndl_t initializeMbox(void) -{ - errorHndl_t l_errl = NO_ERROR; - - do - { - size_t reg_size = sizeof(uint8_t); - - //First need to unlock SIO registers - /* Send SuperIO password - send A5 twice to offset 0x2E */ - uint8_t data = SIO_PASSWORD_REG; - l_errl = lpc_write( LPC_TRANS_IO, SIO_ADDR_REG_2E, - &data, reg_size ); - if( l_errl ) { break; } - - l_errl = lpc_write( LPC_TRANS_IO, SIO_ADDR_REG_2E, - &data, reg_size ); - if( l_errl ) { break; } - - //Second need to select Mailbox SIO Device - // Register 0x07 is device select reg - // Device 0x0E is the sio mailbox device - l_errl = writeRegSIO( SIO_DEVICE_SELECT_REG, SIO_MB ); - if( l_errl ) { break; } - - //First disable SIO Mailbox engine to configure it - // 0x30 - Enable/Disable Reg - // 0x00 - Disable Device (previously selected mailbox device) - l_errl = writeRegSIO( 0x30, 0x00 ); - - if (l_errl) - { - break; - } - - // Set MBOX Base Address - //Regs 0x60/0x61 are a BAR-like reg to configure the MBOX base address - l_errl = writeRegSIO( 0x60, (MBOX_IO_BASE >> 8) & 0xFF ); - - if (l_errl) - { - break; - } - - // Set other half of MBOX Base Address - l_errl = writeRegSIO( 0x61, MBOX_IO_BASE & 0xFF ); - - if (l_errl) - { - break; - } - - //Configure MBOX IRQs - //Regs 0x70 / 0x71 control that - l_errl = writeRegSIO( 0x70, MBOX_LPC_IRQ ); - - if (l_errl) - { - break; - } - - //Other half of MBOX IRQ Configuration - // 1 == Low level trigger - l_errl = writeRegSIO( 0x71, 1 ); - - if (l_errl) - { - break; - } - - //Re-enable Device now that base addr and IRQs are configured - // 1 == Enable Device - l_errl = writeRegSIO( 0x30, 0x01 ); - - if (l_errl) - { - break; - } - } - while(0); - - return l_errl; -} diff --git a/src/occ_405/firdata/ast_mboxdd.h b/src/occ_405/firdata/ast_mboxdd.h deleted file mode 100644 index 64ea40a..0000000 --- a/src/occ_405/firdata/ast_mboxdd.h +++ /dev/null @@ -1,292 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/ast_mboxdd.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __AST_MBOXDD_H -#define __AST_MBOXDD_H - -/** @file ast_mboxdd.H - * @brief Provides the interfaces Aspeed MBOX hardware - */ - -/** - * @brief Provides the interface to exchange Mbox - * messages with the BMC. - */ - -enum -{ - BMC_MBOX_DATA_REGS = 14, - BMC_MBOX_ARGS_REGS = 11, - - /* Commands */ - MBOX_C_RESET_STATE = 0x01, - MBOX_C_GET_MBOX_INFO = 0x02, - MBOX_C_GET_FLASH_INFO = 0x03, - MBOX_C_CREATE_READ_WINDOW = 0x04, - MBOX_C_CLOSE_WINDOW = 0x05, - MBOX_C_CREATE_WRITE_WINDOW = 0x06, - MBOX_C_MARK_WRITE_DIRTY = 0x07, - MBOX_C_WRITE_FLUSH = 0x08, - MBOX_C_BMC_EVENT_ACK = 0x09, - MBOX_C_MARK_WRITE_ERASED = 0x0a, - - /* Responses */ - MBOX_R_SUCCESS = 0x01, - MBOX_R_PARAM_ERROR = 0x02, - MBOX_R_WRITE_ERROR = 0x03, - MBOX_R_SYSTEM_ERROR = 0x04, - MBOX_R_TIMEOUT = 0x05, - MBOX_R_BUSY = 0x06, - MBOX_R_WINDOW_ERROR = 0x07, - -}; - -enum{ - SIO_DEVICE_SELECT_REG = 0x07, /**< Regsiter to select SIO device */ - SIO_ADDR_REG_2E = 0x2E, /**< SuperIO address register */ - SIO_DATA_REG_2F = 0x2F, /**< SuperIO data register */ - SIO_PASSWORD_REG = 0xA5, /**< SuperIO password register (to be unlocked to access SIO) */ - SIO_MB = 0x0E, /**< SIO device: Mailbox */ - SIO_ENABLE_DEVICE = 0x01, /**< Enable SIO device by writing 1 to reg 30 of device */ - SIO_DISABLE_DEVICE = 0x00, /**< Disable SIO device by writing 0 to reg 30 of device */ -}; - - -typedef struct -{ - uint8_t iv_cmd; - uint8_t iv_seq; - uint8_t iv_args[BMC_MBOX_ARGS_REGS]; - uint8_t iv_resp; - -} mboxMessage_t; - -/** - * @brief Write a single byte into an SIO register - * - * @param[in] i_reg: Register to write - * @param[in] i_data: Data to write - * - * @return Error from operation - */ -errorHndl_t writeRegSIO(uint8_t i_regAddr, - uint8_t i_data ); - -/** - * @brief Read a single byte from an SIO register - * - * @param[in] i_reg: Register to read - * @param[in] o_data: Data that was read - * - * @return Error from operation - */ -errorHndl_t readRegSIO(uint8_t i_regAddr, - uint8_t* o_data ); - - -//Helper functions to create mbox messages to send to the BMC - -/** - * @brief 8-bit read accessor of the args section - * - * @param[in] i_msg: mboxMessage_t pointer to access args section - * @param[in] i_index: Index into args section to be read from - * - * @return data requested - */ -static inline uint8_t get8( mboxMessage_t *i_msg, uint8_t i_index) -{ - if ( i_index >= BMC_MBOX_ARGS_REGS ) - { - return 0; - } - - return i_msg->iv_args[i_index]; -} - -/** - * @brief 8-bit write accessor of the args section - * - * @param[in] i_msg: mboxMessage_t pointer to access args section - * @param[in] i_index: Index into args section to be written to - * @param[in] i_value: data to be written - */ -static inline void put8(mboxMessage_t *i_msg, uint8_t i_index, uint8_t i_value) -{ - if ( i_index >= BMC_MBOX_ARGS_REGS ) - { - return; - } - - i_msg->iv_args[i_index] = i_value; -} - -/** - * @brief 16-bit read accessor of the args section - * @param[in] i_msg: mboxMessage_t pointer to access args section - * @param[in] i_index: Index into args section to be read from - * - * @return data requested - */ -static inline uint16_t get16( mboxMessage_t *i_msg, uint8_t i_index ) -{ - if ( i_index >= (BMC_MBOX_ARGS_REGS-1) ) - { - return 0; - } - - return i_msg->iv_args[i_index] | (i_msg->iv_args[i_index + 1] << 8); -} - -/** - * @brief 16-bit write accessor of the args section - * - * @param[in] i_msg: mboxMessage_t pointer to access args section - * @param[in] i_index: Index into args section to be written to - * @param[in] i_value: data to be written - */ -static inline void put16(mboxMessage_t *i_msg, - uint8_t i_index, - uint16_t i_value) -{ - if ( i_index >= (BMC_MBOX_ARGS_REGS-1) ) - { - return; - } - - i_msg->iv_args[i_index] = i_value & 0xff; - i_msg->iv_args[i_index + 1] = i_value >> 8; -} - -/** - * @brief 32-bit read accessor of the args section - * - * @param[in] i_msg: mboxMessage_t pointer to access args section - * @param[in] i_index: Index into args section to be read from - * - * @return data requested - */ -static inline uint32_t get32( mboxMessage_t *i_msg, uint8_t i_index ) -{ - if ( i_index >= (BMC_MBOX_ARGS_REGS-3) ) - { - return 0; - } - - return i_msg->iv_args[i_index] | - (i_msg->iv_args[i_index + 1] << 8) | - (i_msg->iv_args[i_index + 2] << 16) | - (i_msg->iv_args[i_index + 3] << 24); -} - -/** - * @brief 32-bit write accessor of the args section - * - * @param[in] i_msg: mboxMessage_t pointer to access args section - * @param[in] i_index: Index into args section to be read from - */ -static inline void put32(mboxMessage_t *i_msg, - uint8_t i_index, - uint32_t i_value) -{ - if ( i_index >= (BMC_MBOX_ARGS_REGS-3) ) - { - return; - } - - i_msg->iv_args[i_index] = i_value & 0xff; - i_msg->iv_args[i_index + 1] = (i_value >> 8) & 0xff; - i_msg->iv_args[i_index + 2] = (i_value >> 16) & 0xff; - i_msg->iv_args[i_index + 3 ] = i_value >> 24; -} - -typedef struct { - - uint8_t iv_mboxMsgSeq; - mboxMessage_t iv_msg; - -} astMbox_t; - -/** - * @brief Send a message and receive the response - * - * @parm[in/out] io_mbox Mbox pointer to send message - * @parm[in/out] io_msg Message to send, contains the response on exit - * - * @return Error from operation - */ -errorHndl_t doMessage( astMbox_t *io_mbox, mboxMessage_t *io_msg ); - -enum -{ - MBOX_FLAG_REG = 0x0f, - MBOX_STATUS_0 = 0x10, - MBOX_STATUS_1 = 0x11, - MBOX_STATUS1_ATTN = 0x80, - MBOX_STATUS1_RESP = 0x20, - MBOX_BMC_CTRL = 0x12, - MBOX_CTRL_INT_STATUS = 0x80, - MBOX_CTRL_INT_MASK = 0x02, - MBOX_CTRL_INT_SEND = 0x01, - MBOX_HOST_CTRL = 0x13, - MBOX_BMC_INT_EN_0 = 0x14, - MBOX_BMC_INT_EN_1 = 0x15, - MBOX_HOST_INT_EN_0 = 0x16, - MBOX_HOST_INT_EN_1 = 0x17, - - MBOX_IO_BASE = 0x1000, - MBOX_LPC_IRQ = 0x9, - - MBOX_MAX_RESP_WAIT_US = 10000000, /* 10s timeout */ -}; - -/** - * @brief Initialize/Enable the MBox in the SIO - * - * @return Error from operation - */ -errorHndl_t initializeMbox( void ); - -/** - * @brief Write a byte to the mBox - * - * @parm[in] i_addr: Register offset in the mbox - * @parm[in] i_byte: Byte to write - * - * @return Error from operation -*/ -errorHndl_t mboxOut( uint64_t i_addr, uint8_t i_byte ); - -/** - * @brief Read a byte from the mBox - * - * @parm[in] i_addr: Register offset in the mbox - * @parm[out] o_byte: Byte read - * - * @return Error from operation - */ -errorHndl_t mboxIn( uint64_t i_addr, uint8_t *o_byte ); - -#endif /* __AST_MBOXDD_H */ diff --git a/src/occ_405/firdata/ecc.c b/src/occ_405/firdata/ecc.c deleted file mode 100644 index 6696678..0000000 --- a/src/occ_405/firdata/ecc.c +++ /dev/null @@ -1,272 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/ecc.C $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/*#include <stdio.h> */ -#include <endian.h> -#include <assert.h> - -#include <native.h> -#include <ecc.h> - -/** Matrix used for ECC calculation. - * - * Each row of this is the set of data word bits that are used for - * the calculation of the corresponding ECC bit. The parity of the - * bitset is the value of the ECC bit. - * - * ie. ECC[n] = eccMatrix[n] & data - * - * Note: To make the math easier (and less shifts in resulting code), - * row0 = ECC7. HW numbering is MSB, order here is LSB. - * - * These values come from the HW design of the ECC algorithm. - */ -static uint64_t eccMatrix[] = { - /*0000000000000000111010000100001000111100000011111001100111111111 */ - 0x0000e8423c0f99ff, - /*0000000011101000010000100011110000001111100110011111111100000000 */ - 0x00e8423c0f99ff00, - /*1110100001000010001111000000111110011001111111110000000000000000 */ - 0xe8423c0f99ff0000, - /*0100001000111100000011111001100111111111000000000000000011101000 */ - 0x423c0f99ff0000e8, - /*0011110000001111100110011111111100000000000000001110100001000010 */ - 0x3c0f99ff0000e842, - /*0000111110011001111111110000000000000000111010000100001000111100 */ - 0x0f99ff0000e8423c, - /*1001100111111111000000000000000011101000010000100011110000001111 */ - 0x99ff0000e8423c0f, - /*1111111100000000000000001110100001000010001111000000111110011001 */ - 0xff0000e8423c0f99 -}; - -/** Syndrome calculation matrix. - * - * Maps syndrome to flipped bit. - * - * To perform ECC correction, this matrix is a look-up of the bit - * that is bad based on the binary difference of the good and bad - * ECC. This difference is called the "syndrome". - * - * When a particular bit is on in the data, it cause a column from - * eccMatrix being XOR'd into the ECC field. This column is the - * "effect" of each bit. If a bit is flipped in the data then its - * "effect" is missing from the ECC. You can calculate ECC on unknown - * quality data and compare the ECC field between the calculated - * value and the stored value. If the difference is zero, then the - * data is clean. If the difference is non-zero, you look up the - * difference in the syndrome table to identify the "effect" that - * is missing, which is the bit that is flipped. - * - * Notice that ECC bit flips are recorded by a single "effect" - * bit (ie. 0x1, 0x2, 0x4, 0x8 ...) and double bit flips are identified - * by the UE status in the table. - * - * Bits are in MSB order. - */ -static uint8_t syndromeMatrix[] = { - ECC_GD, ECC_E7, ECC_E6, ECC_UE, ECC_E5, ECC_UE, ECC_UE, 47, - ECC_E4, ECC_UE, ECC_UE, 37, ECC_UE, 35, 39, ECC_UE, - ECC_E3, ECC_UE, ECC_UE, 48, ECC_UE, 30, 29, ECC_UE, - ECC_UE, 57, 27, ECC_UE, 31, ECC_UE, ECC_UE, ECC_UE, - ECC_E2, ECC_UE, ECC_UE, 17, ECC_UE, 18, 40, ECC_UE, - ECC_UE, 58, 22, ECC_UE, 21, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, 16, 49, ECC_UE, 19, ECC_UE, ECC_UE, ECC_UE, - 23, ECC_UE, ECC_UE, ECC_UE, ECC_UE, 20, ECC_UE, ECC_UE, - ECC_E1, ECC_UE, ECC_UE, 51, ECC_UE, 46, 9, ECC_UE, - ECC_UE, 34, 10, ECC_UE, 32, ECC_UE, ECC_UE, 36, - ECC_UE, 62, 50, ECC_UE, 14, ECC_UE, ECC_UE, ECC_UE, - 13, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, 61, 8, ECC_UE, 41, ECC_UE, ECC_UE, ECC_UE, - 11, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - 15, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, ECC_UE, 12, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_E0, ECC_UE, ECC_UE, 55, ECC_UE, 45, 43, ECC_UE, - ECC_UE, 56, 38, ECC_UE, 1, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, 25, 26, ECC_UE, 2, ECC_UE, ECC_UE, ECC_UE, - 24, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, 28, ECC_UE, - ECC_UE, 59, 54, ECC_UE, 42, ECC_UE, ECC_UE, 44, - 6, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - 5, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, 63, 53, ECC_UE, 0, ECC_UE, ECC_UE, ECC_UE, - 33, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - 3, ECC_UE, ECC_UE, 52, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - 7, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, 60, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, ECC_UE, ECC_UE, ECC_UE, 4, ECC_UE, ECC_UE, ECC_UE, - ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, ECC_UE, -}; - -/** Returns the parity of x, i.e. the number of 1-bits in x modulo 2. - * Replacement for __builtin_parityl - */ -uint8_t parity_check( uint64_t i_data ) -{ - int ones = 0; - size_t x; - for( x=0; x<(sizeof(i_data)*8); x++ ) - { - if( i_data & (0x8000000000000000ull >> x) ) - { - ones++; - } - } - return ones%2; -} - -/** Create the ECC field corresponding to a 8-byte data field - * - * @param[in] i_data - The 8 byte data to generate ECC for. - * @return The 1 byte ECC corresponding to the data. - */ -uint8_t generateECC(uint64_t i_data) -{ - uint8_t result = 0; - - int i = 0; - for (i = 0; i < 8; i++) - { - result |= (parity_check(eccMatrix[i] & i_data) << i); - } - - return result; -} - -/** Verify the data and ECC match or indicate how they are wrong. - * - * @param[in] i_data - The data to check ECC on. - * @param[in] i_ecc - The [supposed] ECC for the data. - * - * @return eccBitfield or 0-64. - * - * @retval GD - Indicates the data is good (matches ECC). - * @retval UE - Indicates the data is uncorrectable. - * @retval all others - Indication of which bit is incorrect. - */ -uint8_t verifyECC(uint64_t i_data, uint8_t i_ecc) -{ - return syndromeMatrix[generateECC(i_data) ^ i_ecc]; -} - -/** Correct the data and/or ECC. - * - * @param[in,out] io_data - Data to check / correct. - * @param[in,out] io_ecc - ECC to check / correct. - * - * @return eccBitfield or 0-64. - * - * @retval GD - Data is good. - * @retval UE - Data is uncorrectable. - * @retval all others - which bit was corrected. - */ -uint8_t correctECC(uint64_t* io_data, uint8_t* io_ecc) -{ - uint8_t badBit = verifyECC(*io_data, *io_ecc); - - if ((badBit != ECC_GD) && (badBit != ECC_UE)) /* Good is done, UE is hopeless. */ - { - /* Determine if the ECC or data part is bad, do bit flip. */ - if (badBit >= ECC_E7) - { - *io_ecc ^= (1 << (badBit - ECC_E7)); - } - else - { - *io_data ^= (1ul << (63 - badBit)); - } - } - return badBit; -} - -void injectECC(const uint8_t* i_src, - size_t i_srcSz, - uint8_t* o_dst) -{ - assert(0 == (i_srcSz % sizeof(uint64_t))); - - size_t i = 0; - size_t o = 0; - for(i = 0, o = 0; - i < i_srcSz; - i += sizeof(uint64_t), o += sizeof(uint64_t) + sizeof(uint8_t)) - { - /* Read data word, copy to destination. */ - uint64_t data = *((const uint64_t*)(&i_src[i])); - *((uint64_t*)(&o_dst[o])) = data; - data = be64toh(data); - - /* Calculate ECC, copy to destination. */ - uint8_t ecc = generateECC(data); - o_dst[o + sizeof(uint64_t)] = ecc; - } -} - -eccStatus removeECC(uint8_t* io_src, - uint8_t* o_dst, size_t i_dstSz) -{ - assert(0 == (i_dstSz % sizeof(uint64_t))); - - eccStatus rc = ECC_CLEAN; - - size_t i = 0, o = 0; - for(i = 0, o = 0; - o < i_dstSz; - i += sizeof(uint64_t) + sizeof(uint8_t), o += sizeof(uint64_t)) - { - /* Read data and ECC parts. */ - uint64_t data = *((uint64_t*)(&io_src[i])); - data = be64toh(data); - uint8_t ecc = io_src[i + sizeof(uint64_t)]; - - /* Calculate failing bit and fix data. */ - uint8_t badBit = correctECC(&data, &ecc); - - /* Return data to big endian. */ - data = htobe64(data); - - /* Perform correction and status update. */ - if (badBit == ECC_UE) - { - rc = ECC_UNCORRECTABLE; - } - else if (badBit != ECC_GD) - { - if (rc != ECC_UNCORRECTABLE) - { - rc = ECC_CORRECTED; - } - *((uint64_t*)(&io_src[i])) = data; - io_src[i + sizeof(uint64_t)] = ecc; - } - - /* Copy fixed data to destination buffer. */ - *((uint64_t*)(&o_dst[o])) = data; - } - - return rc; -} - diff --git a/src/occ_405/firdata/ecc.h b/src/occ_405/firdata/ecc.h deleted file mode 100644 index 12ffe4e..0000000 --- a/src/occ_405/firdata/ecc.h +++ /dev/null @@ -1,76 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/ecc.H $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#ifndef __PNOR_ECC_H -#define __PNOR_ECC_H - -#include <native.h> - -/** @file ecc.H - * @brief Interfaces for the P8 8-byte ECC algorithm. - */ - -/** Status for the ECC removal function. */ -typedef uint8_t eccStatus; -#define ECC_CLEAN 0x00 /*< No ECC Error was detected. */ -#define ECC_CORRECTED 0x01 /*< ECC error detected and corrected. */ -#define ECC_UNCORRECTABLE 0x02 /*< ECC error detected and uncorrectable. */ - -/** Bit field identifiers for syndrome calculations. */ -typedef uint8_t eccBitfields; -#define ECC_GD 0xff /*< Good ECC matches. */ -#define ECC_UE 0xfe /*< Uncorrectable. */ -#define ECC_E0 71 /*< Error in ECC bit 0 */ -#define ECC_E1 70 /*< Error in ECC bit 1 */ -#define ECC_E2 69 /*< Error in ECC bit 2 */ -#define ECC_E3 68 /*< Error in ECC bit 3 */ -#define ECC_E4 67 /*< Error in ECC bit 4 */ -#define ECC_E5 66 /*< Error in ECC bit 5 */ -#define ECC_E6 65 /*< Error in ECC bit 6 */ -#define ECC_E7 64 /*< Error in ECC bit 7 */ - -/** Inject ECC into a data stream. - * - * @param[in] i_src - Source data to create ECC on. - * @param[in] i_srcSz - Size in bytes of source data. - * @param[out] o_dst - Destination buffer of data+ECC. - * - * @note i_srcSz must be a multiple of 8 bytes. - */ -void injectECC(const uint8_t* i_src, size_t i_srcSz, - uint8_t* o_dst); - -/** Remove ECC from a data stream. - * - * @param[in,out] io_src - Source data+ECC stream. - * @param[out] o_dst - Destination buffer for data only. - * @param[in] i_dstSz - Size in bytes of destination ((srcSz / 9) * 8). - * - * @note i_dstSz must be a multiple of 8 bytes. - */ -eccStatus removeECC(uint8_t* io_src, - uint8_t* o_dst, size_t i_dstSz); - - -#endif diff --git a/src/occ_405/firdata/firData.c b/src/occ_405/firdata/firData.c deleted file mode 100644 index 299f92b..0000000 --- a/src/occ_405/firdata/firData.c +++ /dev/null @@ -1,1389 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/firData.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#include <native.h> - -#include <homerData_common.h> -#include <pnorData_common.h> -#include <pnor_util.h> -#include <scom_trgt.h> -#include <scom_util.h> - -/** Keeps track of pointers to register lists in the HOMER data for each target - * type. */ -typedef struct -{ - uint32_t * glbl; /*/< Global registers */ - uint32_t * fir; /*/< Normal FIRs */ - uint32_t * reg; /*/< Normal registers */ - uint64_t * idFir; /*/< Indirect-SCOM FIRs */ - uint64_t * idReg; /*/< Indirect-SCOM registers */ -} FirData_ListPointers_t; - -/** Contains pointers and sizes for the HOMER and PNOR data buffers. */ -typedef struct -{ - uint8_t * hBuf; /*/< Pointer to the HOMER data buffer */ - uint32_t maxHBufSize; /*/< Maximum size of the HOMER data buffer */ - HOMER_Data_t * hData; /*/< Pointer to the HOMER header data */ - - uint8_t * pBuf; /*/< Pointer to the PNOR data buffer */ - uint32_t maxPBufSize; /*/< Maximum size of the PNOR data buffer */ - PNOR_Data_t * pData; /*/< Pointer to the PNOR header data */ - uint32_t pBufSize; /*/< Current size of the PNOR data buffer */ - - FirData_ListPointers_t hPtrs[TRGT_MAX]; /*/< Pointers to the reg lists */ - - HOMER_ChipSpecAddr_t * ecDepReg; /*/< EC dependent regs */ - -} FirData_t; - - -/** We move the chiplet exist bit fields into this structure left */ -/** justified for easy checking of the fields with a mask */ -typedef struct -{ - uint32_t xbusMask; - uint32_t obusMask; - uint32_t ecMask; - - uint32_t eqMask; - uint32_t exMask; - uint32_t mcbist_mc_Mask; - uint32_t mcs_mi_Mask; - uint32_t mca_dmi_Mask; - - uint32_t cappMask; - uint32_t pecMask; - uint32_t phbMask; - -} FirData_existBits_t; - -/* Uncomment for additional debug traces */ -#if 0 -#define DEBUG_PRD_CHKSTOP_ANALYSIS -#endif - -/*------------------------------------------------------------------------------ */ - -/** @brief Add generic data to the PNOR buffer. - * @param io_fd The FIR data stuct. - * @param i_data Pointer to the data to add to the buffer. - * @param i_dataSize Size of the data to add to the buffer. - * @return True, if where is no room to add the new data. False, otherwise. - */ -bool FirData_addDataToPnor( FirData_t * io_fd, void * i_data, - uint32_t i_dataSize ) -{ - bool full = (io_fd->maxPBufSize < io_fd->pBufSize + i_dataSize); - - if ( full ) - { - /* Indicate the PNOR data is full. */ - io_fd->pData->full = 1; - } - else - { - /* Copy data to PNOR buffer. */ - memcpy( &io_fd->pBuf[io_fd->pBufSize], i_data, i_dataSize ); - io_fd->pBufSize += i_dataSize; - } - - return full; -} - -/*------------------------------------------------------------------------------ */ - -/** @brief SCOMs hardware and adds a normal register to PNOR. - * @param io_fd The FIR data stuct. - * @param io_pTrgt Pointer to PNOR target. - * @param i_sTrgt SCOM target. - * @param i_addr 32-bit address to SCOM. - * @param o_nonZero True if the value of the register was non-zero. False, - * otherwise. - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addRegToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, uint32_t i_addr, - bool * o_nonZero ) -{ - bool full = false; - - int32_t rc = 0; - PNOR_Reg_t reg = { i_addr, 0 }; - - *o_nonZero = false; - - do - { - rc = SCOM_getScom( i_sTrgt, i_addr, &(reg.val) ); - if ( SUCCESS != rc ) - { - TRAC_ERR( "[FirData_addRegToPnor] t=%d p=%d u=%d rc=%d " - "addr=0x%08x val=0x%08x%08x", i_sTrgt.type, - i_sTrgt.procPos, i_sTrgt.procUnitPos, rc, i_addr, - (uint32_t)(reg.val >> 32), (uint32_t)reg.val ); - - if ( io_pTrgt->scomErrs < PNOR_Trgt_MAX_SCOM_ERRORS ) - io_pTrgt->scomErrs++; - - break; - } - - if ( 0 == reg.val ) break; // Skip zero value registers. - - full = FirData_addDataToPnor( io_fd, ®, sizeof(reg) ); - if ( full ) break; - - *o_nonZero = true; - - if ( io_pTrgt->regs < PNOR_Trgt_MAX_REGS_PER_TRGT ) - io_pTrgt->regs++; - - } while (0); - -#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS - TRAC_INFO(" addToPnor: Type:%d Pos:%d Unit:%d Addr:%X Full:%d", - i_sTrgt.type, i_sTrgt.procPos, i_sTrgt.procUnitPos, - i_addr, full ); -#endif - - return full; -} - -/*------------------------------------------------------------------------------ */ - -/** @brief SCOMs hardware and add a indirect-SCOM register to PNOR. - * @param io_fd The FIR data stuct. - * @param io_pTrgt Pointer to PNOR target. - * @param i_sTrgt SCOM target. - * @param i_sTrgt Target to SCOM. - * @param i_addr 64-bit address to SCOM. - * @param o_nonZero True if the value of the register was non-zero. False, - * otherwise. - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addIdRegToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, uint64_t i_addr, - bool * o_nonZero ) -{ - bool full = false; - - int32_t rc = 0; - PNOR_IdReg_t reg = { i_addr, 0 }; - - *o_nonZero = false; - - do - { - rc = SCOM_getIdScom( i_sTrgt, i_addr, &(reg.val) ); - if ( SUCCESS != rc ) - { - if ( io_pTrgt->scomErrs < PNOR_Trgt_MAX_SCOM_ERRORS ) - io_pTrgt->scomErrs++; - break; - } - - if ( 0 == reg.val ) break; // Skip zero value registers. - - full = FirData_addDataToPnor( io_fd, ®, sizeof(reg) ); - if ( full ) break; - - *o_nonZero = true; - - if ( io_pTrgt->idRegs < PNOR_Trgt_MAX_ID_REGS_PER_TRGT ) - io_pTrgt->idRegs++; - - } while (0); - - return full; -} - -/*------------------------------------------------------------------------------ */ - -/** @brief Iterates a list of global registers and adds them to the PNOR. - * @param io_fd The FIR data stuct. - * @param io_pTrgt Pointer to PNOR target. - * @param i_sTrgt SCOM target. - * @param o_noAttn True, if the global registers showed no active attentions - * on the target. False, otherwise. - * @param i_chipStruct Provides chipType and ecLevel we need - * for EC dependent regs - * - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addGlblsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, bool * o_noAttn, - HOMER_Chip_t *i_chipStruct ) -{ - bool full = false; - bool l_isAnyGlobal = false; /* true when we find global reg */ - bool l_isAnyNonZero = false; /* true if ATTN is active on any reg */ - - uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->regCounts[t][REG_GLBL]; - - uint32_t i = 0; - - uint32_t addr = 0; - bool nonZero = false; - - *o_noAttn = false; /* Must be false if there are no global regs. */ - - if ( 0 != cnt ) - { - /** If we get here, we have GLOBALS for this target **/ - l_isAnyGlobal = true; - - for ( i = 0; i < cnt; i++ ) - { - addr = io_fd->hPtrs[t].glbl[i]; - nonZero = false; - - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, - &nonZero ); - if ( full ) break; - - if ( nonZero ) l_isAnyNonZero = true; - } - } - - - /** Handle EC dependent registers, if any */ - HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; - cnt = io_fd->hData->ecDepCounts; - - /** We have a structure with one element for each EC dep address. */ - /** Need to loop thru and verify we have same regType among */ - /** other things prior to using the address. */ - for ( i = 0; i < cnt; i++ ) - { -#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS - TRAC_INFO(" addGlblsToPnor In/Array: chipType:%X::%X trgType:%X::%X" - " regType:%X::%X ecLevel %X::%X", - i_chipStruct->chipType, l_ecAddrtPtr->chipType, - t, l_ecAddrtPtr->trgtType, - REG_GLBL, l_ecAddrtPtr->regType, - i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); -#endif - - /** Need same chipType (nimbus,cumulus,etc..), same target type, */ - /** same register type and EC level must match too */ - if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && - (l_ecAddrtPtr->trgtType == t ) && - (l_ecAddrtPtr->regType == REG_GLBL) && - (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) - ) - { - /** If we get here, we have GLOBALS for this target **/ - l_isAnyGlobal = true; - - /* address is right justified in 64 bits */ - addr = (uint32_t)(l_ecAddrtPtr->address); - nonZero = false; - - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, - &nonZero ); - if ( full ) break; - - if ( nonZero ) l_isAnyNonZero = true; - } /* end if we found an EC dep reg */ - - /* prep pointer for next element (if any) */ - l_ecAddrtPtr++; - - } /** end EC dependent reg loop */ - - /* If we have no GLOBALS, we want to collect other regs */ - /* so then we want to return 'attn is active)'. */ - /* If we have GLOBALS, then we need non-zero reg to */ - /* collect the rest of the regs (attn is active). */ - if ( (true == l_isAnyGlobal) && (false == l_isAnyNonZero) ) - { - /* This indicates we won't collect additional regs */ - *o_noAttn = true; /* starts out as false */ - } - - return full; -} - -/*------------------------------------------------------------------------------ */ - -/** @brief Iterates a list of FIRs and adds them to the PNOR. - * @param io_fd The FIR data stuct. - * @param io_pTrgt Pointer to PNOR target. - * @param i_sTrgt SCOM target. - * @param i_chipStruct Provides chipType and ecLevel we need - * for EC dependent regs - * - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, - HOMER_Chip_t *i_chipStruct ) -{ - bool full = false; - - uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->regCounts[t][REG_FIR]; - - uint32_t i = 0; - - uint32_t addr = 0; - bool nonZero = false; - bool tmp = false; /* ignored, not used */ - - for ( i = 0; i < cnt; i++ ) - { - addr = io_fd->hPtrs[t].fir[i]; - nonZero = false; - - /* Add FIR */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, &nonZero ); - if ( full ) break; - - /* Add MASK */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 3, &tmp ); - if ( full ) break; - - if ( nonZero ) - { - /* Add ACT0 */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 6, - &tmp ); - if ( full ) break; - - /* Add ACT1 */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 7, - &tmp ); - if ( full ) break; - } - } - - - /** Handle EC dependent registers, if any */ - HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; - cnt = io_fd->hData->ecDepCounts; - - /** We have a structure with one element for each EC dep address. */ - /** Need to loop thru and verify we have same regType among */ - /** other things prior to using the address. */ - for ( i = 0; i < cnt; i++ ) - { -#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS - TRAC_INFO(" addFirsToPnor In/Array: chipType:%X::%X trgType:%X::%X" - " regType:%X::%X ecLevel %X::%X", - i_chipStruct->chipType, l_ecAddrtPtr->chipType, - t, l_ecAddrtPtr->trgtType, - REG_GLBL, l_ecAddrtPtr->regType, - i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); -#endif - - /** Need same chipType (nimbus,cumulus,etc..), same target type, */ - /** same register type and EC level must match too */ - if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && - (l_ecAddrtPtr->trgtType == t ) && - (l_ecAddrtPtr->regType == REG_FIR) && - (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) - ) - { /* address is right justified in 64 bits */ - addr = (uint32_t)(l_ecAddrtPtr->address); - nonZero = false; - - /* Add FIR */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, &nonZero ); - if ( full ) break; - - /* Add MASK */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 3, &tmp ); - if ( full ) break; - - if ( nonZero ) - { - /* Add ACT0 */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 6, - &tmp ); - if ( full ) break; - - /* Add ACT1 */ - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr + 7, - &tmp ); - if ( full ) break; - } - - } /* end if we found an EC dep reg */ - - /* prep pointer for next element (if any) */ - l_ecAddrtPtr++; - - } /** end EC dependent reg loop */ - - - return full; -} - -/*------------------------------------------------------------------------------ */ - -/** @brief Iterates a list of REGs and adds them to the PNOR. - * @param io_fd The FIR data stuct. - * @param io_pTrgt Pointer to PNOR target. - * @param i_sTrgt SCOM target. - * @param i_chipStruct Provides chipType and ecLevel we need - * for EC dependent regs - * - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, - HOMER_Chip_t *i_chipStruct ) -{ - bool full = false; - - uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->regCounts[t][REG_REG]; - - uint32_t i = 0; - - uint32_t addr = 0; - bool tmp = false; /* ignored, not used */ - - for ( i = 0; i < cnt; i++ ) - { - addr = io_fd->hPtrs[t].reg[i]; - - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, &tmp ); - if ( full ) break; - } - - /** Handle EC dependent registers, if any */ - HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; - cnt = io_fd->hData->ecDepCounts; - - /** We have a structure with one element for each EC dep address. */ - /** Need to loop thru and verify we have same regType among */ - /** other things prior to using the address. */ - for ( i = 0; i < cnt; i++ ) - { -#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS - TRAC_INFO(" addRegsToPnor In/Array: chipType:%X::%X trgType:%X::%X" - " regType:%X::%X ecLevel %X::%X", - i_chipStruct->chipType, l_ecAddrtPtr->chipType, - t, l_ecAddrtPtr->trgtType, - REG_GLBL, l_ecAddrtPtr->regType, - i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); -#endif - - /** Need same chipType (nimbus,cumulus,etc..), same target type, */ - /** same register type and EC level must match too */ - if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && - (l_ecAddrtPtr->trgtType == t ) && - (l_ecAddrtPtr->regType == REG_REG) && - (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) - ) - { /* address is right justified in 64 bits */ - addr = (uint32_t)(l_ecAddrtPtr->address); - - full = FirData_addRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, - &tmp ); - if ( full ) break; - } /* end if we found an EC dep reg */ - - /* prep pointer for next element (if any) */ - l_ecAddrtPtr++; - - } /** end EC dependent reg loop */ - - return full; -} - -/*------------------------------------------------------------------------------ */ - -/** @brief Iterates a list of IDFIRs and adds them to the PNOR. - * @param io_fd The FIR data stuct. - * @param io_pTrgt Pointer to PNOR target. - * @param i_sTrgt SCOM target. - * @param i_chipStruct Provides chipType and ecLevel we need - * for EC dependent regs - * - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addIdFirsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, - HOMER_Chip_t *i_chipStruct ) -{ - bool full = false; - - uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->regCounts[t][REG_IDFIR]; - - uint32_t i = 0; - - uint64_t addr = 0; - bool nonZero = false; - bool tmp = false; /* ignored, not used */ - - for ( i = 0; i < cnt; i++ ) - { - addr = io_fd->hPtrs[t].idFir[i]; - nonZero = false; - - /* Add FIR */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, - &nonZero ); - if ( full ) break; - - /* Add MASK */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, - addr + 0x300000000ll, &tmp ); - if ( full ) break; - - if ( nonZero ) - { - /* Add ACT0 */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, - addr + 0x600000000ll, &tmp ); - if ( full ) break; - - /* Add ACT1 */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, - addr + 0x700000000ll, &tmp ); - if ( full ) break; - } - } - - - /** Handle EC dependent registers, if any */ - HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; - cnt = io_fd->hData->ecDepCounts; - - /** We have a structure with one element for each EC dep address. */ - /** Need to loop thru and verify we have same regType among */ - /** other things prior to using the address. */ - for ( i = 0; i < cnt; i++ ) - { -#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS - TRAC_INFO(" addIdFirsToPnor In/Array: chipType:%X::%X trgType:%X::%X" - " regType:%X::%X ecLevel %X::%X", - i_chipStruct->chipType, l_ecAddrtPtr->chipType, - t, l_ecAddrtPtr->trgtType, - REG_GLBL, l_ecAddrtPtr->regType, - i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); -#endif - - /** Need same chipType (nimbus,cumulus,etc..), same target type, */ - /** same register type and EC level must match too */ - if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && - (l_ecAddrtPtr->trgtType == t ) && - (l_ecAddrtPtr->regType == REG_IDFIR) && - (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) - ) - { /* need full 64 bit address here */ - addr = l_ecAddrtPtr->address; - nonZero = false; - - /* Add FIR */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, - &nonZero ); - if ( full ) break; - - /* Add MASK */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, - addr + 0x300000000ll, &tmp ); - if ( full ) break; - - if ( nonZero ) - { - /* Add ACT0 */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, - addr + 0x600000000ll, &tmp ); - if ( full ) break; - - /* Add ACT1 */ - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, - addr + 0x700000000ll, &tmp ); - if ( full ) break; - } - - } /* end if we found an EC dep reg */ - - /* prep pointer for next element (if any) */ - l_ecAddrtPtr++; - - } /** end EC dependent reg loop */ - - return full; -} - -/*------------------------------------------------------------------------------ */ - -/** @brief Iterates a list of IDREGs and adds them to the PNOR. - * @param io_fd The FIR data stuct. - * @param io_pTrgt Pointer to PNOR target. - * @param i_sTrgt SCOM target. - * @param i_chipStruct Provides chipType and ecLevel we need - * for EC dependent regs - * - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addIdRegsToPnor( FirData_t * io_fd, PNOR_Trgt_t * io_pTrgt, - SCOM_Trgt_t i_sTrgt, - HOMER_Chip_t *i_chipStruct ) -{ - bool full = false; - - uint8_t t = i_sTrgt.type; - uint8_t cnt = io_fd->hData->regCounts[t][REG_IDREG]; - - uint32_t i = 0; - - uint64_t addr = 0; - bool tmp = false; /* ignored, not used */ - - for ( i = 0; i < cnt; i++ ) - { - addr = io_fd->hPtrs[t].idReg[i]; - - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, &tmp ); - if ( full ) break; - } - - - /** Handle EC dependent registers, if any */ - HOMER_ChipSpecAddr_t *l_ecAddrtPtr = io_fd->ecDepReg; - cnt = io_fd->hData->ecDepCounts; - - /** We have a structure with one element for each EC dep address. */ - /** Need to loop thru and verify we have same regType among */ - /** other things prior to using the address. */ - for ( i = 0; i < cnt; i++ ) - { -#ifdef DEBUG_PRD_CHKSTOP_ANALYSIS - TRAC_INFO(" addIdRegsToPnor In/Array: chipType:%X::%X trgType:%X::%X" - " regType:%X::%X ecLevel %X::%X", - i_chipStruct->chipType, l_ecAddrtPtr->chipType, - t, l_ecAddrtPtr->trgtType, - REG_GLBL, l_ecAddrtPtr->regType, - i_chipStruct->chipEcLevel, l_ecAddrtPtr->ddLevel ); -#endif - - /** Need same chipType (nimbus,cumulus,etc..), same target type, */ - /** same register type and EC level must match too */ - if ( (l_ecAddrtPtr->chipType == i_chipStruct->chipType) && - (l_ecAddrtPtr->trgtType == t ) && - (l_ecAddrtPtr->regType == REG_IDREG) && - (l_ecAddrtPtr->ddLevel == i_chipStruct->chipEcLevel) - ) - { /* Using full 64 bit address here */ - addr = l_ecAddrtPtr->address; - - full = FirData_addIdRegToPnor( io_fd, io_pTrgt, i_sTrgt, addr, &tmp ); - if ( full ) break; - } /* end if we found an EC dep reg */ - - /* prep pointer for next element (if any) */ - l_ecAddrtPtr++; - - } /** end EC dependent reg loop */ - - - return full; -} - - -/*------------------------------------------------------------------------------ */ - -/** @brief Adds a target to the PNOR. - * @param io_fd The FIR data stuct. - * @param i_sTrgt SCOM Target. - * @param o_noAttn True, if the global registers showed no active - * attentions on the target. False, otherwise. - * @param i_chipStruct Provides chipType and ecLevel we need - * for EC dependent regs - * - * @return True if the PNOR buffer is full, false if there was room. - */ -bool FirData_addTrgtToPnor( FirData_t * io_fd, SCOM_Trgt_t i_sTrgt, - bool * o_noAttn, HOMER_Chip_t *i_chipStruct ) -{ - bool full = false; - - PNOR_Trgt_t * pTrgt = (PNOR_Trgt_t *)(&io_fd->pBuf[io_fd->pBufSize]); - - PNOR_Trgt_t tmp_pTrgt = PNOR_getTrgt( i_sTrgt.type, i_sTrgt.procPos, - i_sTrgt.procUnitPos ); - - *o_noAttn = false; /* Must be false if there are no global regs. */ - - TRAC_IMP( "FIRDATA: t=%d p=%d u=%d FSI=0x%08x isM=%c", i_sTrgt.type, - i_sTrgt.procPos, i_sTrgt.procUnitPos, i_sTrgt.fsiBaseAddr, - i_sTrgt.isMaster ? 'T' : 'F' ); - - do - { - /* Add the target info to PNOR. */ - full = FirData_addDataToPnor( io_fd, &tmp_pTrgt, sizeof(tmp_pTrgt) ); - if ( full ) break; - - /* Update the number of targets in the PNOR data. */ - io_fd->pData->trgts++; - - /* NOTE: Must add all regular registers (REG_GLBL, REG_FIR, REG_REG) - * before all indirect-SCOM registers. Also, must check REG_GLBL - * registers first to determine whether it is necessary to do the - * other registers. */ - - /* Add the GLBLs. */ - full = FirData_addGlblsToPnor( io_fd, pTrgt, i_sTrgt, o_noAttn, i_chipStruct ); - if ( full || *o_noAttn ) break; - - /* Add the FIRs. */ - full = FirData_addFirsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); - if ( full ) break; - - /* Add the REGs. */ - full = FirData_addRegsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); - if ( full ) break; - - /* Add the IDFIRs. */ - full = FirData_addIdFirsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); - if ( full ) break; - - /* Add the IDREGs. */ - full = FirData_addIdRegsToPnor( io_fd, pTrgt, i_sTrgt, i_chipStruct ); - if ( full ) break; - - } while (0); - - return full; -} - - -/*------------------------------------------------------------------------------ */ - -/** @brief Iterates through configured targets and adds the data to PNOR. - * @param io_fd The FIR data stuct. - */ -void FirData_addTrgtsToPnor( FirData_t * io_fd ) -{ - bool full = false; - bool noAttn = false; - - uint8_t p = 0; - uint8_t u = 0; - uint8_t l_unit = 0; - - bool isM = false; - uint32_t fsi = 0; - - SCOM_Trgt_t sTrgt; - FirData_existBits_t l_existBits; - - do - { - memset(&l_existBits, 0x00, sizeof(FirData_existBits_t) ); - - /* Point past HOMER header to first chiplet info */ - /* 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); - - /* Iterate ALL CHIPs */ - for ( p = 0; p < io_fd->hData->chipCount; p++ ) - { - l_chipPtr = (HOMER_Chip_t *)l_bytePtr; - - /* get FSI base address and chip position (proc or centaur) */ - fsi = l_chipPtr->fsiBaseAddr; - p = l_chipPtr->chipPos; - - TRAC_INFO( " AddTgtsMain:ChipType:%d ChipNumber:%d", - l_chipPtr->chipType, p ); - - /* Is this a PROC or Centaur chip ? */ - if ( (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) || - (HOMER_CHIP_CUMULUS == l_chipPtr->chipType) ) - { - /* To access the 'chiplet exist' structure */ - l_bytePtr += sizeof(HOMER_Chip_t); - - /* 'Existing chiplet area' varies in size */ - if (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) - { - HOMER_ChipNimbus_t *l_nimExistBitPtr = - (HOMER_ChipNimbus_t *)l_bytePtr; - - /* get master proc indicator */ - isM = l_nimExistBitPtr->isMaster; - - /* Exist bit structure can differ so move to */ - /* common format and left justify for ease of use */ - l_existBits.xbusMask = ((uint32_t)(l_nimExistBitPtr->xbusMask)) - << (32 - MAX_XBUS_PER_PROC); - l_existBits.obusMask = ((uint32_t)(l_nimExistBitPtr->obusMask)) - << (32 - MAX_OBUS_PER_PROC); - l_existBits.ecMask = ((uint32_t)(l_nimExistBitPtr->ecMask)) - << (32 - MAX_EC_PER_PROC); - l_existBits.eqMask = ((uint32_t)(l_nimExistBitPtr->eqMask)) - << (32 - MAX_EQ_PER_PROC); - l_existBits.exMask = ((uint32_t)(l_nimExistBitPtr->exMask)) - << (32 - MAX_EX_PER_PROC); - l_existBits.mcbist_mc_Mask = ((uint32_t)(l_nimExistBitPtr->mcbistMask)) - << (32 - MAX_MCBIST_PER_PROC); - l_existBits.mcs_mi_Mask = ((uint32_t)(l_nimExistBitPtr->mcsMask)) - << (32 - MAX_MCS_PER_PROC); - l_existBits.mca_dmi_Mask = ((uint32_t)(l_nimExistBitPtr->mcaMask)) - << (32 - MAX_MCA_PER_PROC); - l_existBits.cappMask = ((uint32_t)(l_nimExistBitPtr->cappMask)) - << (32 - MAX_CAPP_PER_PROC); - l_existBits.pecMask = ((uint32_t)(l_nimExistBitPtr->pecMask)) - << (32 - MAX_PEC_PER_PROC); - l_existBits.phbMask = ((uint32_t)(l_nimExistBitPtr->phbMask)) - << (32 - MAX_PHB_PER_PROC); - - /* advance our pointer to next chip type */ - l_bytePtr += sizeof(HOMER_ChipNimbus_t); - - } /* if nimbus */ - else if (HOMER_CHIP_CUMULUS == l_chipPtr->chipType) - { - HOMER_ChipCumulus_t *l_cumExistBitPtr = - (HOMER_ChipCumulus_t *)l_bytePtr; - - /* get master proc indicator */ - isM = l_cumExistBitPtr->isMaster; - - /* Exist bit structure can differ so move to */ - /* common format and left justify for ease of use */ - l_existBits.xbusMask = ((uint32_t)(l_cumExistBitPtr->xbusMask)) - << (32 - MAX_XBUS_PER_PROC); - l_existBits.obusMask = ((uint32_t)(l_cumExistBitPtr->obusMask)) - << (32 - MAX_OBUS_PER_PROC); - l_existBits.ecMask = ((uint32_t)(l_cumExistBitPtr->ecMask)) - << (32 - MAX_EC_PER_PROC); - l_existBits.eqMask = ((uint32_t)(l_cumExistBitPtr->eqMask)) - << (32 - MAX_EQ_PER_PROC); - l_existBits.exMask = ((uint32_t)(l_cumExistBitPtr->exMask)) - << (32 - MAX_EX_PER_PROC); - l_existBits.mcbist_mc_Mask = ((uint32_t)(l_cumExistBitPtr->mcMask)) - << (32 - MAX_MC_PER_PROC); - l_existBits.mcs_mi_Mask = ((uint32_t)(l_cumExistBitPtr->miMask)) - << (32 - MAX_MI_PER_PROC); - l_existBits.mca_dmi_Mask = ((uint32_t)(l_cumExistBitPtr->dmiMask)) - << (32 - MAX_DMI_PER_PROC); - l_existBits.cappMask = ((uint32_t)(l_cumExistBitPtr->cappMask)) - << (32 - MAX_CAPP_PER_PROC); - l_existBits.pecMask = ((uint32_t)(l_cumExistBitPtr->pecMask)) - << (32 - MAX_PEC_PER_PROC); - l_existBits.phbMask = ((uint32_t)(l_cumExistBitPtr->phbMask)) - << (32 - MAX_PHB_PER_PROC); - - /* advance our pointer to next chip type */ - l_bytePtr += sizeof(HOMER_ChipCumulus_t); - } /* else if cumulus */ - - TRAC_INFO( " Masks XBUS:%X OBUS:%X EC:%X EQ:%X EX:%X CAPP:%X PEC:%X PHB:%X", - l_existBits.xbusMask, l_existBits.obusMask, l_existBits.ecMask, - l_existBits.eqMask, l_existBits.exMask, l_existBits.cappMask, - l_existBits.pecMask, l_existBits.phbMask ); - TRAC_INFO( " Masks MCBIST:%X MCS:%X MCA:%X", - l_existBits.mcbist_mc_Mask, l_existBits.mcs_mi_Mask, - l_existBits.mca_dmi_Mask ); - - /* Add this PROC to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_PROC, p, 0, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - /* noAttn is true when we have global regs but none */ - /* indicate an attention is present */ - if ( full ) break; - if ( noAttn ) continue; /* Skip other proc chiplets */ - - - /* gather other chiplets on the processor */ - for ( u = 0; u < MAX_XBUS_PER_PROC; u++ ) - { - /* Check if the XBUS is configured. */ - if ( 0 == (l_existBits.xbusMask & (0x80000000 >> u)) ) continue; - - /* Add this XBUS to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_XBUS, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - } - if ( full ) break; - - /* gather other chiplets on the processor */ - for ( u = 0; u < MAX_OBUS_PER_PROC; u++ ) - { - /* Check if the OBUS is configured. */ - if ( 0 == (l_existBits.obusMask & (0x80000000 >> u)) ) continue; - - /* Add this OBUS to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_OBUS, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - } - if ( full ) break; - - /* gather more proc chiplets */ - for ( u = 0; u < MAX_CAPP_PER_PROC; u++ ) - { - /* Check if the CAPP is configured. */ - if ( 0 == (l_existBits.cappMask & (0x80000000 >> u)) ) continue; - - /* Add this CAPP to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_CAPP, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - } - if ( full ) break; - - /* gather other chiplets on the processor */ - for ( u = 0; u < MAX_PEC_PER_PROC; u++ ) - { - /* Check if the PEC is configured. */ - if ( 0 == (l_existBits.pecMask & (0x80000000 >> u)) ) continue; - - /* Add this PEC to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_PEC, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the rest */ - - /* gather PHB's under the PEC */ - /* ************************** */ - /* PEC0-> PHB0 */ - /* PEC1-> PHB1 PHB2 */ - /* PEC2-> PHB3 PHB4 PHB5 */ - /* ************************** */ - uint32_t l_PhbPos; - - /* u will be 0, l_unit 0 */ - /* u will be 1, l_unit 0 and 1 */ - /* u will be 2, l_unit 0 and 1 and 2 */ - for ( l_unit = 0; l_unit < (u+1); l_unit++ ) - { - l_PhbPos = u + l_unit; - /** When we hit PEC2, need to bump PHB position */ - if ((MAX_PEC_PER_PROC - 1) == u) - { - l_PhbPos++; - } /* if last PEC unit */ - - /* Check if the PHB is configured. */ - if ( 0 == (l_existBits.phbMask & (0x80000000 >> l_PhbPos)) ) continue; - - /* Add this PHB to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_PHB, p, l_PhbPos, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the rest */ - - } /* end for on PHB chiplet */ - if ( full ) break; - - } /* end for on PEC chiplet */ - if ( full ) break; - - /* gather other chiplets on the processor */ - for ( u = 0; u < MAX_EC_PER_PROC; u++ ) - { - /* Check if the EC is configured. */ - if ( 0 == (l_existBits.ecMask & (0x80000000 >> u)) ) continue; - - /* Add this EC to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_EC, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the rest */ - - } /* end for on EC chiplet */ - if ( full ) break; - - /* gather other chiplets on the processor */ - for ( u = 0; u < MAX_EQ_PER_PROC; u++ ) - { - /* Check if the EQ is configured. */ - if ( 0 == (l_existBits.eqMask & (0x80000000 >> u)) ) continue; - - /* Add this EQ to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_EQ, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the rest */ - - /* gather other chiplets on the processor */ - uint32_t l_ExPerEq = (MAX_EX_PER_PROC/MAX_EQ_PER_PROC); - uint32_t l_ExPos; - - for (l_unit=0; l_unit < l_ExPerEq; l_unit++) - { - l_ExPos = (l_ExPerEq * u) + l_unit; - - /* Check if the EX is configured. */ - if ( 0 == (l_existBits.exMask & (0x80000000 >> l_ExPos)) ) continue; - - /* Add this EX to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(TRGT_EX, p, l_ExPos, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the rest */ - - } /* end for on EX chiplet */ - if ( full ) break; - - } /* end for on EQ chiplet */ - if ( full ) break; - - - /* processor type can impact next few units */ - TrgtType_t l_pnorTarget = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? - TRGT_MCBIST : TRGT_MC; - uint32_t l_maxPerProc = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? - MAX_MCBIST_PER_PROC : MAX_MC_PER_PROC; - - TrgtType_t l_pnorTarg2 = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? - TRGT_MCA : TRGT_DMI; - uint32_t l_maxPerProc2 = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? - MAX_MCA_PER_PROC : MAX_DMI_PER_PROC; - - uint32_t l_UnitPerMc = l_maxPerProc2 / l_maxPerProc; - uint8_t l_unitNumber; - - for ( u = 0; u < l_maxPerProc; u++ ) - { - /* Check if MCBIST / MC is configured. */ - if ( 0 == (l_existBits.mcbist_mc_Mask & (0x80000000 >> u)) ) continue; - - /* Add this MCBIST or MC to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(l_pnorTarget, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - if ( noAttn ) continue; /* Skip the rest */ - - /* Grab underlying MCA/DMI chiplet */ - for ( l_unit = 0; l_unit < l_UnitPerMc; l_unit++ ) - { - /* u=0 or 1 while l_unit is 0 thru 3 */ - /* Leading to unit number 0:3 or 4:7 */ - l_unitNumber = l_unit + (u * l_UnitPerMc); - /* Check if the MCA / DMI is configured. */ - if ( 0 == (l_existBits.mca_dmi_Mask & (0x80000000 >> l_unitNumber)) ) continue; - - /* Add this MCA / DMI to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(l_pnorTarg2, p, l_unitNumber, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - - } /* end for on MCA/DMI */ - if ( full ) break; - - } /* end for on MCBIST */ - if ( full ) break; - - - l_pnorTarget = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? - TRGT_MCS : TRGT_MI; - l_maxPerProc = (HOMER_CHIP_NIMBUS == l_chipPtr->chipType) ? - MAX_MCS_PER_PROC : MAX_MI_PER_PROC; - - for ( u = 0; u < l_maxPerProc; u++ ) - { - /* Check if the MCS / MI is configured. */ - if ( 0 == (l_existBits.mcs_mi_Mask & (0x80000000 >> u)) ) continue; - - /* Add this MCS or MI to the PNOR. */ - sTrgt = SCOM_Trgt_getTrgt(l_pnorTarget, p, u, fsi, isM); - full = FirData_addTrgtToPnor( io_fd, sTrgt, &noAttn, l_chipPtr ); - if ( full ) break; - } - if ( full ) break; - - - } /* if processor chip type */ - else if (HOMER_CHIP_CENTAUR == l_chipPtr->chipType) - { - /* HOMER_ChipCentaur_t *l_cenExistBitPtr = - (HOMER_ChipCentaur_t *)l_bytePtr; */ - /* uint32_t l_mbaMask = ((uint32_t) l_cenExistBitPtr->mbaMask) << - (sizeof(uint32_t) - MAX_MBA_PER_MEMBUF) */ - - /* we have Centaur chipPos in 'p' and fsi address in 'fsi' */ - - /* add this centaur later and iterate thru l_mbaMask */ - /* don't need for initial support */ - /* TODO RTC 173614 -- with CUMULUS */ - - /* advance our pointer to next chip type */ - l_bytePtr += sizeof(HOMER_ChipCentaur_t); - - } /* end if centaur chip type */ - else - { - /* unexpected chip type */ - TRAC_ERR( "addTrgtsToPnor saw invalid chip:0x%X", - l_chipPtr->chipType ); - break; - } /* end if centaur chip type */ - - } /* end for on all CHIPS we have in homer data */ - - } while (0); - -} /* end FirData_addTrgtsToPnor */ - -/*------------------------------------------------------------------------------ */ - -/** @brief Initializes the FIR data struct. Does range checking for the HOMER - * data. Initializes the PNOR header data. - * @param io_fd The FIR data stuct. - * @param i_hBuf SRAM pointer to the beginning of the HOMER data buffer. - * This should contain the FIR data information provided by - * PRD that is used to define which registers the OCC will - * need to SCOM. - * @param i_hBufSize Total size of the HOMER data buffer. - * @param i_pBuf SRAM pointer to the beginning of the PNOR data buffer. - * This will be used by this function as a temporary area of - * memory to store the PNOR data before writing that data to - * the PNOR. - * @param i_pBufSize Total size of the PNOR data buffer. - * @return Non-SUCCESS if HOMER or PNOR range checking fails or if an - * internal function fails. SUCCESS otherwise. - */ -int32_t FirData_init( FirData_t * io_fd, - uint8_t * i_hBuf, uint32_t i_hBufSize, - uint8_t * i_pBuf, uint32_t i_pBufSize ) -{ - #define FUNC "[FirData_init] " - - int32_t rc = SUCCESS; - - size_t sz_hData = sizeof(HOMER_Data_t); - size_t sz_pnoNoEcc = 0; - size_t sz_u32 = sizeof(uint32_t); - size_t sz_u64 = sizeof(uint64_t); - - bool full = false; - - uint32_t x[TRGT_MAX][REG_MAX]; - size_t curIdx = 0; - - uint32_t t = TRGT_FIRST; - - uint8_t * reglist = NULL; - - PNOR_Data_t pData = PNOR_getData(); - - do - { - /* Init the struct. */ - io_fd->hBuf = i_hBuf; - io_fd->maxHBufSize = i_hBufSize; - io_fd->hData = (HOMER_Data_t *)i_hBuf; - - io_fd->pBuf = i_pBuf; - io_fd->maxPBufSize = i_pBufSize; - io_fd->pData = (PNOR_Data_t *)i_pBuf; - io_fd->pBufSize = 0; - - memset( io_fd->hPtrs, 0x00, sizeof(io_fd->hPtrs) ); - - /* Check HOMER header data size. */ - if ( io_fd->maxHBufSize < sz_hData ) - { - TRAC_ERR( FUNC"HOMER header data size %d is larger than HOMER " - "data buffer %d", sz_hData, io_fd->maxHBufSize ); - rc = FAIL; - break; - } - - /* Check for valid HOMER data. */ - if ( HOMER_FIR2 != io_fd->hData->header ) - { - break; /* nothing to analyze. */ - } - - /* The actual maximum PNOR size may possibly be less then the PNOR data */ - /* buffer. If so, adjust maximum size. */ - sz_pnoNoEcc = (io_fd->hData->pnorInfo.pnorSize / 9) * 8; - if ( sz_pnoNoEcc < io_fd->maxPBufSize ) - io_fd->maxPBufSize = sz_pnoNoEcc; - - /* Initialize the PNOR header data. */ - full = FirData_addDataToPnor( io_fd, &pData, sizeof(pData) ); - if ( full ) - { - TRAC_ERR( FUNC"Unable to add header to PNOR buffer" ); - rc = FAIL; - break; - } - - /* Copy the IPL state from the HOMER data to the PNOR data. */ - io_fd->pData->iplState = io_fd->hData->iplState; - - /* Get the register list byte indexes in HOMER data buffer */ - memset( x, 0x00, sizeof(x) ); - for ( t = TRGT_FIRST; t < TRGT_MAX; t++ ) - { - x[t][REG_GLBL] = curIdx; - x[t][REG_FIR] = x[t][REG_GLBL] + sz_u32 * io_fd->hData->regCounts[t][REG_GLBL]; - x[t][REG_REG] = x[t][REG_FIR] + sz_u32 * io_fd->hData->regCounts[t][REG_FIR]; - x[t][REG_IDFIR] = x[t][REG_REG] + sz_u32 * io_fd->hData->regCounts[t][REG_REG]; - x[t][REG_IDREG] = x[t][REG_IDFIR] + sz_u64 * io_fd->hData->regCounts[t][REG_IDFIR]; - curIdx = x[t][REG_IDREG] + sz_u64 * io_fd->hData->regCounts[t][REG_IDREG]; - } - - /* Check to make sure the list data is not larger than the available */ - /* Homer buffer. */ - if ( io_fd->maxHBufSize - sz_hData < curIdx ) - { - TRAC_ERR( FUNC"HOMER list size %d is larger than HOMER data " - "buffer %d", curIdx, io_fd->maxHBufSize - sz_hData ); - rc = FAIL; - break; - } - - /* 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 **/ - uint32_t l_chipNum; - for ( l_chipNum=0; - (l_chipNum < io_fd->hData->chipCount); - l_chipNum++ ) - { - l_chiptPtr = (HOMER_Chip_t *)reglist; - - /* Skip section on chip type, chip position, etc... */ - reglist += sizeof(HOMER_Chip_t); - - /* 'Existing chiplet area' varies in size */ - if (HOMER_CHIP_NIMBUS == l_chiptPtr->chipType) - { - reglist += sizeof(HOMER_ChipNimbus_t); - } - else if (HOMER_CHIP_CUMULUS == l_chiptPtr->chipType) - { - reglist += sizeof(HOMER_ChipCumulus_t); - } - else if (HOMER_CHIP_CENTAUR == l_chiptPtr->chipType) - { - reglist += sizeof(HOMER_ChipCentaur_t); - } - else - { - TRAC_ERR(FUNC"Chiptype is invalid %X ", l_chiptPtr->chipType); - rc = FAIL; - break; - } - - } /* end for loop skipping chip info sections */ - - - /* Now, get the pointers for each list. */ - for ( t = TRGT_FIRST; t < TRGT_MAX; t++ ) - { - (io_fd->hPtrs[t]).glbl = (uint32_t *)(reglist + x[t][REG_GLBL] ); - (io_fd->hPtrs[t]).fir = (uint32_t *)(reglist + x[t][REG_FIR] ); - (io_fd->hPtrs[t]).reg = (uint32_t *)(reglist + x[t][REG_REG] ); - (io_fd->hPtrs[t]).idFir = (uint64_t *)(reglist + x[t][REG_IDFIR]); - (io_fd->hPtrs[t]).idReg = (uint64_t *)(reglist + x[t][REG_IDREG]); - } - - /* Set EC level dep reg list ptr - at very end of list */ - io_fd->ecDepReg = (HOMER_ChipSpecAddr_t *)(reglist + curIdx); - - - } while (0); - - return rc; - - #undef FUNC -} - -/*------------------------------------------------------------------------------ */ -/* External functions */ -/*------------------------------------------------------------------------------ */ - -int32_t FirData_captureCsFirData( uint8_t * i_hBuf, uint32_t i_hBufSize, - uint8_t * i_pBuf, uint32_t i_pBufSize ) -{ - #define FUNC "[FirData_captureCsFirData] " - - int32_t rc = SUCCESS; - - do - { - /* Init the FIR data struct. */ - FirData_t fd; - rc = FirData_init( &fd, i_hBuf, i_hBufSize, i_pBuf, i_pBufSize ); - if ( SUCCESS != rc ) - { - TRAC_ERR( FUNC"Failed to init FIR data" ); - break; - } - - /* Check for valid HOMER data. */ - if ( HOMER_FIR2 != fd.hData->header ) - { - TRAC_ERR( FUNC"No HOMER data detected: header=0x%08x", - fd.hData->header ); - break; /* nothing to analyze. */ - } - - /* Start adding register data to PNOR for each target. */ - FirData_addTrgtsToPnor( &fd ); - - /* Write Buffer to PNOR */ -/* TODO: enable when function is supported. - rc = PNOR_writeFirData( fd.hData->pnorInfo, fd.pBuf, fd.pBufSize ); - if ( SUCCESS != rc ) - { - TRAC_ERR( FUNC"Failed to process FIR data" ); - break; - } -*/ - - } while (0); - - if ( SUCCESS != rc ) - { - TRAC_ERR( FUNC"Failed: i_hBuf=%p, i_hBufSize=0x%08x, i_pBuf=%p, " - "i_pBufSize=%08x", i_hBuf, i_hBufSize, i_pBuf, i_pBufSize ); - } - - return rc; - - #undef FUNC -} - diff --git a/src/occ_405/firdata/firData.h b/src/occ_405/firdata/firData.h deleted file mode 100644 index f1475db..0000000 --- a/src/occ_405/firdata/firData.h +++ /dev/null @@ -1,48 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/firData.H $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __firData_h -#define __firData_h - -#include "native.h" - -/** @brief Reads the register list from the HOMER data, SCOMs hardware, and - * stores the register values in PNOR. - * @param i_hBuf SRAM pointer to the beginning of the HOMER data buffer. - * This should contain the FIR data information provided by - * PRD that is used to define which registers the OCC will - * need to SCOM. - * @param i_hBufSize Total size of the HOMER data buffer. - * @param i_pBuf SRAM pointer to the beginning of the PNOR data buffer. - * This will be used by this function as a temporary area - * of memory to store the PNOR data before writing that - * data to the PNOR. - * @param i_pBufSize Total size of the PNOR data buffer. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t FirData_captureCsFirData( uint8_t * i_hBuf, uint32_t i_hBufSize, - uint8_t * i_pBuf, uint32_t i_pBufSize ); - -#endif /* __firData_h */ diff --git a/src/occ_405/firdata/firDataConst_common.h b/src/occ_405/firdata/firDataConst_common.h deleted file mode 100644 index 403a028..0000000 --- a/src/occ_405/firdata/firDataConst_common.h +++ /dev/null @@ -1,132 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/firDataConst_common.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __firDataConst_common_h -#define __firDataConst_common_h - -/** NOTE: This file is common between OCC and Hosboot. Any change to this file - * must be mirrored to both repositories. Also, this must be C, not C++, - * because OCC strictly uses C. */ - -#include <stdint.h> - -/** Target types for all supported targets. */ -/** NOTE: These are used to build the register list in HOMER data */ -/** and also to create the exiting chiplet masks. Hence, */ -/** the numbers assigned here have to match the sequence */ -/** of chiplets in HOMER_ChipNimbus_t, HOMER_ChipCumulus_t, etc. */ -typedef enum -{ - /* NOTE: These will be used as array indexes. */ - TRGT_FIRST = 0, - - /** Common Nimbus/Cumulus types */ - TRGT_PROC = TRGT_FIRST, - TRGT_CAPP, - TRGT_XBUS, - TRGT_OBUS, - TRGT_PEC, - TRGT_PHB, - TRGT_EQ, - TRGT_EX, - TRGT_EC, - - /* Nimbus only */ - TRGT_MCBIST, - TRGT_MCS, - TRGT_MCA, - - /* Cumulus only */ - /* NOTE: Nimbus and Cumulus cannot be used at the same time. So we can have - * These array indexes overlap to save space. */ - TRGT_MC = TRGT_MCBIST, - TRGT_MI, - TRGT_DMI, - - /* Centaur only */ - TRGT_MEMBUF, - TRGT_MBA, - - TRGT_MAX, - -} TrgtType_t; - -/** Boundary/position ranges for each target type. */ -typedef enum -{ - /* Common Nimbus/Cumulus */ - MAX_PROC_PER_NODE = 8, - MAX_CAPP_PER_PROC = 2, - MAX_XBUS_PER_PROC = 3, /* Nimbus 1 and 2, Cumulus 0, 1, and 2 */ - MAX_OBUS_PER_PROC = 4, /* Nimbus 0 and 3, Cumulus 0, 1, 2, and 3 */ - MAX_PEC_PER_PROC = 3, - MAX_PHB_PER_PROC = 6, - MAX_EQ_PER_PROC = 6, - MAX_EX_PER_PROC = 12, - MAX_EC_PER_PROC = 24, - - /** Nimbus only */ - MAX_MCBIST_PER_PROC = 2, - MAX_MCS_PER_PROC = 4, - MAX_MCA_PER_PROC = 8, - - /** Cumulus only */ - MAX_MC_PER_PROC = 2, - MAX_MI_PER_PROC = 4, - MAX_DMI_PER_PROC = 8, - - /** Centaur only */ - MAX_MEMBUF_PER_PROC = 8, - MAX_MEMBUF_PER_NODE = MAX_MEMBUF_PER_PROC * MAX_PROC_PER_NODE, - MAX_MBA_PER_MEMBUF = 2, - MAX_MBA_PER_PROC = MAX_MEMBUF_PER_PROC * MAX_MBA_PER_MEMBUF, - -} TrgtPos_t; - -/** All register types. */ -typedef enum -{ - /* NOTE: These will be used as array indexes. */ - REG_FIRST = 0, - - REG_GLBL = REG_FIRST, /* 32-bit addresses, 64-bit value */ - REG_FIR, /* 32-bit addresses, 64-bit value */ - REG_REG, /* 32-bit addresses, 64-bit value */ - REG_IDFIR, /* 64-bit addresses, 32-bit value */ - REG_IDREG, /* 64-bit addresses, 32-bit value */ - - REG_MAX, - -} RegType_t; - -/** Indicates the state of the machine when the checkstop occurred. */ -typedef enum -{ - FIRDATA_STATE_RUNTIME = 0, - FIRDATA_STATE_IPL = 1, - -} IplState_t; - -#endif /* __firDataConst_common_h */ diff --git a/src/occ_405/firdata/fir_data_collect.c b/src/occ_405/firdata/fir_data_collect.c deleted file mode 100644 index a2af34f..0000000 --- a/src/occ_405/firdata/fir_data_collect.c +++ /dev/null @@ -1,166 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/fir_data_collect.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - - -#include <fir_data_collect.h> -#include <scom.h> -#include <occ_service_codes.h> -#include <errl.h> -#include "tpc_firmware_registers.h" -#include "tpc_register_addresses.h" -#include <trac.h> -#include <homer.h> -#include <firData.h> - -FIR_HEAP_BUFFER(uint8_t G_fir_heap[FIR_HEAP_SECTION_SIZE]); -FIR_PARMS_BUFFER(uint8_t G_fir_data_parms[FIR_PARMS_SECTION_SIZE]); -uint32_t G_fir_master = FIR_OCC_NOT_FIR_MASTER; - -/* - * Function Specification - * - * Name: fir_data_collect - * - * Description: Collects FIR data on checkstop. - * - * End Function Specification - */ -void fir_data_collect(void) -{ - - int32_t l_rc = 0; - - // Homer data section and size - uint8_t *l_hBuf = (uint8_t*) FIR_PARMS_SECTION_BASE_ADDRESS; - uint32_t l_hBufSize = HOMER_FIR_PARM_SIZE; - // PNOR working buffer in SRAM and size - uint8_t *l_pBuf = (uint8_t*) FIR_HEAP_SECTION_BASE_ADDRESS; - uint32_t l_pBufSize = FIR_HEAP_SECTION_SIZE; - - l_rc = FirData_captureCsFirData(l_hBuf, - l_hBufSize, - l_pBuf, - l_pBufSize); - - // Trace the rc only, error logs cannot be collected in this state - TRAC_IMP("Checkstop FIR data capture completed with rc=%d", l_rc); -} - - -/* - * Function Specification - * - * Name: pnor_access_ok - * - * Description: Determines if it is ok for this OCC to access the PNOR. - * - * End Function Specification - */ -// TODO: This code is not allowed currently, as it relies on performing scom operations. -#if 0 -bool pnor_access_allowed(void) -{ - /* BMC ownership of the PNOR is indicated by bit 18 in TPC_GP0 */ - int l_rc = 0; - tpc_gp0_t l_tp_gp0_read; - bool l_access_allowed = FALSE; - - l_tp_gp0_read.words.high_order = 0x00000000; - l_tp_gp0_read.words.low_order = 0x00000000; - - l_rc = getscom_ffdc(TPC_GP0, (uint64_t *)&l_tp_gp0_read, NULL); - - if (l_rc == 0) - { - if ((l_tp_gp0_read.words.high_order & TPC_GP0_BIT18_PNOR_OWNER_MASK) == 0) - { - TRAC_INFO("PNOR access allowed at this time"); - l_access_allowed = TRUE; - } - else - { - TRAC_INFO("PNOR access NOT allowed at this time, tpc_gp0.hi = 0x%08x", - l_tp_gp0_read.words.high_order); - - /* @ - * @errortype - * @moduleid FIR_DATA_MID - * @reasoncode INTERNAL_FAILURE - * @userdata1 TPC_GP0 high word - * @userdata4 ERC_PNOR_OWNERSHIP_NOT_AVAILABLE - * @devdesc PNOR access not allowed at this time. - */ - errlHndl_t l_errl = createErrl( - FIR_DATA_MID, /*ModId */ - INTERNAL_FAILURE, /*Reasoncode */ - ERC_PNOR_OWNERSHIP_NOT_AVAILABLE, /*Extended reasoncode */ - ERRL_SEV_INFORMATIONAL, /*Severity */ - NULL, /*Trace Buf */ - DEFAULT_TRACE_SIZE, /*Trace Size */ - l_tp_gp0_read.words.high_order, /*Userdata1 */ - 0 /*Userdata2 */ - ); - - /* Commit log */ - commitErrl(&l_errl); - } - } - else - { - /* getscom failure */ - TRAC_ERR("TPC_GP0 getscom failure rc = 0x%08x", -l_rc ); - - /* @ - * @errortype - * @moduleid FIR_DATA_MID - * @reasoncode INTERNAL_HW_FAILURE - * @userdata1 getscom failure rc - * @userdata4 ERC_GETSCOM_TPC_GP0_FAILURE - * @devdesc Failure determining PNOR ownership. Cannot read TPC_GP0. - */ - errlHndl_t l_errl = createErrl( - FIR_DATA_MID, /*ModId */ - INTERNAL_HW_FAILURE, /*Reasoncode */ - ERC_GETSCOM_TPC_GP0_FAILURE, /*Extended reasoncode */ - ERRL_SEV_PREDICTIVE, /*Severity */ - NULL, /*Trace Buf */ - DEFAULT_TRACE_SIZE, /*Trace Size */ - l_rc, /*Userdata1 */ - 0 /*Userdata2 */ - ); - - /* Callout firmware */ - addCalloutToErrl(l_errl, - ERRL_CALLOUT_TYPE_COMPONENT_ID, - ERRL_COMPONENT_ID_FIRMWARE, - ERRL_CALLOUT_PRIORITY_HIGH); - - /* Commit log */ - commitErrl(&l_errl); - } - - return l_access_allowed; -} -#endif diff --git a/src/occ_405/firdata/fir_data_collect.h b/src/occ_405/firdata/fir_data_collect.h deleted file mode 100644 index c313956..0000000 --- a/src/occ_405/firdata/fir_data_collect.h +++ /dev/null @@ -1,56 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/fir_data_collect.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - - -#ifndef _FIR_DATA_COLLECT_H -#define _FIR_DATA_COLLECT_H - -#include <common_types.h> - -/* This size has to agree with the size _FIR_PARMS_SECTION_SIZE defined in the */ -/* OCC linker command file. */ -#define FIR_PARMS_SECTION_SIZE 0x1000 -// This size has to agree with the size _FIR_HEAP_SECTION_SIZE defined in the -// OCC linker command file. -#define FIR_HEAP_SECTION_SIZE 0x3000 - -enum fir_master -{ - FIR_OCC_NOT_FIR_MASTER = 0x00000000, - FIR_OCC_IS_FIR_MASTER = 0x00000001 -}; - -extern uint8_t G_fir_data_parms[FIR_PARMS_SECTION_SIZE]; -extern uint8_t G_fir_heap[FIR_HEAP_SECTION_SIZE]; -extern uint32_t G_fir_master; - -#define OCC_SET_FIR_MASTER(_fm_t) G_fir_master = _fm_t -#define OCC_IS_FIR_MASTER() (G_fir_master == FIR_OCC_IS_FIR_MASTER) ? TRUE : FALSE -#define TPC_GP0_BIT18_PNOR_OWNER_MASK 0x00002000 - -void fir_data_collect(void); -bool pnor_access_allowed(void); - -#endif /* _FIR_DATA_COLLECT_H */ diff --git a/src/occ_405/firdata/fsi.c b/src/occ_405/firdata/fsi.c deleted file mode 100644 index 4bf105a..0000000 --- a/src/occ_405/firdata/fsi.c +++ /dev/null @@ -1,152 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/fsi.C $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#include <fsi.h> -#include <scom_util.h> -#include <native.h> - -#define OPB_REG_CMD 0x00020010 -#define OPB_REG_STAT 0x00020011 -#define OPB_REG_RES 0x00020014 -#define OPB_STAT_BUSY 0x0001000000000000 /**< 15 is the Busy bit */ -#define NS_PER_MSEC (1000000ull) - - -void fsi_recovery() -{ - int32_t rc = SUCCESS; - - /* Clear out OPB error */ - uint64_t scom_data = 0; - scom_data = 0x8000000000000000; /*0=Unit Reset*/ - rc |= xscom_write( OPB_REG_RES, scom_data ); - rc |= xscom_write( OPB_REG_STAT, scom_data ); - - /* Check if we have any errors left */ - rc |= xscom_read( OPB_REG_STAT, &scom_data ); - - TRACFCOMP( "PIB2OPB Status after cleanup = %08X%08X (rc=%d)", - (uint32_t)(scom_data >> 32), (uint32_t)scom_data, rc ); -} - -/** - * @brief Poll for completion of a FSI operation, return data on read - */ -int32_t poll_for_complete( uint32_t * o_val ) -{ - int32_t rc = SUCCESS; - - enum { MAX_OPB_TIMEOUT_NS = 10*NS_PER_MSEC }; /*=10ms */ - - *o_val = 0; - - uint64_t read_data = 0; - uint64_t elapsed_time_ns = 0; - do - { - rc = xscom_read( OPB_REG_STAT, &read_data ); - if ( SUCCESS != rc ) - { - fsi_recovery(); /* Try to recover the engine. */ - return rc; - } - - /* Check for completion. Note: not checking for FSI errors. */ - if ( (read_data & OPB_STAT_BUSY) == 0 ) break; /* Not busy */ - - sleep( 10000 ); /* sleep for 10,000 ns */ - elapsed_time_ns += 10000; - - } while ( elapsed_time_ns <= MAX_OPB_TIMEOUT_NS ); - - if ( MAX_OPB_TIMEOUT_NS < elapsed_time_ns ) - { - TRAC_ERR( "[poll_for_complete] FSI request timed out." ); - return FAIL; - } - - *o_val = (uint32_t)read_data; /* Data in the bottom half. */ - - return rc; -} - -/** - * @brief Read a FSI register - */ -int32_t getfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t * o_val ) -{ - int32_t rc = SUCCESS; - - uint32_t fsi_addr = i_trgt.fsiBaseAddr | i_addr; - - /* setup the OPB command register */ - /* only supporting 4-byte access */ - uint64_t fsi_cmd = fsi_addr | 0x60000000; /* 011=Read Full Word */ - fsi_cmd <<= 32; /* Command is in the upper word of the scom */ - - /* Write the OPB command register to trigger the read */ - rc = xscom_write( OPB_REG_CMD, fsi_cmd ); - if ( SUCCESS != rc ) - { - fsi_recovery(); /* Try to recover the engine. */ - return rc; - } - - /* Poll for complete and get the data back. */ - rc = poll_for_complete( o_val ); - - return rc; -} - -/** - * @brief Write a FSI register - */ -int32_t putfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t i_val ) -{ - int32_t rc = SUCCESS; - - uint32_t fsi_addr = i_trgt.fsiBaseAddr | i_addr; - - /* setup the OPB command register */ - /* only supporting 4-byte access */ - uint64_t fsi_cmd = fsi_addr | 0xE0000000; /* 111=Write Full Word */ - fsi_cmd <<= 32; /* Command is in the upper word of the scom */ - fsi_cmd |= i_val; /* Data is in the bottom 32-bits */ - - /* Write the OPB command register to trigger the read */ - rc = xscom_write( OPB_REG_CMD, fsi_cmd ); - if ( SUCCESS != rc ) - { - fsi_recovery(); /* Try to recover the engine. */ - return rc; - } - - /* Poll for complete */ - uint32_t junk = 0; // Not used. - rc = poll_for_complete( &junk ); - - return rc; -} - diff --git a/src/occ_405/firdata/fsi.h b/src/occ_405/firdata/fsi.h deleted file mode 100644 index 870e47f..0000000 --- a/src/occ_405/firdata/fsi.h +++ /dev/null @@ -1,47 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/fsi.H $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/* Interfaces to read/write FSI registers */ - -#include <scom_trgt.h> - -/** - * @brief Read a FSI register. - * @param i_trgt Chip/unit to read from. - * @param i_addr FSI address to read, relative to slave's base address. - * @param o_val Returned value. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t getfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t * o_val ); - -/** - * @brief Write a FSI register. - * @param i_trgt Chip/unit to write to. - * @param i_addr FSI address to write, relative to slave's base address. - * @param o_val Value to write. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t putfsi( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint32_t i_val ); - diff --git a/src/occ_405/firdata/homerData_common.h b/src/occ_405/firdata/homerData_common.h deleted file mode 100644 index 66aa53a..0000000 --- a/src/occ_405/firdata/homerData_common.h +++ /dev/null @@ -1,271 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/homerData_common.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __homerData_common_h -#define __homerData_common_h - -/** NOTE: This file is common between OCC and Hosboot. Any change to this file - * must be mirrored to both repositories. Also, this must be C, not C++, - * because OCC strictly uses C. */ - -#include <firDataConst_common.h> -#include <string.h> - -/** This file is used to define the format of the register list stored in the - * HOMER data that the OCC will use to determine what register data to capture - * in the event of a system checkstop. The data will be stored in the following - * format: - * - * - HOMER_Data_t struct - This contains PNOR information, IPL state, number of - * configured chips, and number of register addresses per target type per - * register type. - * - * - For each configured chip, the following format will be used: - * - HOMER_Chip_t struct - containing FSI base address, chip type, and chip - * position. - * - Immediately following will be a chip struct that is specific to the - * chip type stored in the preceding struct. These vary in size and - * structure depending on the chip type. - * - * - 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 - * 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: - * - FIR - * - MASK (FIR address + 3) - * - ACT0 (FIR address + 6) - * - ACT1 (FIR address + 7) - * - ID FIR - * - ID MASK (ID FIR address + 0x300000000ll) - * - ID ACT0 (ID FIR address + 0x600000000ll) - * - ID ACT1 (ID FIR address + 0x700000000ll) - * Note that not all FIRs have a corresponding WOF register. So any WOFs needed - * for analysis will need to be explicitly listed in the corresponding - * 'Registers' lists. - */ - -typedef enum -{ - HOMER_FIR1 = 0x46495231, /** FIR data version 1 ("FIR1" in ascii) P8 */ - HOMER_FIR2 = 0x46495232, /** FIR data version 1 ("FIR2" in ascii) P9 */ - -} 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 */ - uint32_t pnorSize; /** Maximum size of FIRDATA (includes ECC) */ - uint32_t mmioOffset; /** Address of MMIO access */ - uint32_t norWorkarounds; /** NOR flash vendor */ - -} HOMER_PnorInfo_t; - -/** 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 */ - - 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; - - /** 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]; - -} HOMER_Data_t; - -/** @return An initialized HOMER_Data_t struct. */ -static inline HOMER_Data_t HOMER_getData() -{ - HOMER_Data_t d; memset( &d, 0x00, sizeof(d) ); /* init to zero */ - - d.header = HOMER_FIR2; - - return d; -} - -/*----------------------------------------------------------------------------*/ - -/** Supported chip types. */ -typedef enum -{ - HOMER_CHIP_NIMBUS, /** P9 Nimbus processor chip */ - HOMER_CHIP_CUMULUS, /** P9 Cumulus processor chip */ - HOMER_CHIP_CENTAUR, /** Centaur memory buffer chip */ - -} 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. */ - - 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. */ - uint32_t trgtType : 6; /** See TrgtType_t. */ - uint32_t regType : 4; /** See RegType_t. */ - uint32_t ddLevel : 8; /** A zero value applies to all levels on a chip. */ - uint32_t reserved : 10; /** unused at this time */ - - /** The 32 or 64 bit address (right justified). */ - uint64_t address; - -} HOMER_ChipSpecAddr_t; - -/** @return An initialized HOMER_Chip_t struct. */ -static inline HOMER_Chip_t HOMER_getChip( HOMER_ChipType_t i_type ) -{ - HOMER_Chip_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ - - c.fsiBaseAddr = 0xffffffff; - c.chipType = i_type; - - return c; -} - -/*----------------------------------------------------------------------------*/ - -/** 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 */ - uint32_t xbusMask : 3; /** Mask of configured XBUS units (0-2) */ - uint32_t obusMask : 4; /** Mask of configured OBUS units (0-3) */ - uint32_t ecMask : 24; /** Mask of configured EC units (0-23) */ - - uint32_t eqMask : 6; /** Mask of configured EQ units (0-5) */ - uint32_t exMask : 12; /** Mask of configured EX units (0-11) */ - uint32_t mcbistMask : 2; /** Mask of configured MCBIST units (0-1) */ - uint32_t mcsMask : 4; /** Mask of configured MCS units (0-3) */ - uint32_t mcaMask : 8; /** Mask of configured MCA units (0-7) */ - - 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; - -/** @return An initialized HOMER_ChipNimbus_t struct. */ -static inline HOMER_ChipNimbus_t HOMER_initChipNimbus() -{ - HOMER_ChipNimbus_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ - - return c; -} - -/*----------------------------------------------------------------------------*/ - -/** 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 */ - uint32_t xbusMask : 3; /** Mask of configured XBUS units (0-2) */ - uint32_t obusMask : 4; /** Mask of configured OBUS units (0-3) */ - uint32_t ecMask : 24; /** Mask of configured EC units (0-23) */ - - uint32_t eqMask : 6; /** Mask of configured EQ units (0-5) */ - uint32_t exMask : 12; /** Mask of configured EX units (0-11) */ - uint32_t mcMask : 2; /** Mask of configured MC units (0-1) */ - uint32_t miMask : 4; /** Mask of configured MI units (0-3) */ - uint32_t dmiMask : 8; /** Mask of configured DMI units (0-7) */ - - 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; - -/** @return An initialized HOMER_ChipCumulus_t struct. */ -static inline HOMER_ChipCumulus_t HOMER_initChipCumulus() -{ - HOMER_ChipCumulus_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ - - return c; -} - -/*----------------------------------------------------------------------------*/ - -/** Information specific to a Centaur memory buffer chip. */ -/* NOTE: This structure is 4-byte word aligned. */ -typedef struct __attribute__((packed)) -{ - uint32_t mbaMask : 2; /** Mask of configured MBA units (0-1) */ - uint32_t reserved : 30; - -} HOMER_ChipCentaur_t; - -/** @return An initialized HOMER_ChipCentaur_t struct. */ -static inline HOMER_ChipCentaur_t HOMER_initChipCentaur() -{ - HOMER_ChipCentaur_t c; memset( &c, 0x00, sizeof(c) ); /* init to zero */ - - return c; -} - -#endif /* __homerData_common_h */ diff --git a/src/occ_405/firdata/lpc.c b/src/occ_405/firdata/lpc.c deleted file mode 100644 index ffe2b48..0000000 --- a/src/occ_405/firdata/lpc.c +++ /dev/null @@ -1,391 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/lpc.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#include <native.h> -#include <lpc.h> -#include <trac_interface.h> -#include <scom_util.h> - -#define LPCHC_FW_SPACE 0xF0000000 /**< LPC Host Controller FW Space */ -#define LPCHC_MEM_SPACE 0xE0000000 /**< LPC Host Controller Mem Space */ -#define LPCHC_IO_SPACE 0xD0010000 /**< LPC Host Controller I/O Space */ -#define LPCHC_REG_SPACE 0xC0012000 /**< LPC Host Ctlr Register Space */ -#define ECCB_NON_FW_RESET_REG 0x000B0001 /**< ECCB Reset Reg (non-FW) */ - -#define LPC_BASE_REG 0x00090040 /**< LPC Base Address Register */ -#define LPC_CMD_REG 0x00090041 /**< LPC Command Register */ -#define LPC_DATA_REG 0x00090042 /**< LPC Data Register */ -#define LPC_STATUS_REG 0x00090043 /**< LPC Status Register */ - -#define ECCB_CTL_REG 0x000B0020 /**< ECCB Control Reg (FW) */ -#define ECCB_RESET_REG 0x000B0021 /**< ECCB Reset Reg (FW) */ -#define ECCB_STAT_REG 0x000B0022 /**< ECCB Status Reg (FW) */ -#define ECCB_DATA_REG 0x000B0023 /**< ECCB Data Reg (FW) */ - -/* Default Values to set for all operations - 1101.0100.0000.000x.0000.0001.0000.0000.<address> */ -#define ECCB_CTL_REG_DEFAULT 0xD400010000000000 - -/* Error bits: wh_todo comments here */ -#define LPC_STAT_REG_ERROR_MASK 0x0000000000000000 /**< Error Bits */ //wh_todo correctly set mask - -/**< OPB LPCM Sync FIR Reg - used to read the FIR*/ -#define OPB_LPCM_FIR_REG 0x01010C00 - -/**< OPB LPCM Sync FIR Reg WOX_AND - used to clear the FIR */ -#define OPB_LPCM_FIR_WOX_AND_REG 0x01010C01 - -/**< OPB LPCM Sync FIR Mask Reg WO_OR - used to set the mask */ -#define OPB_LPCM_FIR_MASK_WO_OR_REG 0x01010C05 - -#define OPB_LPCM_FIR_ERROR_MASK 0xFF00000000000000 /**< Error Bits MASK */ - -/* LPCHC reset-related registers */ -#define OPB_MASTER_LS_CONTROL_REG 0x008 /**<OPBM LS Control Reg */ -#define LPCHC_RESET_REG 0x0FC /**<LPC HC Reset Register */ - -#define ECCB_RESET_LPC_FAST_RESET (1ULL << 62) /**< bit 1 Fast reset */ - -#define LPC_POLL_TIME_NS 400000 /**< max time should be 400ms */ -#define LPC_POLL_INCR_NS 100000 /**< increase for testing */ - -#define LPCHC_SYNC_CYCLE_COUNTER_INFINITE 0xFF000000 - -/** - * @brief LPC Base Register Layout -*/ -typedef union -{ - - uint64_t data64; - - struct - { - /* unused sections should be set to zero */ - uint64_t unused0 : 8; /**< 0:7 */ - uint64_t base_addr : 24; /**< 8:31 */ - uint64_t unused1 : 31; /**< 32:62 */ - uint64_t disable : 1; /**< 63 */ - }; -} BaseReg_t; - -/** - * @brief LPC Control Register Layout - */ -typedef union -{ - - uint64_t data64; - - struct - { - /* unused sections should be set to zero */ - // rnw == read not write - uint64_t rnw : 1; /**< 0 = Setting to 1 causes read */ - uint64_t unused0 : 4; /**< 1:4 */ - uint64_t size : 7; /**< 5:11 */ - uint64_t unused1 : 20; /**< 12:31 */ - uint64_t address : 32; /**< 32:63 = LPC Address */ - }; -} CommandReg_t; - -/** - * @brief LPC Status Register Layout - */ -typedef union -{ - uint64_t data64; - struct - { - uint64_t op_done : 1; /**< 0 */ - uint64_t unused0 : 9; /**< 1:9 */ - uint64_t opb_valid : 1; /**< 10 */ - uint64_t opb_ack : 1; /**< 11 */ - uint64_t unused1 : 52; /**< 12:63 */ - }; -} StatusReg_t; - -uint32_t checkAddr(LpcTransType i_type, - uint32_t i_addr) -{ - uint32_t full_addr = 0; - switch ( i_type ) - { - case LPC_TRANS_IO: - full_addr = i_addr | LPCHC_IO_SPACE; - break; - case LPC_TRANS_FW: - full_addr = i_addr | LPCHC_FW_SPACE; - break; - } - return full_addr; -} - - -errorHndl_t pollComplete(CommandReg_t* i_ctrl, - StatusReg_t* o_stat) -{ - errorHndl_t l_err = NO_ERROR; - - do { - uint64_t poll_time = 0; - uint64_t loop = 0; - do - { - SCOM_Trgt_t l_target; - l_target.type = TRGT_PROC; - l_target.isMaster = TRUE; - l_err = SCOM_getScom(l_target, LPC_STATUS_REG, &(o_stat->data64)); - - if( l_err ) - { - break; - } - - if( o_stat->op_done ) - { - break; - } - - /* Want to start out incrementing by small numbers then get bigger - to avoid a really tight loop in an error case so we'll increase - the wait each time through */ - sleep( LPC_POLL_INCR_NS*(++loop) ); - poll_time += LPC_POLL_INCR_NS * loop; - } while ( poll_time < LPC_POLL_TIME_NS ); - - /* Check for hw errors or timeout if no previous logs */ - if( (l_err == NO_ERROR) && - ((o_stat->data64 & LPC_STAT_REG_ERROR_MASK) - || (!o_stat->op_done)) ) - { - TRAC_ERR( "LpcDD::pollComplete> LPC error or timeout: addr=0x%.8X, status=0x%.8X%.8X", - i_ctrl->address, (uint32_t)(o_stat->data64>>32), (uint32_t)o_stat->data64 ); - l_err = -1; - break; - } - } while(0); - - return l_err; - -} - - -/*========================================================*/ - -errorHndl_t lpc_read( LpcTransType i_type, - uint32_t i_addr, - uint8_t* o_data, - size_t i_size ) -{ - errorHndl_t l_err = NO_ERROR; - int32_t l_addr = 0; - uint64_t l_ret; - uint32_t l_shift_amount; - uint64_t l_temp_data; - - do { - if( o_data == NULL ) - { - TRACFCOMP( "o_data is NULL!" ); - l_err = -2; - break; - } - - - /* Generate the full absolute LPC address */ - l_addr = checkAddr( i_type, i_addr ); - - /* Setup command */ - CommandReg_t lpc_cmd; - lpc_cmd.rnw = 1; //Indicate read not write - lpc_cmd.size = i_size; - lpc_cmd.address = l_addr; - - /* Execute command via Scom */ - SCOM_Trgt_t l_target; - l_target.type = TRGT_PROC; - l_target.isMaster = TRUE; - - //First write the address we want to read from in the - //LPC_CMD_REG scom address - l_err = SCOM_putScom(l_target, LPC_CMD_REG, lpc_cmd.data64); - if(l_err != SUCCESS) - { - TRAC_ERR("lpc_read: SCOM_putScom failed to write to LPC_CMD_REG command rc=0x%08x", - (uint32_t)l_err); - break; - } - - /* Poll for completion */ - StatusReg_t lpc_status; - l_err = pollComplete( &lpc_cmd, &lpc_status ); - if( l_err ) { break; } - - // Read data from the LPC_DATA_REG - l_err = SCOM_getScom(l_target, LPC_DATA_REG, &l_ret); - if(l_err != SUCCESS) - { - TRAC_ERR("lpc_read: SCOM_getScom failed rc=0x%08x", (uint32_t)l_err); - break; - } - - //The scom returns the data in the byte offset represented by last - //3 bits of the address. For example, addr 0x21 will have have data - //starting in byte1 on value returned from scom. - //addr & 0x7 <-- this gives the byte offset - //7 - (addr & 0x7) <-- subratcing from 7 as the data is left aligned - //adding (size - 1) <-- to incorporate reading more than one byte - //multiply by 8 to convert from byte to bits - l_shift_amount = (7 - ((l_addr & 0x7) + (i_size-1))) * 8; - l_temp_data = l_ret >> l_shift_amount; - - //Had some weird problems with memcpy, that's why typecasting - //to the size of data asked. - if (i_size == sizeof(uint8_t)) - { - uint8_t* l_temp_ptr = (uint8_t*)(o_data); - *l_temp_ptr = l_temp_data; - } - else if (i_size == sizeof(uint16_t)) - { - uint16_t* l_temp_ptr = (uint16_t*)(o_data); - *l_temp_ptr = l_temp_data; - } - else if (i_size == sizeof(uint32_t)) - { - uint32_t* l_temp_ptr = (uint32_t*)(o_data); - *l_temp_ptr = l_temp_data; - } - else if (i_size == sizeof(uint64_t)) - { - uint64_t* l_temp_ptr = (uint64_t*)(o_data); - *l_temp_ptr = l_temp_data; - } - else - { - TRAC_ERR("lpc_read: unsupported size length"); - l_err = -1; - break; - } - - } while(0); - - return l_err; -} - -errorHndl_t lpc_write( LpcTransType i_type, - uint32_t i_addr, - uint8_t* i_data, - size_t i_size ) -{ - errorHndl_t l_err = NO_ERROR; - uint32_t l_addr = 0; - uint64_t l_write_data = 0; - uint64_t l_data = 0; - uint32_t l_shift_amount; - - do { - /* Generate the full absolute LPC address */ - l_addr = checkAddr( i_type, i_addr ); - - /* Setup Write Command */ - CommandReg_t lpc_cmd; - lpc_cmd.rnw = 0; //Indicate write - lpc_cmd.size = i_size; - lpc_cmd.address = l_addr; - - /* Setup Write command via Scom */ - SCOM_Trgt_t l_target; - l_target.type = TRGT_PROC; - l_target.isMaster = TRUE; - - //First write the address we want to write to in LPC_CMD_REG - l_err = SCOM_putScom(l_target, LPC_CMD_REG, lpc_cmd.data64); - if(l_err != SUCCESS) - { - TRAC_ERR("ERROR> lpc_write: SCOM_putScom failed to write to LPC_CMD_REG command: rc=0x%08x", - (uint32_t)l_err); - break; - } - - //There were some weird memcpy problems. That's why, typecasting - //to the size of data requested to write - if (i_size == sizeof(uint8_t)) - { - l_write_data = (*i_data); - } - else if (i_size == sizeof(uint16_t)) - { - uint16_t* l_temp_ptr = (uint16_t*)(i_data); - l_write_data = *l_temp_ptr; - } - else if (i_size == sizeof(uint32_t)) - { - uint32_t* l_temp_ptr = (uint32_t*)(i_data); - l_write_data = *l_temp_ptr; - } - else if (i_size == sizeof(uint64_t)) - { - uint64_t* l_temp_ptr = (uint64_t*)(i_data); - l_write_data = *l_temp_ptr; - } - else - { - TRAC_ERR("lpc_write: unsupported size length"); - l_err = -1; - break; - } - - //The scom expects the data in the byte offset represented by last - //3 bits of the address. For example, addr 0x21 will have have data - //starting in byte1 on value returned from scom. - //addr & 0x7 <-- this gives the byte offset - //7 - (addr & 0x7) <-- subratcing from 7 as the data in the scom reg - //is expected to be left aligned - //adding (size - 1) <-- to incorporate reading more than one byte - //multiply by 8 to convert from byte to bits - l_shift_amount = (7 - ((l_addr & 0x7) + (i_size-1))) * 8; - l_data = (l_write_data << l_shift_amount); - - //Write the value to the LPC_DATA_REG - l_err = SCOM_putScom(l_target, LPC_DATA_REG, l_data); - if(l_err != SUCCESS) - { - TRAC_ERR("ERROR> lpc_write: SCOM_putScom failed to write to LPC_DATA_REG data: rc=0x%08x", - (uint32_t)l_err); - break; - } - - /* Poll for completion */ - StatusReg_t lpc_stat; - l_err = pollComplete( &lpc_cmd, &lpc_stat ); - if( l_err ) { break; } - - - } while(0); - - return l_err; -} diff --git a/src/occ_405/firdata/lpc.h b/src/occ_405/firdata/lpc.h deleted file mode 100644 index 177deda..0000000 --- a/src/occ_405/firdata/lpc.h +++ /dev/null @@ -1,55 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/lpc.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef _LPC_H -#define _LPC_H - -#include <native.h> -#include <errl.h> - -/** - * @enum LPC::TransType - * @brief LPC Transaction Types - */ -typedef enum { - LPC_TRANS_IO = 0, /* LPC IO Space */ - LPC_TRANS_FW = 1, /* LPC Firmware Space */ -} LpcTransType; - -errorHndl_t lpc_read( LpcTransType i_type, - uint32_t i_addr, - uint8_t* o_data, - size_t i_size ); - -errorHndl_t lpc_write( LpcTransType i_type, - uint32_t i_addr, - uint8_t* i_data, - size_t i_size ); - -uint32_t checkAddr(LpcTransType i_type, - uint32_t i_addr); - - -#endif diff --git a/src/occ_405/firdata/native.c b/src/occ_405/firdata/native.c deleted file mode 100644 index d214468..0000000 --- a/src/occ_405/firdata/native.c +++ /dev/null @@ -1,76 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/native.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#include <native.h> -#include <scom.h> -#include <trac.h> - -void sleep( SsxInterval i_nanoseconds ) -{ - ssx_sleep(SSX_NANOSECONDS(i_nanoseconds)); -} - -int TRACE_XSCOM=0; - -int32_t xscom_read( uint32_t i_address, uint64_t * o_data ) -{ - int32_t rc = SUCCESS; - - *o_data = 0; - - rc = getscom_ffdc( i_address, o_data, NULL ); - if ( SUCCESS != rc ) - { - TRAC_ERR( "SCOM error in xscom_read wrapper, rc=%d", rc ); - } - - if ( TRACE_XSCOM ) - { - TRACFCOMP( "xscom_read(%08X)=%08X%08X", i_address, - (uint32_t)(*o_data>>32), (uint32_t)(*o_data) ); - } - - return rc; -} - -int32_t xscom_write( uint32_t i_address, uint64_t i_data ) -{ - int32_t rc = SUCCESS; - - rc = putscom_ffdc( i_address, i_data, NULL ); - if ( SUCCESS != rc ) - { - TRAC_ERR( "SCOM error in xscom_write wrapper, rc=%d", rc ); - } - - if ( TRACE_XSCOM ) - { - TRACFCOMP( "xscom_write(%08X)=%08X%08X", i_address, - (uint32_t)(i_data>>32), (uint32_t)i_data); - } - - return rc; -} - diff --git a/src/occ_405/firdata/native.h b/src/occ_405/firdata/native.h deleted file mode 100644 index dd0daa7..0000000 --- a/src/occ_405/firdata/native.h +++ /dev/null @@ -1,98 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/native.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/* Native functions provided by OCC code */ -#ifndef _NATIVE_H -#define _NATIVE_H - -#include <common_types.h> -#include <trac.h> - -#ifdef __cplusplus -extern "C" { -#endif -#include "ssx.h" -#ifdef __cplusplus -} -#endif - -#ifndef NO_TRAC_STRINGS - -#ifdef FIRD_DEBUG -#define TRACDCOMP(frmt,args...) DBG_PRINT(frmt,##args) -#else -#define TRACDCOMP(frmt,args...) -#endif // FIRD_DEBUG - -#define TRACFCOMP(frmt,args...) TRACE(&g_des_array[INF_TRACE_DESCRIPTOR],INFO_MRK frmt,##args) - -#else // NO_TRAC_STRINGS - -#define TRACDCOMP(frmt,args...) -#define TRACFCOMP(frmt,args...) - -#endif // NO_TRAC_STRINGS - -typedef uint32_t errorHndl_t; - -#define ENTER_MRK -#define NO_ERROR 0 - -/* Return a number >= input that is aligned up to the next 4-byte boundary */ -#define ALIGN_4(u) (((u) + 0x3ull) & ~0x3ull) - -#define NS_PER_SEC (1000000000ull) - -#undef be64toh -#undef htobe64 -#define be64toh(x) (x) -#define htobe64(x) (x) - -#define KILOBYTE (1024ul) /**< 1 KB */ -#define MEGABYTE (1024 * 1024ul) /**< 1 MB */ -#define GIGABYTE (MEGABYTE * 1024ul) /**< 1 GB */ -#define TERABYTE (GIGABYTE * 1024ul) /**< 1 TB */ - -#define PAGESIZE (4*KILOBYTE) /**< 4 KB */ - -#undef SUCCESS -#define SUCCESS 0 - -#undef FAIL -#define FAIL -1 - -/*================================================ */ - -/* XSCOM Read */ -int32_t xscom_read( uint32_t i_address, uint64_t * o_data ); - -/* XSCOM Write */ -int32_t xscom_write( uint32_t i_address, uint64_t i_data ); - -/* Sleep */ -void sleep( SsxInterval i_nanoseconds ); - - -#endif diff --git a/src/occ_405/firdata/norflash.h b/src/occ_405/firdata/norflash.h deleted file mode 100644 index c4c9cdc..0000000 --- a/src/occ_405/firdata/norflash.h +++ /dev/null @@ -1,154 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/norflash.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __PNOR_NORFLASH_H -#define __PNOR_NORFLASH_H - -#include <native.h> -#include <pnor_mboxdd.h> - -/** @file norflash.H - * @brief Contains constants related to specific types of - * of NOR flash chips - */ - -/** - * @brief Supported NOR Chip IDs - */ -enum NorChipIDs -{ - UNKNOWN_NOR_ID = 0x12345600, /**< Initial value before read */ - - MICRON_MFG_ID = 0x20000000, /**< Micron Mfg ID */ - MICRON_NOR_ID = 0x20ba2000, /**< Micron NOR */ - - MACRONIX_MFG_ID = 0xC2000000, /**< Macronix Mfg ID */ - MACRONIX32_NOR_ID = 0xC2201A00, /**< Macronix NOR MXxxL51235F */ - MACRONIX64_NOR_ID = 0xC2201900, /**< Macronix NOR MXxxL25635F */ - - /* Note: Simics currently models Micron NOR */ - VPO_NOR_ID = 0x20201800, /**< VPO NOR chip ID */ - FAKE_NOR_ID = 0xBADBAD00, /**< ID used during fake pnor */ - - ID_MASK = 0xFFFFFF00, /**< Only look at 3 bytes */ - MFGID_MASK = 0xFF000000, /**< Manufacturer ID is the first byte */ -}; - -/** - * @brief SPI Config Info - * OP Codes and other MISC info for configuring SFC - */ -typedef enum -{ - SPI_NO_OPCODE = 0x00, /**< Undefined value */ - - /* - * Micron Flash Commands - */ - SPI_MICRON_FLAG_STAT = 0x70, /**< Check write/erase complete */ - SPI_MICRON_CLRFLAG_STAT = 0x50, /**< Clear write/erase Status reg */ - - /* - * Macronix Flash Commands - */ - SPI_MACRONIX_EN4B = 0xB7, /**< Enable Macronix 4-Byte addressing */ - - /* SPI protocol commands */ - SPI_JEDEC_WRITE_STATUS = 0x01, /*WRSR */ - SPI_JEDEC_PAGE_PROGRAM = 0x02, /*PP */ - SPI_JEDEC_READ = 0x03, /*READ */ - SPI_JEDEC_WRITE_DISABLE = 0x04, /*WRDI */ - SPI_JEDEC_READ_STATUS = 0x05, /*RDSR */ - SPI_JEDEC_WRITE_ENABLE = 0x06, /*WREN */ - SPI_JEDEC_FAST_READ = 0x0B, /*FAST_READ */ - SPI_JEDEC_SECTOR_ERASE = 0x20, /*SE */ - SPI_JEDEC_READ_SFDP = 0x5A, /*RDSFDP */ - SPI_JEDEC_CHIPID = 0x9F, /*RDID */ - SPI_JEDEC_BLOCK_ERASE = 0xD8, /*BE */ - -} SpiConfigInfo; - -/** - * @brief General Constants related to flash - */ -enum -{ - PAGE_PROGRAM_BYTES = 256, /***< 256 bytes per PP command */ -}; - - -/** - * Common format of Status Register - */ -typedef union -{ - uint8_t data8; - struct - { - uint8_t writeProtect : 1; /*0 */ - uint8_t rsvd : 5; /*1:5 */ - uint8_t writeEnable : 1; /*6 */ - uint8_t writeInProgress : 1; /*7 */ - }; -} NorStatusReg_t; - -/** - * Flags used to trigger Hardware workarounds - */ -enum -{ - /* No workarounds present */ - HWWK_NO_WORKAROUNDS = 0x00000000, - - /* Must perform 'read flag status' commands after */ - /* any write or erase */ - HWWK_MICRON_WRT_ERASE = 0x00000001, - - /* Must do a read of a low flash address before issuing read */ - /* commands that return more than 1 word of data */ - HWWK_MICRON_EXT_READ = 0x00000002, -}; - - -/* - * Vendor-specific interfaces - */ - -/** - * @brief Check flag status bit on Micron NOR chips - * The current version of Micron parts require the Flag - * Status register be read after a read or erase operation, - * otherwise all future operations won't work.. - * - * @parm i_pnorMbox Pnor Mbox Struct to operate on - * - * @return Error from operation - */ -errorHndl_t micronFlagStatus( pnorMbox_t* i_pnorMbox ); - - - - -#endif diff --git a/src/occ_405/firdata/pnorData_common.h b/src/occ_405/firdata/pnorData_common.h deleted file mode 100644 index 3037e39..0000000 --- a/src/occ_405/firdata/pnorData_common.h +++ /dev/null @@ -1,162 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/pnorData_common.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __pnorData_common_h -#define __pnorData_common_h - -/** NOTE: This file is common between OCC and Hosboot. Any change to this file - * must be mirrored to both repositories. Also, this must be C, not C++, - * because OCC strictly uses C. */ - -#include <firDataConst_common.h> -#include <string.h> - -/** This file is used to define the format of the register data captured by the - * OCC and stored in PNOR. The data will be stored in the following format: - * - * - PNOR_Data_t struct - This has all of the information characterizing how - * many targets that have register data. - * - For each target with register data, the following format will be used: - * - PNOR_Trgt_t struct - Contains the target type, position, and how many - * registers are in the register list. - * - 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 - * of SCOM errors detected should be stored in each PNOR_Trgt_t struct. - * - If the value of a FIR (or ID FIR) is zero, do not capture the - * associated ACT0 and ACT1 registers. Note that the associated MASK - * register is still needed for FFDC. - * - Each target type may have associated global registers. If none exist, - * simply capture all registers for that type. However, if they do exist - * and the values of ALL the global registers are zero, skip capturing - * the associated registers of the target and any subsequent targets on - * the affinity path. Example, - * - For a MCBIST, skip this MCBIST and all associated MCSs, and MCAs. - * - If for some reason we run out of space in the PNOR, do not SCOM any - * more registers, set the 'full' bit in the PNOR_Data_t struct, and - * write all data successfully captured to PNOR. - */ - -typedef enum -{ - PNOR_FIR1 = 0x46495231, /** FIR data version 1 ("FIR1" in ascii) P8 */ - PNOR_FIR2 = 0x46495232, /** FIR data version 2 ("FIR2" in ascii) P9 */ - -} 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 */ - - 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; - -/** @return An initialized PNOR_Data_t struct. */ -static inline PNOR_Data_t PNOR_getData() -{ - PNOR_Data_t d; memset( &d, 0x00, sizeof(d) ); /* init to zero */ - - d.header = PNOR_FIR2; - - return d; -}; - -/** These values will match the corresponding bit fields in PNOR_Trgt_t. */ -typedef enum -{ - PNOR_Trgt_MAX_REGS_PER_TRGT = 511, /* Currently expect 266 on the PROC */ - PNOR_Trgt_MAX_ID_REGS_PER_TRGT = 15, /* Currently expect 9 on the MBA */ - PNOR_Trgt_MAX_SCOM_ERRORS = 255, /* Should be plenty */ - -} 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 trgtType : 6; /** Target type. See enum TrgtType_t */ - uint32_t reserved : 26; - -} PNOR_Trgt_t; - -/** @param i_trgtType Target type. See enum TrgtType_t. - * @param i_chipPos Parent chip position relative to the node. - * @param i_unitPos Unit position relative to the parent chip. - * @return An initialized PNOR_Data_t struct. - */ -static inline PNOR_Trgt_t PNOR_getTrgt( uint32_t i_trgtType, uint32_t i_chipPos, - uint32_t i_unitPos ) -{ - PNOR_Trgt_t t; memset( &t, 0x00, sizeof(t) ); /* init to zero */ - - t.trgtType = i_trgtType; - t.chipPos = i_chipPos; - t.unitPos = i_unitPos; - - return t; -}; - -/** Information for a normal register. */ -/* NOTE: This structure is 4-byte word aligned. */ -typedef struct __attribute__((packed)) -{ - uint32_t addr; /** 32-bit address */ - uint64_t val; /** 64-bit value */ - -} 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 */ - uint32_t val; /** 32-bit value */ - -} PNOR_IdReg_t; - -#endif // __pnorData_common_h - diff --git a/src/occ_405/firdata/pnor_mboxdd.c b/src/occ_405/firdata/pnor_mboxdd.c deleted file mode 100644 index 463e950..0000000 --- a/src/occ_405/firdata/pnor_mboxdd.c +++ /dev/null @@ -1,404 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/pnor_mboxdd.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/** - * @file ast_mboxdd.c - * - * @brief Implementation of the PNOR access code on top of AST MBOX protocol - */ - -/*****************************************************************************/ -// I n c l u d e s -/*****************************************************************************/ -#include <native.h> -#include <norflash.h> -#include <pnor_mboxdd.h> -#include <lpc.h> - -errorHndl_t hwInit(pnorMbox_t* i_pnorMbox) -{ - errorHndl_t l_err = NO_ERROR; - uint8_t* l_data; - int i; - do - { - //Current window starts closed - i_pnorMbox->iv_curWindowOpen = false; - i_pnorMbox->iv_mbox.iv_mboxMsgSeq = 1; - l_err = initializeMbox(); - if (l_err) - { - TRAC_ERR("initializeMbox failed rc:0x%x", l_err); - break; - } - - //Send message to BMC Mbox to get MBOX info - // This message gets the MBOX protocol version - mboxMessage_t l_getInfoMsg; - l_data = (uint8_t*)(&l_getInfoMsg); - for (i = 0; i < BMC_MBOX_DATA_REGS; i++) - { - l_data[i] = 0; - } - - l_getInfoMsg.iv_cmd = MBOX_C_GET_MBOX_INFO; - put8(&l_getInfoMsg, 0, 2); - l_err = doMessage(&i_pnorMbox->iv_mbox, &l_getInfoMsg); - if (l_err) - { - TRAC_ERR("doMessage to ping BMC failed with rc=0x%x", l_err); - break; - } - - i_pnorMbox->iv_protocolVersion = get8(&l_getInfoMsg, 0); - if (i_pnorMbox->iv_protocolVersion == 1) - { - i_pnorMbox->iv_blockShift = 12; - i_pnorMbox->iv_readWindowSize = get16(&l_getInfoMsg, 1) - << i_pnorMbox->iv_blockShift; - i_pnorMbox->iv_writeWindowSize = get16(&l_getInfoMsg, 3) - << i_pnorMbox->iv_blockShift; - } - else - { - i_pnorMbox->iv_blockShift = get8(&l_getInfoMsg, 5); - } - - //Now get the size of the flash - mboxMessage_t l_getSizeMsg; - l_getSizeMsg.iv_cmd = MBOX_C_GET_FLASH_INFO; - l_err = doMessage(&i_pnorMbox->iv_mbox, &l_getSizeMsg); - if (l_err) - { - TRAC_ERR("doMessage failed to get flash size rc=0x%x", l_err); - break; - } - - if (i_pnorMbox->iv_protocolVersion == 1) - { - i_pnorMbox->iv_flashSize = get32(&l_getSizeMsg, 0); - i_pnorMbox->iv_flashEraseSize = get32(&l_getSizeMsg, 4); - } - else - { - i_pnorMbox->iv_flashSize = get16(&l_getSizeMsg, 0) - << i_pnorMbox->iv_blockShift; - i_pnorMbox->iv_flashEraseSize = get16(&l_getSizeMsg, 2) - << i_pnorMbox->iv_blockShift; - } - } while (0); - return l_err; -} - - -errorHndl_t readFlash(pnorMbox_t* i_pnorMbox, - uint32_t i_addr, - size_t i_size, - void* o_data) -{ - errorHndl_t l_err = NO_ERROR; - - do - { - // Ensure we are operating on a 4-byte boundary - if ((i_size % 4 != 0) && (i_addr % 4 != 0)) - { - TRAC_ERR("readFlash: not on 4-byte boundary"); - return FAIL; - } - - while (i_size) - { - uint32_t l_lpcAddr; - size_t l_chunkLen; - - l_err = adjustMboxWindow(i_pnorMbox, - false, - i_addr, - i_size, - &l_lpcAddr, - &l_chunkLen); - - if (l_err) - { - break; - } - - //Directly access LPC to do read/write as BMC is setup now - l_err = lpc_read(LPC_TRANS_FW, l_lpcAddr, o_data, l_chunkLen); - - if (l_err) - { - break; - } - - i_addr += l_chunkLen; - i_size -= l_chunkLen; - o_data = (char*)o_data + l_chunkLen; - } - - if(l_err) - { - break; - } - - } - while(0); - - return l_err; -} - -errorHndl_t writeFlash(pnorMbox_t* i_pnorMbox, - uint32_t i_addr, - size_t i_size, - void* i_data) -{ - errorHndl_t l_err = NO_ERROR; - - do - { - // Ensure we are operating on a 4-byte boundary - if (i_size % 4 != 0) - { - TRAC_ERR("writeFlash: not on 4-byte boundary"); - return FAIL; - } - - - errorHndl_t l_flushErr = NO_ERROR; - - while (i_size) - { - uint32_t l_lpcAddr; - size_t l_chunkLen; - - l_err = adjustMboxWindow(i_pnorMbox, - true, - i_addr, - i_size, - &l_lpcAddr, - &l_chunkLen); - - if (l_err) - { - break; - } - - //Directly do LPC access to space pointed to by BMC - l_err = lpc_write(LPC_TRANS_FW, l_lpcAddr, i_data, l_chunkLen); - - if (l_err) - { - break; - } - - //Tell BMC to push data from LPC space into PNOR - l_err = writeDirty(i_pnorMbox, i_addr, l_chunkLen); - - if (l_err) - { - break; - } - - i_addr += l_chunkLen; - i_size -= l_chunkLen; - i_data = (char*)i_data + l_chunkLen; - } - - /* We flush whether we had an error or not. - * - * NOTE: It would help the daemon a lot if we moved that out of here - * and instead had a single flush call over a series of writes. - */ - l_flushErr = writeFlush(i_pnorMbox); - - if ( l_err == NO_ERROR && l_flushErr ) - { - l_err = l_flushErr; - } - - if( l_err ) - { - i_size = 0; - } - - if(l_err) - { - break; - } - - } - while(0); - - return l_err; -} - -errorHndl_t adjustMboxWindow(pnorMbox_t* i_pnorMbox, - bool i_isWrite, uint32_t i_reqAddr, - size_t i_reqSize, uint32_t *o_lpcAddr, - size_t *o_chunkLen) -{ - errorHndl_t l_err = NO_ERROR; - uint32_t l_pos, l_wSize, l_reqSize; - - do - { - /* - * Handle the case where the window is already opened, is of - * the right type and contains the requested address. - */ - uint32_t l_wEnd = i_pnorMbox->iv_curWindowOffset + - i_pnorMbox->iv_curWindowSize; - - /* A read request can be serviced by a write window */ - if (i_pnorMbox->iv_curWindowOpen && - (i_pnorMbox->iv_curWindowWrite || !i_isWrite) && - i_reqAddr >= i_pnorMbox->iv_curWindowOffset && i_reqAddr < l_wEnd) - { - size_t l_gap = (l_wEnd - i_reqAddr); - - *o_lpcAddr = i_pnorMbox->iv_curWindowLpcOffset + - (i_reqAddr - i_pnorMbox->iv_curWindowOffset); - if (i_reqSize <= l_gap) - { - *o_chunkLen = i_reqSize; - } - else - { - *o_chunkLen = l_gap; - } - return NO_ERROR; - } - - /* - * We need a window change, mark it closed first - */ - i_pnorMbox->iv_curWindowOpen = false; - - /* - * Then open the new one at the right position. The required - * alignment differs between protocol versions - */ - if (i_pnorMbox->iv_protocolVersion == 1) - { - l_wSize = i_isWrite ? i_pnorMbox->iv_writeWindowSize - : i_pnorMbox->iv_readWindowSize; - l_pos = i_reqAddr & ~(l_wSize - 1); - l_reqSize = 0; - } - else - { - uint32_t l_blockMask = (1u << i_pnorMbox->iv_blockShift) - 1; - l_wSize = 0; - l_pos = i_reqAddr & ~l_blockMask; - l_reqSize = (((i_reqAddr + i_reqSize) + l_blockMask) & ~l_blockMask) - - l_pos; - } - - mboxMessage_t winMsg; - if (i_isWrite) - { - winMsg.iv_cmd = MBOX_C_CREATE_WRITE_WINDOW; - } - else - { - winMsg.iv_cmd = MBOX_C_CREATE_READ_WINDOW; - } - - put16(&winMsg, 0, l_pos >> i_pnorMbox->iv_blockShift); - put16(&winMsg, 2, l_reqSize >> i_pnorMbox->iv_blockShift); - l_err = doMessage(&i_pnorMbox->iv_mbox, &winMsg); - - if (l_err) - { - break; - } - - i_pnorMbox->iv_curWindowLpcOffset = - (get16(&winMsg,0)) << i_pnorMbox->iv_blockShift; - - if (i_pnorMbox->iv_protocolVersion == 1) - { - i_pnorMbox->iv_curWindowOffset = l_pos; - i_pnorMbox->iv_curWindowLpcOffset = - (get16(&winMsg,0)) << i_pnorMbox->iv_blockShift; - i_pnorMbox->iv_curWindowSize = l_wSize; - } - else - { - i_pnorMbox->iv_curWindowLpcOffset = (get16(&winMsg,0)) - << i_pnorMbox->iv_blockShift; - i_pnorMbox->iv_curWindowSize = (get16(&winMsg,2)) - << i_pnorMbox->iv_blockShift; - i_pnorMbox->iv_curWindowOffset = (get16(&winMsg,4)) - << i_pnorMbox->iv_blockShift; - } - - i_pnorMbox->iv_curWindowOpen = true; - i_pnorMbox->iv_curWindowWrite = i_isWrite; - - } - while (true); - - return l_err; -} - -errorHndl_t writeDirty(pnorMbox_t* i_pnorMbox, uint32_t i_addr, size_t i_size) -{ - /* To pass a correct "size" for both protocol versions, we - * calculate the block-aligned start and end. - */ - uint32_t l_blockMask = (1u << i_pnorMbox->iv_blockShift) - 1; - uint32_t l_start = i_addr & ~l_blockMask; - uint32_t l_end = ((i_addr + i_size) + l_blockMask) & ~l_blockMask; - - mboxMessage_t dirtyMsg; - dirtyMsg.iv_cmd = MBOX_C_MARK_WRITE_DIRTY; - - if (i_pnorMbox->iv_protocolVersion == 1) - { - put16(&dirtyMsg, 0, i_addr >> i_pnorMbox->iv_blockShift); - put32(&dirtyMsg, 2, l_end - l_start); - } - else - { - put16(&dirtyMsg, 0, (i_addr - i_pnorMbox->iv_curWindowOffset) - >> i_pnorMbox->iv_blockShift); - put16(&dirtyMsg, 2, (l_end - l_start) >> i_pnorMbox->iv_blockShift); - } - - return doMessage(&i_pnorMbox->iv_mbox, &dirtyMsg); -} - -errorHndl_t writeFlush(pnorMbox_t* i_pnorMbox) -{ - mboxMessage_t flushMsg; - flushMsg.iv_cmd = MBOX_C_WRITE_FLUSH; - - put16(&flushMsg, 0, 0); - put32(&flushMsg, 2, 0); - - return doMessage(&i_pnorMbox->iv_mbox, &flushMsg); -} diff --git a/src/occ_405/firdata/pnor_mboxdd.h b/src/occ_405/firdata/pnor_mboxdd.h deleted file mode 100644 index ab8f05d..0000000 --- a/src/occ_405/firdata/pnor_mboxdd.h +++ /dev/null @@ -1,135 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/pnor_mboxdd.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#ifndef __PNOR_MBOX_H -#define __PNOR_MBOX_H - -//NOTE: Protocol Definition is here: -// https://github.com/openbmc/mboxbridge/blob/master/Documentation/mbox_protocol.md - -#include <ast_mboxdd.h> - -/** @file pnor_mbox.h - * @brief Provides the interfaces to the PNOR via the - * MBOX protocol - */ - -typedef struct -{ - astMbox_t iv_mbox; - uint32_t iv_protocolVersion; - //Block size is either 4k (V1) or BMC defined (V2) - // the iv_blockShift parm is a representation of that size - // as a power of 2. Most command and response args are specified - // in some multiple of block size - uint32_t iv_blockShift; - uint32_t iv_flashSize; - uint32_t iv_flashEraseSize; - // Current Window - bool iv_curWindowOpen; // Currently open - bool iv_curWindowWrite; // Write vs Read window - uint32_t iv_curWindowOffset; // Offset into flash - uint32_t iv_curWindowSize; // Size - uint32_t iv_curWindowLpcOffset; // Offset into LPC FW space - // Legacy v1 protocol - uint32_t iv_readWindowSize; - uint32_t iv_writeWindowSize; - -} pnorMbox_t; - -/* - * @brief Do base initialization of the MBOX functionality - * - * @parm[io] io_pnorMbox - Pointer to pnorMbox_t structure - * - * @return Error from operation - */ -errorHndl_t hwInit(pnorMbox_t* i_pnorMbox); - -/* - * @brief Read data from the PNOR flash - * - * @param[in] Pointer to pnorMbox struct - * @parm[in] i_addr PNOR flash Address to read - * @parm[in] i_size Amount of data to read, in bytes. - * @parm[out] o_data Buffer to read data into - * - * @return Error from operation - */ -errorHndl_t readFlash(pnorMbox_t* i_pnorMbox, - uint32_t i_addr, - size_t i_size, - void* o_data); - -/** - * @brief Write data to the PNOR flash - * @param[in] Pointer to pnorMbox struct - * @parm i_addr PNOR flash Address to write - * @parm i_size Amount of data to write, in bytes. - * @parm i_data Buffer containing data to write - * - * @return Error from operation - */ -errorHndl_t writeFlash(pnorMbox_t* i_pnorMbox, - uint32_t i_addr, - size_t i_size, - void* i_data); - -/** - * @brief Open a window on the BMC for PNOR accesses - * if necessary and return adjusted LPC address and chunk size - * @param[in] Pointer to pnorMbbox struct - * @parm[in] i_isWrite Write or read window - * @parm[in] i_reqAddr Requested flash offset - * @parm[in] i_reqSize Requested size - * @parm[out] o_lpcAddr LPC offset for the requested offset - * @parm[out] o_chunkLen i_reqSize adjusted to fit in the window - * - * @return Error from operation - */ -errorHndl_t adjustMboxWindow(pnorMbox_t* i_pnorMbox, - bool i_isWrite, - uint32_t i_reqAddr, - size_t i_reqSize, - uint32_t *o_lpcAddr, - size_t *o_chunkLen); - -/** - * @brief Mark a range dirty in a write window - * @param[in] Pointer to pnorMbox struct - * @parm[in] i_addr Flash offset of the range - * @parm[in] i_size Size of the range - * - * @return Error from operation - */ -errorHndl_t writeDirty(pnorMbox_t* i_pnorMbox, uint32_t i_addr, size_t i_size); - -/** -* @brief Flush all pending dirty data to the flash -* @param[in] Pointer to pnorMbox struct -* @return Error from operation -*/ -errorHndl_t writeFlush(pnorMbox_t* i_pnorMbox); - -#endif /* __PNOR_MBOX_H */ diff --git a/src/occ_405/firdata/pnor_util.c b/src/occ_405/firdata/pnor_util.c deleted file mode 100644 index 2c48179..0000000 --- a/src/occ_405/firdata/pnor_util.c +++ /dev/null @@ -1,220 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/pnor_util.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/* Interfaces to write into PNOR */ - -#include <native.h> -#include <pnor_mboxdd.h> -#include <pnor_util.h> -#include <norflash.h> - -/*================================================================= */ -/* The offset of the next byte to write */ -uint32_t g_next_byte = 0xFFFFFFFF; -/* Size of the FIRDATA section of PNOR */ -uint32_t g_pnor_size = 0; -/* Global PNOR Mbox object */ -pnorMbox_t* g_pnorMbox; - -/* Cache to queue up PNOR writes */ -uint8_t g_write_cache[PAGE_PROGRAM_BYTES]; -/* Current position of data inside write cache */ -size_t g_write_cache_index = 0; - -/** - * @brief Write 8 bytes of data into PNOR starting - */ -int32_t pnor_write_8B( uint64_t i_data ) -{ - int32_t rc = SUCCESS; - - if ( (g_next_byte == 0xFFFFFFFF) || /* initialized data */ - ((g_next_byte + g_pnor_size) < (g_next_byte + 9)) ) /* make sure there is room */ - { - TRACFCOMP("pnor_write_8B> g_next_byte=%.8X, g_pnor_size=%.8X",g_next_byte,g_pnor_size); - /* must have been some error in the prep */ - return FAIL; - } - -//@TODO: Do we need ECC, or does the BMC handle that for us now? - /* Create 9-byte ECC-ified version */ -// uint8_t data9[9]; -// injectECC( (uint8_t*)(&i_data), 8, data9 ); - - /* Copy data into the write cache until we queue up - a big chunk of data to write. This is more efficient - and avoids handling the write boundary of the PP - command internally. */ -// size_t cpsz = 9; - - uint8_t data8[8]; - size_t cpsz = 8; - - if( (g_write_cache_index + cpsz) > PAGE_PROGRAM_BYTES ) - { - cpsz = PAGE_PROGRAM_BYTES - g_write_cache_index; - } - memcpy( &(g_write_cache[g_write_cache_index]), data8, cpsz ); -// memcpy( &(g_write_cache[g_write_cache_index]), data9, cpsz ); - - g_write_cache_index += cpsz; - - /* Write a complete chunk into the flash */ - if( g_write_cache_index == PAGE_PROGRAM_BYTES ) - { - errorHndl_t tmp = writeFlash( g_pnorMbox, - g_next_byte, - PAGE_PROGRAM_BYTES, - g_write_cache ); - if ( NO_ERROR != tmp ) - { - TRACFCOMP("pnor_write_8B> writeFlash failed"); - /* hit an error, stop any more writes from happening */ - g_next_byte = 0xFFFFFFFF; - g_pnor_size = 0; - return FAIL; - } - g_next_byte += PAGE_PROGRAM_BYTES; - memset( g_write_cache, 0xFF, PAGE_PROGRAM_BYTES ); - g_write_cache_index = 0; - - if( (8 - cpsz) > 0 ) - { - memcpy( &(g_write_cache[0]), &(data8[cpsz]), 8 - cpsz ); - g_write_cache_index = 8 - cpsz; - } - - /* Handle the overflow */ -// if( (9 - cpsz) > 0 ) -// { -// memcpy( &(g_write_cache[0]), &(data9[cpsz]), 9 - cpsz ); -// g_write_cache_index = 9 - cpsz; -// } - } - - return rc; -} - - -/** - * @brief Perform any necessary operations to prepare - * the PNOR hw/code for writing - */ -errorHndl_t pnor_prep( HOMER_PnorInfo_t* i_pnorInfo ) -{ - errorHndl_t l_err = NO_ERROR; - - /* Figure out where to start */ - TRACFCOMP("FIRDATA is at %.8X..%.8X", i_pnorInfo->pnorOffset, i_pnorInfo->pnorOffset+i_pnorInfo->pnorSize ); - g_next_byte = i_pnorInfo->pnorOffset; - g_pnor_size = i_pnorInfo->pnorSize; - memset( g_write_cache, 0xFF, PAGE_PROGRAM_BYTES ); - - /* Can we rely on skiboot leaving things in a good state? */ - l_err = hwInit(g_pnorMbox); - if( l_err ) - { - TRACFCOMP("hwInit failed"); - /* hit an error, stop any writes from happening */ - g_next_byte = 0xFFFFFFFF; - g_pnor_size = 0; - } - - return l_err; -} - -/*------------------------------------------------------------------------------ */ - -int32_t PNOR_writeFirData( HOMER_PnorInfo_t i_pnorInfo, - uint8_t * i_buf, uint32_t i_bufSize ) -{ - int32_t rc = SUCCESS; - TRACFCOMP(">>PNOR_writeFirData"); - - do - { - /* Initialize the PNOR data. */ - errorHndl_t l_err = pnor_prep( &i_pnorInfo ); - if( l_err ) - { - TRACFCOMP("pnor_prep failed"); - rc = FAIL; - break; /*nothing more to do here*/ - } - - uint32_t idx = 0; - uint64_t dataChunk = 0; - size_t sz_dataChunk = sizeof(uint64_t); - - /* Add PNOR data 8 bytes at a time. */ - for ( idx = 0; idx < i_bufSize; idx += sz_dataChunk ) - { - memcpy( &dataChunk, &i_buf[idx], sz_dataChunk ); - - rc = pnor_write_8B( dataChunk ); - if ( SUCCESS != rc ) - { - TRACFCOMP( "pnor_write_8B() failed during FIR write" ); - break; - } - } - if ( SUCCESS != rc ) break; - - /* Add any extra bytes if they exist at the end of the buffer. */ - if ( idx != i_bufSize ) - { - uint32_t extraBytes = idx - i_bufSize; - - dataChunk = 0; - memcpy( &dataChunk, &i_buf[idx], extraBytes ); - - rc = pnor_write_8B( dataChunk ); - if ( SUCCESS != rc ) - { - TRACFCOMP( "pnor_write_8B() failed during blank fill" ); - break; - } - } - - /* Fill the rest of the page with good ECC */ - for ( idx = i_bufSize; - idx < i_pnorInfo.pnorSize; - idx += sz_dataChunk ) - { - dataChunk = 0xFFFFFFFFFFFFFFFFull; - rc = pnor_write_8B( dataChunk ); - if ( SUCCESS != rc ) - { - TRACFCOMP( "pnor_write_8B() failed during ECC fill" ); - break; - } - } - - } while (0); - - TRACFCOMP("<<PNOR_writeFirData"); - return rc; -} - diff --git a/src/occ_405/firdata/pnor_util.h b/src/occ_405/firdata/pnor_util.h deleted file mode 100644 index d8b5518..0000000 --- a/src/occ_405/firdata/pnor_util.h +++ /dev/null @@ -1,41 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/pnor_util.H $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __pnor_util_h -#define __pnor_util_h - -#include <homerData_common.h> - -/** - * @brief Writes a buffer containing the FIR data to PNOR (adding ECC). - * @param i_pnorInfo Information regarding PNOR location, size, etc. - * @param i_buf Data buffer (no ECC included). - * @param i_bufSize Size of the data buffer. - * @return Non-SUCCESS, if the write fails. SUCCESS, otherwise. - */ -int32_t PNOR_writeFirData( HOMER_PnorInfo_t i_pnorInfo, - uint8_t * i_buf, uint32_t i_bufSize ); - -#endif /* __pnor_util_h */ diff --git a/src/occ_405/firdata/sbe_fifo.c b/src/occ_405/firdata/sbe_fifo.c deleted file mode 100644 index 9a2099a..0000000 --- a/src/occ_405/firdata/sbe_fifo.c +++ /dev/null @@ -1,444 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/sbe_fifo.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#include "sbe_fifo.h" -#include <trac.h> -#include <fsi.h> -#include <native.h> - -/** @brief Waits for FIFO to be ready to be written to - * @param i_target The SCOM target. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -uint32_t waitUpFifoReady(SCOM_Trgt_t* i_target) -{ - uint32_t l_rc = SUCCESS; - - uint64_t l_elapsed_time_ns = 0; - uint32_t l_addr = SBE_FIFO_UPFIFO_STATUS; - uint32_t l_data = 0; - - do - { - //Read upstream status to see if there is room for more data - l_rc = getfsi(*i_target, l_addr, &l_data); - if(l_rc != SUCCESS) - { - TRAC_ERR("waitUpFifoReady: failed to getfsi from addr 0x%08x", - l_addr); - break; - } - - if(!(l_data & UPFIFO_STATUS_FIFO_FULL)) - { - break; - } - - //Check for timeout - if(l_elapsed_time_ns >= MAX_UP_FIFO_TIMEOUT_NS) - { - l_rc = FAIL; - TRAC_ERR("waitUpFifoReady: timeout occurred while waiting for" - " FIFO to clear"); - break; - } - - sleep(10000); //sleep for 10,000 ns - l_elapsed_time_ns += 10000; - }while(TRUE); - - return l_rc; -} - -/** @brief Waits for information to show up in FIFO - * @param i_target The SCOM target. - * @param o_status the status of the FIFO - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -uint32_t waitDnFifoReady(SCOM_Trgt_t* i_target, uint32_t* o_status) -{ - uint32_t l_rc = SUCCESS; - - uint64_t l_elapsed_time_ns = 0; - uint32_t l_addr = SBE_FIFO_DNFIFO_STATUS; - - do - { - // read dnstream status to see if data ready to be read - // or if has hit the EOT - l_rc = getfsi(*i_target, l_addr, o_status); - if(l_rc != SUCCESS) - { - return l_rc; - } - - if(!(*o_status & DNFIFO_STATUS_FIFO_EMPTY) || - (*o_status & DNFIFO_STATUS_DEQUEUED_EOT_FLAG)) - { - break; - } - else - { - TRAC_IMP("SBE status reg returned fifo empty or dequeued eot flag 0x%.8X", - *o_status); - } - - // Check for timeout - if(l_elapsed_time_ns >= MAX_UP_FIFO_TIMEOUT_NS) - { - TRAC_ERR("waitDnFifoReady: timeout waiting for downstream FIFO" - " to be empty."); - l_rc = FAIL; - break; - } - - sleep(10000); // wait for 10,000 ns - l_elapsed_time_ns += 10000; - - }while(TRUE); - - return l_rc; -} - -/** @brief Writes a request to FIFO - * @param i_target The SCOM target. - * @param i_fifoRequest the request to execute. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -uint32_t writeRequest(SCOM_Trgt_t* i_target, uint32_t* i_fifoRequest) -{ - uint32_t l_rc = SUCCESS; - - TRAC_IMP("Enter writeRequest"); - - // Ensure Downstream Max Transfer Counter is 0 non-0 can cause - // protocol issues) - uint32_t l_addr = SBE_FIFO_DNFIFO_MAX_TSFR; - uint32_t l_data = 0; - l_rc = putfsi(*i_target, l_addr, l_data); - if(l_rc != SUCCESS) - { - TRAC_ERR("writeRequest: failed to putfsi to addr 0x%08x", - l_addr); - return l_rc; - } - - //The first uint32_t has the number of uint32_t words in the request - l_addr = SBE_FIFO_UPFIFO_DATA_IN; - uint32_t* l_sent = i_fifoRequest; //This pointer will advance as words are sent - uint32_t l_count = *l_sent; - uint32_t i; - - for(i = 0; i < l_count; ++i) - { - //Wait for room to write into fifo - l_rc = waitUpFifoReady(i_target); - if(l_rc != SUCCESS) - { - return l_rc; - } - - //Send data into fifo - l_rc = putfsi(*i_target, l_addr, *l_sent); - if(l_rc != SUCCESS) - { - TRAC_ERR("writeRequest: failed to putfsi to addr 0x%08x", - l_addr); - return l_rc; - } - - l_sent++; - } - - //Notify SBE that last word has been sent - l_rc = waitUpFifoReady(i_target); - if(l_rc != SUCCESS) - { - return l_rc; - } - - l_addr = SBE_FIFO_UPFIFO_SIG_EOT; - l_data = FSB_UPFIFO_SIG_EOT; - l_rc = putfsi(*i_target, l_addr, l_data); - if(l_rc != SUCCESS) - { - TRAC_ERR("writeRequest: failed to putfsi to addr 0x%08x", l_addr); - } - - TRAC_IMP("Exit writeRequest"); - - return l_rc; -} - -/** @brief Reads and processes the FIFO response - * @param i_target The SCOM target. - * @param i_fifoRequest the original FIFO request. - * @param o_fifoResponse the FIFO response. - * @param i_responseSize the expected size of the response. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -uint32_t readResponse(SCOM_Trgt_t* i_target, - uint32_t* i_fifoRequest, - uint32_t* o_fifoResponse, - uint32_t i_responseSize) -{ - uint32_t l_rc = SUCCESS; - uint32_t l_readBuffer[READ_BUFFER_SIZE]; - - TRAC_IMP("Enter readResponse"); - - // EOT is expected before the response buffer is full. Room for - // the PCBPIB status or FFDC is included, but is only returned - // if there is an error. The last received word has the distance - // to the status, which is placed at the end of the returned data - // in order to reflect errors during transfer. - - uint32_t* l_received = o_fifoResponse; // advance as words are received - uint32_t l_maxWords = i_responseSize / sizeof(uint32_t); - uint32_t l_wordsReceived = 0; // Used to validata the "distance" to status - bool l_eotReceived = FALSE; - uint32_t l_lastWord = 0; // Last word received. Final read is the "distance" - // in words to the status header. - bool l_overRun = FALSE; - - do - { - // Wait for data to be ready to receive (download) or if the EOT - // has been sent. If not EOT, then data ready to receive. - uint32_t l_status = 0; - l_rc = waitDnFifoReady(i_target, &l_status); - if(l_rc != SUCCESS) - { - return l_rc; - } - - if(l_status & DNFIFO_STATUS_DEQUEUED_EOT_FLAG) - { - l_eotReceived = TRUE; - // Ignore EOT dummy word - if(l_wordsReceived >= (sizeof(struct statusHeader) / sizeof(uint32_t))) - { - if(l_overRun == FALSE) - { - l_received--; - l_wordsReceived--; - l_lastWord = o_fifoResponse[l_wordsReceived-1]; - } - else - { - l_lastWord = l_readBuffer[l_wordsReceived-2]; - } - } - break; - } - - // When error occurs, SBE will write more than l_maxWords - // we have to keep reading 1 word at a time until we get EOT - // or more than READ_BUFFER_SIZE. Save what we read in the buffer - if(l_wordsReceived >= l_maxWords) - { - l_overRun = TRUE; - } - - // Read next word - l_rc = getfsi(*i_target, SBE_FIFO_DNFIFO_DATA_OUT, &l_lastWord); - if(l_rc != SUCCESS) - { - return l_rc; - } - - l_readBuffer[l_wordsReceived] = l_lastWord; - - if(l_overRun == FALSE) - { - *l_received = l_lastWord; // Copy to returned output buffer - l_received++; // Advance to the next position - } - l_wordsReceived++; - - if(l_wordsReceived > READ_BUFFER_SIZE) - { - TRAC_ERR("readResponse: data overflow without EOT"); - l_rc = FAIL; - return l_rc; - } - - }while(TRUE); - - // At this point, l_wordsReceived of words received. - // l_received points to 1 word past last word received. - // l_lastWord has last word received, which is "distance" to status - // EOT is expected before running out of response buffer - if(!l_eotReceived) - { - l_rc = FAIL; - TRAC_ERR("readResponse: no EOT cmd = 0x%08x size = %d", - i_fifoRequest[1], i_responseSize); - return l_rc; - } - - // Notify SBE that EOT has been received - uint32_t l_eotSig = FSB_UPFIFO_SIG_EOT; - l_rc = putfsi(*i_target, SBE_FIFO_DNFIFO_ACK_EOT, l_eotSig); - if(l_rc != SUCCESS) - { - return l_rc; - } - - // Determine if transmission is successful. - // Last word received has the distance to status in words including itself. - // l_wordsReceived has number of words received. - // Need to have received at least status header and distance word. - if((l_lastWord < (sizeof(struct statusHeader)/sizeof(uint32_t) + 1)) || - (l_wordsReceived < (sizeof(struct statusHeader)/sizeof(uint32_t) + 1)) || - (l_lastWord > l_wordsReceived)) - { - TRAC_ERR("readResponse: invalid status distance. Cmd = 0x%08x distance" - " = %d allocated response size = %d received word size = %d", - i_fifoRequest[1], l_lastWord, i_responseSize, l_wordsReceived); - l_rc = FAIL; - return l_rc; - } - - // Check status for success. - // l_received points one word past last word received. - // l_lastWord has number of words to status header including self. - uint32_t* l_statusTmp = (l_overRun == FALSE) ? (l_received - l_lastWord) : - &l_readBuffer[l_wordsReceived - 1]; - struct statusHeader* l_statusHeader = (struct statusHeader*)l_statusTmp; - if((FIFO_STATUS_MAGIC != l_statusHeader->magic) || - (SBE_PRI_OPERATION_SUCCESSFUL != l_statusHeader->primaryStatus) || - (SBE_SEC_OPERATION_SUCCESSFUL != l_statusHeader->secondaryStatus)) - { - TRAC_ERR("readResponse: failing downstream status cmd = 0x%08x magic = " - "0x%08x primary status = 0x%08x secondary status = 0x%08x", - i_fifoRequest[1], - l_statusHeader->magic, - l_statusHeader->primaryStatus, - l_statusHeader->secondaryStatus); - - l_rc = FAIL; - } - - TRAC_IMP("Exit readResponse"); - return l_rc; -} - -/** @brief Performs a FIFO operation (read or write) - * @param i_target The SCOM target. - * @param i_fifoRequest the FIFO request data structure - * @param i_fifoResponse the response from SBE - * @param i_responseSize the size of the response - * @return Non-SUCCESS if the operation fails. SUCCESS otherwise. - */ -uint32_t performFifoChipOp(SCOM_Trgt_t* i_target, - uint32_t* i_fifoRequest, - uint32_t* i_fifoResponse, - uint32_t i_responseSize) -{ - uint32_t l_rc = SUCCESS; - - TRAC_IMP("Enter performFifoChipOp"); - - l_rc = writeRequest(i_target, i_fifoRequest); - if(l_rc != SUCCESS) - { - return l_rc; - } - - l_rc = readResponse(i_target, - i_fifoRequest, - i_fifoResponse, - i_responseSize); - - TRAC_IMP("Exit performFifoChioOp"); - - return l_rc; -} - -/** @brief Performs a write SCOM operation using SBE FIFO - * @param i_target The SCOM target. - * @param i_addr 64-bit SCOM address. - * @param i_data 64-bit data to write. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -int32_t putFifoScom(SCOM_Trgt_t* i_target, uint64_t i_addr, uint64_t i_data) -{ - uint32_t l_rc = SUCCESS; - - TRAC_IMP("Enter putFifoScom"); - - struct fifoPutScomRequest l_fifoRequest; - struct fifoPutScomResponse l_fifoResponse; - - l_fifoRequest.wordCnt = PUT_SCOM_REQUEST_WORD_CNT; - l_fifoRequest.reserved = 0; - l_fifoRequest.commandClass = SBE_FIFO_CLASS_SCOM_ACCESS; - l_fifoRequest.command = SBE_FIFO_CMD_PUT_SCOM; - l_fifoRequest.address = i_addr; - l_fifoRequest.data = i_data; - - l_rc = performFifoChipOp(i_target, - (uint32_t*)&l_fifoRequest, - (uint32_t*)&l_fifoResponse, - sizeof(struct fifoPutScomResponse)); - - TRAC_IMP("Exit putFifoScom"); - - return l_rc; -} - -/** @brief Performs a read SCOM operation using SBE FIFO - * @param i_target The SCOM target. - * @param i_addr 64-bit SCOM address. - * @param o_data 64-bit returned value. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -int32_t getFifoScom(SCOM_Trgt_t* i_target, uint64_t i_addr, uint64_t* o_data) -{ - uint32_t l_rc = SUCCESS; - - TRAC_IMP("Enter getFifoScom"); - - struct fifoGetScomRequest l_fifoRequest; - struct fifoGetScomResponse l_fifoResponse; - - l_fifoRequest.wordCnt = GET_SCOM_REQUEST_WORD_CNT; - l_fifoRequest.reserved = 0; - l_fifoRequest.commandClass = SBE_FIFO_CLASS_SCOM_ACCESS; - l_fifoRequest.command = SBE_FIFO_CMD_GET_SCOM; - l_fifoRequest.address = i_addr; - - l_rc = performFifoChipOp(i_target, - (uint32_t*)&l_fifoRequest, - (uint32_t*)&l_fifoResponse, - sizeof(struct fifoGetScomResponse)); - - //Always return data even if there is an error - *o_data = l_fifoResponse.data; - - TRAC_IMP("Exit getFifoScom"); - - return l_rc; -} diff --git a/src/occ_405/firdata/sbe_fifo.h b/src/occ_405/firdata/sbe_fifo.h deleted file mode 100644 index 4194471..0000000 --- a/src/occ_405/firdata/sbe_fifo.h +++ /dev/null @@ -1,123 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/sbe_fifo.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#ifndef __SBE_FIFO_H -#define __SBE_FIFO_H - -#include <scom_trgt.h> -#include <stdint.h> - -#define PACKED __attribute__((__packed__)) - -#define PUT_SCOM_REQUEST_WORD_CNT 0x06 -#define GET_SCOM_REQUEST_WORD_CNT 0x04 - -#define SBE_FIFO_CMD_GET_SCOM 0x01 -#define SBE_FIFO_CMD_PUT_SCOM 0x02 -#define SBE_FIFO_CLASS_SCOM_ACCESS 0xA2 -#define SBE_FIFO_DNFIFO_MAX_TSFR 0x00002458 -#define SBE_FIFO_UPFIFO_DATA_IN 0x00002400 -#define SBE_FIFO_UPFIFO_SIG_EOT 0x00002408 -#define FSB_UPFIFO_SIG_EOT 0x80000000 -#define SBE_FIFO_UPFIFO_STATUS 0x00002404 -#define SBE_FIFO_DNFIFO_STATUS 0x00002444 -#define UPFIFO_STATUS_FIFO_FULL 0x00200000 -#define DNFIFO_STATUS_FIFO_EMPTY 0x00100000 -#define DNFIFO_STATUS_DEQUEUED_EOT_FLAG 0x00800000 -#define SBE_FIFO_DNFIFO_ACK_EOT 0x00002454 -#define SBE_FIFO_DNFIFO_DATA_OUT 0x00002440 -#define NS_PER_MSEC (1000000ull) -#define MAX_UP_FIFO_TIMEOUT_NS 10*NS_PER_MSEC -#define READ_BUFFER_SIZE 2048 -#define FIFO_STATUS_MAGIC 0xC0DE -#define SBE_PRI_OPERATION_SUCCESSFUL 0x00 -#define SBE_SEC_OPERATION_SUCCESSFUL 0x00 - -struct statusHeader -{ - uint16_t magic; //set to 0xC0DE - uint8_t commandClass; - uint8_t command; - uint16_t primaryStatus; - uint16_t secondaryStatus; -} PACKED; - -struct ffdc_struct -{ - const void* ptr; - size_t size; -}; - -struct fifoPutScomRequest -{ - uint32_t wordCnt; - uint16_t reserved; - uint8_t commandClass; - uint8_t command; - uint64_t address; - uint64_t data; -} PACKED; - -struct fifoPutScomResponse -{ - struct statusHeader status; - struct ffdc_struct ffdc; //ffdc data - uint32_t status_distance; //distance to status -} PACKED; - -struct fifoGetScomRequest -{ - uint32_t wordCnt; - uint16_t reserved; - uint8_t commandClass; - uint8_t command; - uint64_t address; -} PACKED; - -struct fifoGetScomResponse -{ - uint64_t data; //Data (0..31) + (32..63) - struct statusHeader status; - struct ffdc_struct ffdc; //ffdc data - uint32_t status_distance; // distance to status -} PACKED; - -/** @brief Performs a write SCOM operation using SBE FIFO - * @param i_target The SCOM target. - * @param i_addr 64-bit SCOM address. - * @param i_data 64-bit data to write. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -int32_t putFifoScom(SCOM_Trgt_t* i_target, uint64_t i_addr, uint64_t i_data); - -/** @brief Performs a read SCOM operation using SBE FIFO - * @param i_target The SCOM target. - * @param i_addr 64-bit SCOM address. - * @param o_data 64-bit returned value. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -int32_t getFifoScom(SCOM_Trgt_t* i_target, uint64_t i_addr, uint64_t* o_data); - -#endif - diff --git a/src/occ_405/firdata/scom_addr_util.c b/src/occ_405/firdata/scom_addr_util.c deleted file mode 100644 index a59a5a7..0000000 --- a/src/occ_405/firdata/scom_addr_util.c +++ /dev/null @@ -1,82 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/scom_addr_util.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#include "scom_addr_util.h" - - -void set_sat_id(const uint8_t i_sat_id, uint64_t * o_addr) -{ - *o_addr &= 0xFFFFFFFFFFFFFC3FULL; - *o_addr |= ((i_sat_id & 0xF) << 6); -} - -void set_chiplet_id(const uint8_t i_chiplet_id, uint64_t * o_addr) -{ - *o_addr &= 0xFFFFFFFFC0FFFFFFULL; - *o_addr |= ((i_chiplet_id & 0x3F) << 24); -} - -void set_ring(const uint8_t i_ring, uint64_t * o_addr) -{ - *o_addr &= 0xFFFFFFFFFFFF03FFULL; - *o_addr |= ((i_ring & 0x3F) << 10); -} - -void set_sat_offset(const uint8_t i_sat_offset, uint64_t * o_addr) -{ - *o_addr &= 0xFFFFFFFFFFFFFFC0ULL; - *o_addr |= (i_sat_offset & 0x3F); -} - -void set_rxtx_group_id(const uint8_t i_grp_id, uint64_t * o_addr) -{ - *o_addr &= 0xFFFFF81FFFFFFFFFULL; - *o_addr |= (i_grp_id & 0x3FULL) << 37; -} - -uint8_t get_sat_id(const uint64_t i_addr) -{ - return ((i_addr >> 6) & 0xF); -} - -uint8_t get_chiplet_id(const uint64_t i_addr) -{ - return ((i_addr >> 24) & 0x3F); -} - -uint8_t get_ring(const uint64_t i_addr) -{ - return ((i_addr >> 10) & 0x3F); -} - -uint8_t get_sat_offset(const uint64_t i_addr) -{ - return (i_addr & 0x3F); -} - -uint8_t get_rxtx_group_id(const uint64_t i_addr) -{ - return (i_addr >> 37) & 0x3F; -} - diff --git a/src/occ_405/firdata/scom_addr_util.h b/src/occ_405/firdata/scom_addr_util.h deleted file mode 100644 index 51988b4..0000000 --- a/src/occ_405/firdata/scom_addr_util.h +++ /dev/null @@ -1,81 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/scom_addr_util.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ -#ifndef __scom_addr_util_h -#define __scom_addr_util_h - -#include <stdint.h> - -//This file is a result of de-classing the p9_scom_addr that currently -//lives in EKB: chips/p9/common/scominfo/p9_scom_addr.H - -// @brief Modify SCOM address, update satellite ID field -// @param[in] i_sat_id Satellite ID value to write -// @retval none -// -void set_sat_id(const uint8_t i_sat_id, uint64_t * o_addr); - -// @brief Modify SCOM address, update pervasive chiplet ID -// @param[in] i_chiplet_id Chiplet ID value to write -// @retval none -// -void set_chiplet_id(const uint8_t i_chiplet_id, uint64_t * o_addr); - -// @brief Modify SCOM address, update ring field value -// @param[in] i_ring Ring field value to write -// @retval none -void set_ring(const uint8_t i_ring, uint64_t * o_addr); - -// @brief Modify SCOM address, update satellite offset field -// @param[in] i_sat_offset Satellite offset value to write -// @retval none -void set_sat_offset(const uint8_t i_sat_offset, uint64_t * o_addr); - -// @brief Modify SCOM address, update the RX or TX Group ID -// @param[in] i_grp_id Group id to set -// @retval none -void set_rxtx_group_id(const uint8_t i_grp_id, uint64_t * o_addr); - -// @brief Extract satellite ID field from SCOM address -// @retval uint8_t Satellite ID field value -uint8_t get_sat_id(const uint64_t i_addr); - -// @brief Extract pervasive chiplet ID from SCOM address -// @retval uint8_t Pervasive chiplet ID value -uint8_t get_chiplet_id(const uint64_t i_addr); - -// @brief Extract ring field from SCOM address -// @retval uint8_t Ring field value -uint8_t get_ring(const uint64_t i_addr); - -// @brief Extract satellite register offset field from SCOM address -// @retval uint8_t Satellite register offset field value -uint8_t get_sat_offset(const uint64_t i_addr); - -// @brief Extract the RX or TX Group ID of an indirect scom address -// @retval uint8_t Satellite register offset field value -uint8_t get_rxtx_group_id(const uint64_t i_addr); - - -#endif diff --git a/src/occ_405/firdata/scom_trgt.c b/src/occ_405/firdata/scom_trgt.c deleted file mode 100644 index 15ad3fc..0000000 --- a/src/occ_405/firdata/scom_trgt.c +++ /dev/null @@ -1,180 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/scom_trgt.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#include <native.h> -#include <scom_trgt.h> -#include <scom_util.h> - -/*------------------------------------------------------------------------------ */ - -SCOM_Trgt_t SCOM_Trgt_getTrgt( TrgtType_t i_type, uint8_t i_procPos, - uint8_t i_procUnitPos, uint32_t i_fsiBaseAddr, - bool i_isMaster ) -{ - SCOM_Trgt_t trgt = { - .type = i_type, - .procPos = i_procPos, - .procUnitPos = i_procUnitPos, - .isMaster = i_isMaster, - .fsiBaseAddr = i_fsiBaseAddr, - }; - - if (TRGT_PROC == trgt.type) - { - trgt.procUnitPos = 0; - } - - if ( TRGT_MEMBUF == trgt.type || TRGT_MBA == trgt.type ) - { - trgt.isMaster = false; - } - - return trgt; -} - -/*------------------------------------------------------------------------------ */ - -uint8_t SCOM_Trgt_getChipPos( SCOM_Trgt_t i_trgt ) -{ - uint32_t p = 0; - - switch ( i_trgt.type ) - { - case TRGT_PROC: - case TRGT_CAPP: - case TRGT_XBUS: - case TRGT_OBUS: - case TRGT_PEC: - case TRGT_PHB: - case TRGT_EQ: - case TRGT_EX: - case TRGT_EC: - case TRGT_MCBIST: - case TRGT_MCS: - case TRGT_MCA: - p = i_trgt.procPos; - break; - - case TRGT_MEMBUF: /* TODO RTC 173614 -- with CUMULUS */ - p = (i_trgt.procPos * MAX_MEMBUF_PER_PROC) + i_trgt.procUnitPos; - break; - - case TRGT_MBA: /* TODO RTC 173614 -- with CUMULUS */ - p = (i_trgt.procPos * MAX_MEMBUF_PER_PROC) + - (i_trgt.procUnitPos / MAX_MBA_PER_MEMBUF); - break; - - default: ; - } - - return p; -} - -/*------------------------------------------------------------------------------ */ - -uint8_t SCOM_Trgt_getChipUnitPos( SCOM_Trgt_t i_trgt ) -{ - uint32_t u = 0; - - switch ( i_trgt.type ) - { - case TRGT_PROC: - case TRGT_MEMBUF: u = 0; break; - - case TRGT_CAPP: - case TRGT_XBUS: - case TRGT_OBUS: - case TRGT_PEC: - case TRGT_PHB: - case TRGT_EQ: - case TRGT_EX: - case TRGT_EC: - case TRGT_MCBIST: - case TRGT_MCS: - case TRGT_MCA: u = i_trgt.procUnitPos; break; - - case TRGT_MBA: u = i_trgt.procUnitPos % MAX_MBA_PER_MEMBUF; break; - /* TODO RTC 173614 -- with CUMULUS */ - - default: ; - } - - return u; -} - -/*------------------------------------------------------------------------------ */ - -SCOM_Trgt_t SCOM_Trgt_getParentChip( SCOM_Trgt_t i_trgt ) -{ - TrgtType_t t = TRGT_MAX; - switch ( i_trgt.type ) - { - case TRGT_PROC: - case TRGT_CAPP: - case TRGT_XBUS: - case TRGT_OBUS: - case TRGT_PEC: - case TRGT_PHB: - case TRGT_EQ: - case TRGT_EX: - case TRGT_EC: - case TRGT_MCBIST: - case TRGT_MCS: - case TRGT_MCA: t = TRGT_PROC; break; - - case TRGT_MEMBUF: - case TRGT_MBA: t = TRGT_MEMBUF; break; - - default: ; - } - - uint8_t u = 0; - switch ( i_trgt.type ) - { - case TRGT_PROC: - case TRGT_CAPP: - case TRGT_XBUS: - case TRGT_OBUS: - case TRGT_PEC: - case TRGT_PHB: - case TRGT_EQ: - case TRGT_EX: - case TRGT_EC: - case TRGT_MCBIST: - case TRGT_MCS: - case TRGT_MCA: - case TRGT_MEMBUF: u = i_trgt.procUnitPos; break; - /* TODO RTC 173614 -- with CUMULUS */ - - case TRGT_MBA: u = i_trgt.procUnitPos / MAX_MBA_PER_MEMBUF; break; - /* TODO RTC 173614 -- with CUMULUS */ - - default: ; - } - - return SCOM_Trgt_getTrgt( t, i_trgt.procPos, u, i_trgt.fsiBaseAddr, - i_trgt.isMaster ); -} - diff --git a/src/occ_405/firdata/scom_trgt.h b/src/occ_405/firdata/scom_trgt.h deleted file mode 100644 index 4ffe8b5..0000000 --- a/src/occ_405/firdata/scom_trgt.h +++ /dev/null @@ -1,89 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ/firdata/scom.H $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -#ifndef __scom_trgt_h -#define __scom_trgt_h - -#include <firDataConst_common.h> -#include <native.h> - -typedef struct -{ - /** See enum TrgtType_t. NOTE: This value is not consistant with Hostboot - * target types. */ - TrgtType_t type; - - /** Absolute position of the connected PROC within the node. This value - * should be consistant with the Hostboot target positions. */ - uint8_t procPos; - - /** Unit position relative to the connected PROC. This value should be - * consistant with the Hostboot target positions. */ - uint8_t procUnitPos; - - /** Indicates this target is, or is connected to, the master processor. */ - bool isMaster; - - /** This target's FSI base address. */ - uint32_t fsiBaseAddr; - -} SCOM_Trgt_t; - -/** @param i_type See enum Type. - * @param i_procPos Absolute position within the node of the connected - * PROC target. - * @param i_procUnitPos Unit position relative to the connected PROC. Will be - * explicitly set to 0 for PROC targets. - * @param i_fsiBaseAddr For EX and MCS, the FSI base address for the - * connected PROC. For MEMB and MBA, the FSI base - * address for the connected MEMB. - * @param i_isMaster True, if this target is, or is connected to, the - * master processor. False, otherwise. Will be explicitly - * set to false for MEMB and MBA targets. - * @return A SCOM_Trgt_t struct. - */ -SCOM_Trgt_t SCOM_Trgt_getTrgt( TrgtType_t i_type, uint8_t i_procPos, - uint8_t i_procUnitPos, uint32_t i_fsiBaseAddr, - bool i_isMaster ); - -/** @param i_trgt The SCOM target. - * @return This target's absolute position of the parent chip (PROC or - * MEMB) within the node. - */ -uint8_t SCOM_Trgt_getChipPos( SCOM_Trgt_t i_trgt ); - -/** @param i_trgt The SCOM target. - * @return This target's unit position relative to the parent chip. Only - * valid for EX, MCS, and MBA units. Will return 0 for PROC and - * MEMB chips. - */ -uint8_t SCOM_Trgt_getChipUnitPos( SCOM_Trgt_t i_trgt ); - -/** @param i_trgt The SCOM target. - * @return A target for the containing parent chip (PROC or MEMB). - */ -SCOM_Trgt_t SCOM_Trgt_getParentChip( SCOM_Trgt_t i_trgt ); - -#endif /* __scom_trgt_h */ diff --git a/src/occ_405/firdata/scom_util.c b/src/occ_405/firdata/scom_util.c deleted file mode 100644 index 7709017..0000000 --- a/src/occ_405/firdata/scom_util.c +++ /dev/null @@ -1,607 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/scom_util.c $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/* Support for SCOM operations */ -#include <fsi.h> -#include <native.h> -#include <occhw_async.h> -#include "occ_common.h" -#include "gpe_export.h" -#include <scom_util.h> -#include "scom_addr_util.h" -#include <sbe_fifo.h> - -bool G_request_created = FALSE; -GPE_BUFFER(ipc_scom_op_t G_scom_op); -GpeRequest G_request; - -enum { - /*FSI addresses are byte offsets, so need to multiply by 4 - since each register is 4 bytes long. - prefix with 0x10xx for FSI2PIB engine offset */ - DATA0_REG = 0x1000, /* SCOM Data Register 0 (0x00) */ - DATA1_REG = 0x1004, /* SCOM Data Register 1 (0x01) */ - COMMAND_REG = 0x1008, /* SCOM Command Register (0x02) */ - ENGINE_RESET_REG = 0x1018, /* Engine Reset Register (0x06) */ - STATUS_REG = 0x101C, /* STATUS Register (0x07) */ - PIB_RESET_REG = 0x101C, /* PIB Reset Register (0x07) */ - - PIB_ABORT_BIT = 0x00100000, /* 12= PIB Abort */ - PIB_ERROR_BITS = 0x00007000, /* 17:19= PCB/PIB Errors */ -}; - -/** - * @brief Indirect SCOM Status - */ -typedef union -{ - uint64_t data64; - struct - { - uint64_t :12; /*0:11*/ - uint64_t addr:20; /*12:31*/ - uint64_t done:1; /*32*/ - uint64_t piberr:3; /*33:35*/ - uint64_t userstat:4; /*36:39*/ - uint64_t :8; /*40:47*/ - uint64_t data:16; /*48:63*/ - }; -} IndirectScom_t; - -enum { - MCS_MASK = 0xFFFFFFFF7FFFFF80, - MCS_BASEADDR = 0x0000000002011800, - MCS_DMI_BASEADDR = 0x0000000002011A00, - IND_MCS_BASEADDR = 0x8000006002011A00, - IND_MCS_DMI_BASEADDR = 0x8000006002011A3F, - MBA_MASK = 0xFFFFFFFF7FFFFC00, - MBA_BASEADDR = 0x0000000003010400, - TCM_MBA_BASEADDR = 0x0000000003010800, - IND_MBA_BASEADDR = 0x800000000301143f, -}; - -/** - * @brief Translates a relative unit address to a real physical address - * @param i_trgt Chip/unit to SCOM. - * @param i_addr Address to SCOM (the unit's 0th address for unit SCOMs). - * @param o_addr Return address. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t translate_addr( SCOM_Trgt_t i_trgt, uint64_t i_addr, uint64_t * o_addr ) -{ - #define FUNC "[translate_addr] " - - int32_t rc = SUCCESS; - uint8_t l_chip_unit_num = SCOM_Trgt_getChipUnitPos(i_trgt); - - *o_addr = i_addr; - - //The following translation logic is a copy of p9_scominfo_createChipUnitScomAddr - //function from EKB (chips/p9/common/scominfo/p9_scominfo.C) - - if(i_trgt.type == TRGT_PROC || i_trgt.type == TRGT_MEMBUF) - { - //No need to translate here. - //We already assigned i_addr to o_addr above, so just return SUCCESS. - return rc; - } - else if(i_trgt.type == TRGT_CAPP) //CAPP - { - set_chiplet_id(N0_CHIPLET_ID + (l_chip_unit_num * 2), o_addr); - } - else if(i_trgt.type == TRGT_XBUS) //XBUS - { - uint8_t l_ring_id = get_ring(i_addr) & 0xF; - if(l_ring_id <= XB_IOX_2_RING_ID && l_ring_id >= XB_IOX_0_RING_ID) - { - set_ring((XB_IOX_0_RING_ID + l_chip_unit_num) & 0xF, o_addr); - } - else if(l_ring_id <= XB_PBIOX_2_RING_ID && - l_ring_id >= XB_PBIOX_0_RING_ID) - { - set_ring((XB_PBIOX_0_RING_ID + l_chip_unit_num) & 0xF, o_addr); - } - } - else if(i_trgt.type == TRGT_OBUS) //OBUS - { - set_chiplet_id(OB0_CHIPLET_ID + l_chip_unit_num, o_addr); - } - else if(i_trgt.type == TRGT_PEC) //PEC - { - if(get_chiplet_id(i_addr) == N2_CHIPLET_ID) - { - // nest - set_ring((N2_PCIS0_0_RING_ID + l_chip_unit_num) & 0xF, o_addr); - } - else - { - // iopci / pci - set_chiplet_id(PCI0_CHIPLET_ID + l_chip_unit_num, o_addr); - } - } - else if (i_trgt.type == TRGT_PHB) //PHB - { - if(get_chiplet_id(i_addr) == N2_CHIPLET_ID) - { - // nest - if(l_chip_unit_num == 0) - { - set_ring(N2_PCIS0_0_RING_ID & 0xF, o_addr); - set_sat_id((get_sat_id(i_addr) < 4) ? 1 : 4, o_addr); - } - else - { - set_ring((N2_PCIS0_0_RING_ID + (l_chip_unit_num / 3) + 1) & 0xF, - o_addr); - set_sat_id(((get_sat_id(i_addr) < 4) ? 1 : 4) + - ((l_chip_unit_num % 2) ? 0 : 1) + - (2 * l_chip_unit_num / 5), o_addr); - } - } - else - { - // pci - if(l_chip_unit_num == 0) - { - set_chiplet_id(PCI0_CHIPLET_ID, o_addr); - set_sat_id(((get_sat_id(i_addr) < 4) ? 1 : 4), o_addr); - } - else - { - set_chiplet_id(PCI0_CHIPLET_ID + (l_chip_unit_num / 3) + 1, o_addr); - set_sat_id(((get_sat_id(i_addr) < 4) ? 1 : 4) + - ((l_chip_unit_num % 2) ? 0 : 1) + - 2 * l_chip_unit_num / 5, o_addr); - } - } - } - else if(i_trgt.type == TRGT_EX) //EX - { - if(get_chiplet_id(i_addr) <= EP05_CHIPLET_ID && - get_chiplet_id(i_addr) >= EP00_CHIPLET_ID) - { - set_chiplet_id(EP00_CHIPLET_ID + (l_chip_unit_num / 2), o_addr); - uint8_t l_ring_id = get_ring(i_addr) & 0xF; - l_ring_id = (l_ring_id - (l_ring_id % 2)) + (l_chip_unit_num % 2); - set_ring(l_ring_id & 0xF, o_addr); - } - else if(get_chiplet_id(i_addr) <= EC23_CHIPLET_ID && - get_chiplet_id(i_addr) >= EC00_CHIPLET_ID) - { - set_chiplet_id(EC00_CHIPLET_ID + - (get_chiplet_id(i_addr) % 2) + - (l_chip_unit_num * 2), o_addr); - } - } - else if(i_trgt.type == TRGT_EQ) //EQ - { - set_chiplet_id(EP00_CHIPLET_ID + l_chip_unit_num, o_addr); - } - else if(i_trgt.type == TRGT_EC) //EC - { - set_chiplet_id(EC00_CHIPLET_ID + l_chip_unit_num, o_addr); - } - else if(i_trgt.type == TRGT_MBA) //MBA - { - if( (i_addr & MBA_MASK) == MBA_BASEADDR ) - { - /* 0x00000000_03010400 MBA 0 # MBA01 */ - /* 0x00000000_03010C00 MBA 1 # MBA23 */ - if( l_chip_unit_num == 1 ) - { - *o_addr |= 0x00000800; - } - } - else if( (i_addr & MBA_MASK) == TCM_MBA_BASEADDR ) - { - /* 0x00000000_03010880 MBA 0 # Trace for MBA01 */ - /* 0x00000000_030110C0 MBA 1 # Trace for MBA23 */ - *o_addr |= (l_chip_unit_num * 0x840); - } - else if( (i_addr & MBA_MASK) == IND_MBA_BASEADDR ) - { - /* 0x00000000_03011400 MBA 0 # DPHY01 (indirect addressing) */ - /* 0x00000000_03011800 MBA 1 # DPHY23 (indirect addressing) */ - /* 0x80000000_0301143f MBA 0 # DPHY01 (indirect addressing) */ - /* 0x80000000_0301183f MBA 1 # DPHY23 (indirect addressing) */ - /* 0x80000000_0701143f MBA 0 # DPHY01 (indirect addressing) */ - /* 0x80000000_0701183f MBA 1 # DPHY23 (indirect addressing) */ - if( l_chip_unit_num == 1 ) - { - /* 030114zz->030118zz */ - *o_addr &= 0xFFFFFFFFFFFFFBFF; - *o_addr |= 0x0000000000000800; - } - } - } - else if(i_trgt.type == TRGT_MCS || //MCS - i_trgt.type == TRGT_MI) //MI TODO RTC 175488 - { - set_chiplet_id(N3_CHIPLET_ID - (2 * (l_chip_unit_num / 2)), o_addr); - set_sat_id(2 * (l_chip_unit_num % 2), o_addr); - } - else if(i_trgt.type == TRGT_MCBIST || //MCBIST - i_trgt.type == TRGT_MC) //MC TODO RTC 175488 - { - set_chiplet_id(MC01_CHIPLET_ID + l_chip_unit_num, o_addr); - } - else if(i_trgt.type == TRGT_MCA) //MCA - { - if(get_chiplet_id(i_addr) == MC01_CHIPLET_ID || - get_chiplet_id(i_addr) == MC23_CHIPLET_ID) - { - set_chiplet_id(MC01_CHIPLET_ID + (l_chip_unit_num / 4), o_addr); - - if((get_ring(i_addr) & 0xf) == MC_MC01_0_RING_ID) - { - // mc - uint8_t l_sat_id = get_sat_id(i_addr); - set_sat_id((l_sat_id - (l_sat_id % 4)) + (l_chip_unit_num % 4) - , o_addr); - } - else - { - // iomc - set_ring((MC_IOM01_0_RING_ID + (l_chip_unit_num % 4)) & 0xF - , o_addr); - } - } - else - { - // mcs->mca registers - uint8_t l_mcs_unitnum = l_chip_unit_num / 2; - set_chiplet_id(N3_CHIPLET_ID - (2 * (l_mcs_unitnum / 2)) , o_addr); - set_sat_id(2 * (l_chip_unit_num % 2), o_addr); - uint8_t l_mcs_sat_offset = 0x2F & get_sat_offset(i_addr); - l_mcs_sat_offset |= (l_chip_unit_num % 2) << 4; - set_sat_offset(l_mcs_sat_offset, o_addr); - } - } - else if(i_trgt.type == TRGT_DMI) //DMI TODO RTC 175488 - { - if(get_chiplet_id(i_addr) == N3_CHIPLET_ID || get_chiplet_id(i_addr) == N1_CHIPLET_ID) - { - set_chiplet_id(N3_CHIPLET_ID - 2 * (l_chip_unit_num / 4), o_addr); - set_sat_id(2 * ((l_chip_unit_num / 2) % 2), o_addr); - uint8_t l_sat_offset = get_sat_offset(i_addr); - l_sat_offset = (l_sat_offset & 0xF) + ((2 + (l_chip_unit_num % 2)) << 4); - set_sat_offset(l_sat_offset, o_addr); - } - else if(get_chiplet_id(i_addr) == MC01_CHIPLET_ID || get_chiplet_id(i_addr) == MC23_CHIPLET_ID) - { - if(get_ring(i_addr) == P9C_MC_CHAN_RING_ID) - { - set_chiplet_id(MC01_CHIPLET_ID + l_chip_unit_num / 4, o_addr); - uint8_t l_sat_id = get_sat_id(i_addr); - l_sat_id = l_sat_id & 0xC; - set_sat_id(l_sat_id + l_chip_unit_num % 4, o_addr); - } - else if(get_ring(i_addr) == P9C_MC_BIST_RING_ID) - { - set_chiplet_id(MC01_CHIPLET_ID + l_chip_unit_num / 4, o_addr); - uint8_t l_sat_offset = get_sat_offset(i_addr); - l_sat_offset = (l_sat_offset & 0xF) + ((l_chip_unit_num % 2) << 4); - set_sat_offset(l_sat_offset, o_addr); - } - else if(get_ring(i_addr) == P9C_MC_IO_RING_ID) - { - set_chiplet_id(MC01_CHIPLET_ID + l_chip_unit_num / 4, o_addr); - uint8_t l_rxtx_group = get_rxtx_group_id(i_addr); - l_rxtx_group = l_rxtx_group & 0xF0; - - switch(l_chip_unit_num % 4) - { - case 0: - l_rxtx_group += 3; - break; - case 1: - l_rxtx_group += 2; - break; - case 2: - l_rxtx_group += 0; - break; - case 3: - l_rxtx_group += 1; - break; - default: - break; - } - set_rxtx_group_id(l_rxtx_group, o_addr); - } - } - } - else - { - TRAC_ERR( FUNC"unsupported unit type %d", i_trgt.type ); - rc = FAIL; - } - - return rc; - - #undef FUNC -} - -/** - * @brief Performs a getscom operation with no address translation. - * @param i_chip Chip to SCOM. - * @param i_addr Address to SCOM. - * @param o_val Returned value. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t getscomraw( SCOM_Trgt_t i_chip, uint32_t i_addr, uint64_t * o_val ) -{ - int32_t l_rc = SUCCESS; - - //Use SBE FIFO if it's a slave proc - if(!i_chip.isMaster) - { - return getFifoScom(&i_chip, i_addr, o_val); - } - - if(!G_request_created) //Only need to create request once - { - l_rc = gpe_request_create(&G_request, //Request - &G_async_gpe_queue0, //Queue - IPC_ST_SCOM_OPERATION, //Function ID - &G_scom_op, //GPE arguments - SSX_SECONDS(5), //Timeout - NULL, //Callback function - NULL, //Callback args - ASYNC_REQUEST_BLOCKING); //Options - if(l_rc) - { - TRAC_ERR("getscomraw: failed to create gpe request, rc=0x%08X", l_rc); - return l_rc; - } - else - { - G_request_created = TRUE; - } - } - - //Pack in the request data - G_scom_op.read = TRUE; - G_scom_op.addr = i_addr; - - l_rc = gpe_request_schedule(&G_request); - if(l_rc) - { - TRAC_ERR("getscomraw: failed to schedule gpe request, rc=0x%08X", l_rc); - return l_rc; - } - - //Since it's a blocking request, it should be completed by the time we - //get here. If it's not, then a timeout has occurred. - if(G_request.request.completion_state == ASYNC_REQUEST_STATE_COMPLETE) - { - *o_val = G_scom_op.data; - } - else - { - *o_val = 0; - l_rc = FAIL; - } - - return l_rc; -} - -/** - * @brief Perform a putscom operation with no address translation. - * @param i_chip Chip to SCOM. - * @param i_addr Address to SCOM. - * @param i_val Value to write. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t putscomraw( SCOM_Trgt_t i_chip, uint32_t i_addr, uint64_t i_val ) -{ - int32_t l_rc = SUCCESS; - - //Use SBE FIFO if it's a slave proc - if(!i_chip.isMaster) - { - return putFifoScom(&i_chip, i_addr, i_val); - } - - if(!G_request_created) //Only need to create request once - { - l_rc = gpe_request_create(&G_request, //Request - &G_async_gpe_queue0, //Queue - IPC_ST_SCOM_OPERATION, //Function ID - &G_scom_op, //GPE arguments - SSX_SECONDS(5), //Timeout - NULL, //Callback function - NULL, //Callback args - ASYNC_REQUEST_BLOCKING); //Options - if(l_rc) - { - TRAC_ERR("putscomraw gpe request create failed, rc = 0x%08x", l_rc); - return l_rc; - } - else - { - G_request_created = TRUE; - } - } - - //Pack in the request data - G_scom_op.read = FALSE; - G_scom_op.addr = i_addr; - G_scom_op.data = i_val; - - l_rc = gpe_request_schedule(&G_request); - if(l_rc) - { - TRAC_ERR("putscomraw gpe request schedule failed, rc=0x%08X", l_rc); - return l_rc; - } - - //It's a blocking request, so if the request hasn't been completed by this - //time, then a timeout has occurred. - if(G_request.request.completion_state != ASYNC_REQUEST_STATE_COMPLETE) - { - TRAC_ERR("putscomraw gpe request failed to complete, rc = 0x%08x", l_rc); - l_rc = FAIL; - } - - return l_rc; -} - -/** - * @brief Executes standard getscom. - * @param i_trgt Chip to SCOM. - * @param i_addr Address to SCOM. - * @param o_val Returned value. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t SCOM_getScom( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint64_t * o_val ) -{ - int32_t rc = SUCCESS; - - /* Get the parent chip. */ - SCOM_Trgt_t chip_targ = SCOM_Trgt_getParentChip(i_trgt); - - /* Get the address relative to the parent chip. */ - uint64_t trans_addr; - rc = translate_addr( i_trgt, i_addr, &trans_addr ); - if ( SUCCESS == rc ) - { - /* Do the SCOM. */ - rc = getscomraw( chip_targ, trans_addr, o_val ); - } - - return rc; -} - -/** - * @brief Execute indirect getscom. - * @param i_trgt Chip to SCOM. - * @param i_addr Address to SCOM. - * @param o_val Returned value. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. - */ -int32_t SCOM_getIdScom( SCOM_Trgt_t i_trgt, uint64_t i_addr, uint32_t * o_val ) -{ - #define FUNC "[SCOM_getIdScom] " - - int32_t rc = SUCCESS; - - *o_val = 0; - - /* Get the parent chip */ - SCOM_Trgt_t chip_targ = SCOM_Trgt_getParentChip(i_trgt); - - /* Get the address relative to the parent chip. */ - uint64_t trans_addr; - rc = translate_addr( i_trgt, i_addr, &trans_addr ); - if ( SUCCESS != rc ) return rc; - - /* An indirect SCOM is performed by putting the top of the 64-bit address - * into the first data word of the SCOM */ - - /* Zero out the indirect address from the buffer. */ - /* bit 0-31 - indirect area. */ - /* bit 32 - always 0 */ - /* bit 33-47 - bcast/chipletID/port */ - /* bit 48-63 - local addr */ - uint32_t phys_addr = trans_addr & 0x000000007FFFFFFF; - - /* To do a read we need to do a write first. */ - - /* Start with the 20bit indirect address */ - uint64_t data_buffer = trans_addr & 0x001FFFFF00000000; - /* Turn the read bit on. */ - data_buffer |= 0x8000000000000000; - - /* perform write before the read with the new */ - rc = putscomraw( i_trgt, phys_addr, data_buffer ); - if ( SUCCESS != rc ) return rc; - - // Loop on read until we see done, error, or we timeout - IndirectScom_t scomout; - uint64_t elapsed_indScom_time_ns = 0; - do - { - /* Now perform the op requested using the passed in */ - /* IO_Buffer to pass the read data back to caller. */ - rc = getscomraw( chip_targ, phys_addr, &(scomout.data64) ); - if ( SUCCESS != rc ) return rc; - - /* Check for PIB error. */ - if ( scomout.piberr ) - { - TRAC_ERR( FUNC"ID SCOM PIB error: phys_addr=0x%08x " - "trans_addr=0x%08x%08x", phys_addr, - (uint32_t)(trans_addr >> 32), (uint32_t)trans_addr ); - return FAIL; - } - - /* Jump out when done. */ - if ( scomout.done ) break; - - sleep( 10000 ); /* sleep for 10,000 ns */ - elapsed_indScom_time_ns += 10000; - - } while ( elapsed_indScom_time_ns <= 100000 ); /* wait for .1ms */ - - if ( !scomout.done ) - { - TRAC_ERR( FUNC"ID SCOM loop timeout exceeded: phys_addr=0x%08x " - "trans_addr=0x%08x%08x", phys_addr, - (uint32_t)(trans_addr >> 32), (uint32_t)trans_addr ); - return FAIL; - } - - *o_val = scomout.data; - - return rc; - - #undef FUNC -} - -/** - * @brief Executes standard putscom. - * @param i_trgt Chip to SCOM. - * @param i_addr Address to SCOM. - * @param i_val Value to put. - * @return Non-SUCCESS if an internal function fails. SUCCESS otherwise. -*/ -int32_t SCOM_putScom( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint64_t i_val ) -{ - int32_t l_rc = SUCCESS; - - /* Get the parent chip. */ - SCOM_Trgt_t l_chip_targ = SCOM_Trgt_getParentChip(i_trgt); - - /* Get the address relative to the parent chip. */ - uint64_t l_trans_addr; - l_rc = translate_addr( i_trgt, i_addr, &l_trans_addr ); - if ( SUCCESS == l_rc ) - { - /* Do the SCOM. */ - l_rc = putscomraw( l_chip_targ, l_trans_addr, i_val ); - } - - return l_rc; -} diff --git a/src/occ_405/firdata/scom_util.h b/src/occ_405/firdata/scom_util.h deleted file mode 100644 index 1ec7fd2..0000000 --- a/src/occ_405/firdata/scom_util.h +++ /dev/null @@ -1,98 +0,0 @@ -/* IBM_PROLOG_BEGIN_TAG */ -/* This is an automatically generated prolog. */ -/* */ -/* $Source: src/occ_405/firdata/scom_util.h $ */ -/* */ -/* OpenPOWER OnChipController Project */ -/* */ -/* Contributors Listed Below - COPYRIGHT 2015,2017 */ -/* [+] International Business Machines Corp. */ -/* */ -/* */ -/* Licensed under the Apache License, Version 2.0 (the "License"); */ -/* you may not use this file except in compliance with the License. */ -/* You may obtain a copy of the License at */ -/* */ -/* http://www.apache.org/licenses/LICENSE-2.0 */ -/* */ -/* Unless required by applicable law or agreed to in writing, software */ -/* distributed under the License is distributed on an "AS IS" BASIS, */ -/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or */ -/* implied. See the License for the specific language governing */ -/* permissions and limitations under the License. */ -/* */ -/* IBM_PROLOG_END_TAG */ - -/* Interfaces to read SCOM registers */ - -/*#include <stdint.h> */ -#include <native.h> -#include <scom_trgt.h> - -#define SCOMFAIL 0xDEADBEEF - -typedef enum -{ - N0_CHIPLET_ID = 0x02, ///< Nest0 (North) chiplet - N1_CHIPLET_ID = 0x03, ///< Nest1 (East) chiplet - N2_CHIPLET_ID = 0x04, ///< Nest2 (South) chiplet - N3_CHIPLET_ID = 0x05, ///< Nest3 (West) chiplet - MC01_CHIPLET_ID = 0x07, ///< MC01 (West) chiplet - MC23_CHIPLET_ID = 0x08, ///< MC23 (East) chiplet - OB0_CHIPLET_ID = 0x09, ///< OBus0 chiplet - PCI0_CHIPLET_ID = 0x0D, ///< PCIe0 chiplet - EP00_CHIPLET_ID = 0x10, ///< Quad0 chiplet (EX0/1) - EP05_CHIPLET_ID = 0x15, ///< Quad5 chiplet (EX10/11) - EC00_CHIPLET_ID = 0x20, ///< Core0 chiplet (Quad0, EX0, C0) - EC23_CHIPLET_ID = 0x37 ///< Core23 chiplet (Quad5, EX11, C1) -} p9_chiplet_id_t; - -typedef enum -{ - MC_MC01_0_RING_ID = 0x2, ///< MC01_0 / MC23_0 - MC_IOM01_0_RING_ID = 0x4, ///< IOM01_0 / IOM45_0 -} p9_mc_ring_id_t; - -typedef enum -{ - XB_IOX_0_RING_ID = 0x3, ///< IOX_0 - XB_IOX_2_RING_ID = 0x5, ///< IOX_2 - XB_PBIOX_0_RING_ID = 0x6, ///< PBIOX_0 - XB_PBIOX_2_RING_ID = 0x8 ///< PBIOX_2 -} p9_xb_ring_id_t; - -typedef enum -{ - P9C_MC_CHAN_RING_ID = 0x2, - P9C_MC_IO_RING_ID = 0x4, - P9C_MC_BIST_RING_ID = 0x8 -} p9c_mc_ring_id_t; - -typedef enum -{ - N2_PCIS0_0_RING_ID = 0x3, ///< PCIS0_0 -} p9_n2_ring_id_t; - -/** @brief Performs a hardware scom on a regular register. - * @param i_trgt The SCOM target. - * @param i_addr 32-bit SCOM address. - * @param o_val 64-bit returned value. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -int32_t SCOM_getScom( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint64_t * o_val ); - -/** @brief Performs a hardware put scom on a regular register. - * @param i_trgt The SCOM target. - * @param i_addr 32-bit SCOM address. - * @param i_val 64-bit value to write to the address. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. -*/ -int32_t SCOM_putScom( SCOM_Trgt_t i_trgt, uint32_t i_addr, uint64_t i_val ); - -/** @brief Performs a hardware scom on an indirect-SCOM register. - * @param i_trgt The SCOM target. - * @param i_addr 64-bit SCOM address. - * @param o_val 32-bit returned value. - * @return Non-SUCCESS if the SCOM fails. SUCCESS otherwise. - */ -int32_t SCOM_getIdScom( SCOM_Trgt_t i_trgt, uint64_t i_addr, uint32_t * o_val ); |