diff options
-rw-r--r-- | src/common/centaur_configuration.h | 2 | ||||
-rw-r--r-- | src/common/global_app_cfg.h | 2 | ||||
-rwxr-xr-x | src/occ_405/occbuildname.c | 2 | ||||
-rw-r--r-- | src/occ_gpe1/gpe_centaur.c | 13 | ||||
-rw-r--r-- | src/occ_gpe1/gpe_centaur.h | 1 | ||||
-rw-r--r-- | src/occ_gpe1/gpe_centaur_scom.c | 269 | ||||
-rw-r--r-- | src/occ_gpe1/occ_gpe1_machine_check_handler.c | 44 | ||||
-rw-r--r-- | src/occ_gpe1/occ_gpe1_mck_handler.S | 64 | ||||
-rw-r--r-- | src/occ_gpe1/pk_app_cfg.h | 3 | ||||
-rw-r--r-- | src/occ_gpe1/topfiles.mk | 5 |
10 files changed, 325 insertions, 80 deletions
diff --git a/src/common/centaur_configuration.h b/src/common/centaur_configuration.h index 65b556b..46f9521 100644 --- a/src/common/centaur_configuration.h +++ b/src/common/centaur_configuration.h @@ -122,6 +122,8 @@ typedef struct enum { // rc 1 - 7 reserved from scom rc + CENTAUR_ACCESS_INACTIVE = 98, + CENTAUR_ACCESS_IN_PROGRESS = 99, CENTAUR_INVALID_SCOM = 100, CENTAUR_GET_MEM_DATA_COLLECT_INVALID = 200, CENTAUR_GET_MEM_DATA_UPDATE_INVALID = 201, diff --git a/src/common/global_app_cfg.h b/src/common/global_app_cfg.h index 97957e7..5dd6008 100644 --- a/src/common/global_app_cfg.h +++ b/src/common/global_app_cfg.h @@ -40,7 +40,7 @@ // Redefine the default MSR to mask off SIB errors and avoid data machine checks // These SIB errors probably occur due to contention on the PIB #define PK_THREAD_MACHINE_CONTEXT_DEFAULT (MSR_SEM | MSR_UIE | MSR_EE | MSR_ME) -#define PPE42_MSR_INITIAL (MSR_SEM | MSR_ME) +#define PPE42_MSR_INITIAL (MSR_SEM | MSR_ME | MSR_UIE ) // Enable GPE IPC Timers #define GPE_IPC_TIMERS diff --git a/src/occ_405/occbuildname.c b/src/occ_405/occbuildname.c index eb61723..376e72b 100755 --- a/src/occ_405/occbuildname.c +++ b/src/occ_405/occbuildname.c @@ -34,6 +34,6 @@ volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = #else -volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = /*<BuildName>*/ "op_occ_180711a\0" /*</BuildName>*/ ; +volatile const char G_occ_buildname[16] __attribute__((section(".buildname"))) = /*<BuildName>*/ "op_occ_180802a\0" /*</BuildName>*/ ; #endif diff --git a/src/occ_gpe1/gpe_centaur.c b/src/occ_gpe1/gpe_centaur.c index 671b30d..d492133 100644 --- a/src/occ_gpe1/gpe_centaur.c +++ b/src/occ_gpe1/gpe_centaur.c @@ -23,6 +23,7 @@ void gpe_centaur_init(ipc_msg_t* i_cmd, void* i_arg) } else { + PK_TRACE("Centaur_configuration. MSR:%08x",mfmsr()); rc = gpe_centaur_configuration_create(G_centaur_config); } @@ -42,10 +43,16 @@ void gpe_centaur_init(ipc_msg_t* i_cmd, void* i_arg) void gpe_centaur_scom(ipc_msg_t* i_cmd, void* i_arg) { + static int g_log_once = 0; int rc; ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd; CentaurScomParms_t * scomParms = (CentaurScomParms_t*)async_cmd->cmd_data; + if(g_log_once == 0) + { + g_log_once = 1; + PK_TRACE("Centaur Scom. MSR:%08x",mfmsr()); + } gpe_scom_centaur(G_centaur_config, scomParms); // Send response @@ -64,12 +71,18 @@ void gpe_centaur_scom(ipc_msg_t* i_cmd, void* i_arg) void gpe_centaur_data(ipc_msg_t* i_cmd, void* i_arg) { + static int g_log_once = 0; int rc; ipc_async_cmd_t *async_cmd = (ipc_async_cmd_t*)i_cmd; CentaurGetMemDataParms_t * dataParms = (CentaurGetMemDataParms_t *)async_cmd->cmd_data; + if(g_log_once == 0) + { + g_log_once = 1; + PK_TRACE("Centaur Data. MSR:%08x",mfmsr()); + } rc = centaur_get_mem_data(G_centaur_config, dataParms); dataParms->error.rc = rc; diff --git a/src/occ_gpe1/gpe_centaur.h b/src/occ_gpe1/gpe_centaur.h index e30a724..482af22 100644 --- a/src/occ_gpe1/gpe_centaur.h +++ b/src/occ_gpe1/gpe_centaur.h @@ -57,4 +57,5 @@ int centaur_get_mem_data(CentaurConfiguration_t* i_config, */ int check_channel_chkstp(unsigned int i_centaur); +extern uint32_t g_centaur_access_state; #endif diff --git a/src/occ_gpe1/gpe_centaur_scom.c b/src/occ_gpe1/gpe_centaur_scom.c index 4cd4cf5..edee857 100644 --- a/src/occ_gpe1/gpe_centaur_scom.c +++ b/src/occ_gpe1/gpe_centaur_scom.c @@ -24,11 +24,63 @@ #include "pba_register_addresses.h" #include "ppe42_msr.h" +#define CENTAUR_ACCESS_READ 1 +#define CENTAUR_ACCESS_WRITE 2 + /** * @file centaur_scom * @brief scom access from gpe to a centaur */ +uint32_t g_centaur_access_state = CENTAUR_ACCESS_INACTIVE; + +int centaur_access(CentaurConfiguration_t* i_config, + uint32_t i_instance, + uint32_t i_oci_addr, + uint64_t * io_data, + int i_read_write) +{ + int rc = 0; + uint32_t org_msr = mfmsr(); + uint32_t msr = org_msr | MSR_SEM; // Mask off SIB from generating mck. + + g_centaur_access_state = CENTAUR_ACCESS_IN_PROGRESS; + + if(i_read_write == CENTAUR_ACCESS_READ) + { + mtmsr(msr); + sync(); + PPE_LVD(i_oci_addr, *io_data); + } + else + { + // Set PPE to precise mode for stores so that in the case of a machine + // check, there is a predictable instruction address to resume on. + msr &= ~MSR_IPE; + mtmsr(msr); + sync(); + + PPE_STVD(i_oci_addr, *io_data); + } + + // Poll SIB error or machine check + if((mfmsr() & MSR_SIBRC) || + g_centaur_access_state != CENTAUR_ACCESS_IN_PROGRESS) + { + // Take centaur out of config + PK_TRACE("Removing Centaur %d from list of configured Centaurs", + i_instance); + + i_config->config &= ~(CHIP_CONFIG_CENTAUR(i_instance)); + + // This will cause the 405 to remove the centaur sensor. + rc = CENTAUR_CHANNEL_CHECKSTOP; + } + g_centaur_access_state = CENTAUR_ACCESS_INACTIVE; + mtmsr(org_msr); + return rc; +} + /** * Setup the PBASLVCTLN extended address and calculate the OCI scom address * @param[in] PBA base address @@ -74,6 +126,10 @@ int centaur_scom_setup(CentaurConfiguration_t* i_config, { // workaround - don't use extraddr - use pbabar. uint64_t barMsk = 0; + + // Mask SIB from generating mck + mtmsr(mfmsr() | MSR_SEM); + // put the PBA in the BAR rc = putscom_abs(PBA_BARN(PBA_BAR_CENTAUR), pb_addr); if(rc) @@ -122,6 +178,10 @@ int centaur_sensorcache_setup(CentaurConfiguration_t* i_config, { // HW bug workaround - don't use extaddr - use pbabar. uint64_t barMsk = 0; + + // Mask SIB from generating mck + mtmsr(mfmsr() | MSR_SEM); + // put the PBA in the BAR rc = putscom_abs(PBA_BARN(PBA_BAR_CENTAUR), pb_addr); if (rc) @@ -174,33 +234,14 @@ uint64_t pbaslvctl_setup(GpePbaParms* i_pba_parms) return slvctl_val_org; } -// Get the most severe rc from the sibrca field in the msr -int rc_from_sibrc() -{ - int rc = 0; - uint32_t sibrca = (mfmsr() & 0x0000007f); - if(sibrca) - { - uint32_t mask = 1; - rc = 7; - for(; mask != 0x00000080; mask <<=1) - { - if( mask & sibrca ) - { - break; - } - --rc; - } - } - return rc; -} - // Get data from each existing centaur. int centaur_get_scom_vector(CentaurConfiguration_t* i_config, uint32_t i_scom_address, uint64_t* o_data) { int rc = 0; + int access_rc = 0; + int pba_rc = 0; int instance = 0; uint64_t pba_slvctln_save; @@ -215,18 +256,32 @@ int centaur_get_scom_vector(CentaurConfiguration_t* i_config, if( CHIP_CONFIG_CENTAUR(instance) & (i_config->config)) { uint32_t oci_addr; - rc = centaur_scom_setup(i_config, - instance, - i_scom_address, - &oci_addr); + pba_rc = centaur_scom_setup(i_config, + instance, + i_scom_address, + &oci_addr); - if(rc) + if(pba_rc) { + rc = pba_rc; // Already traced. - break; + // Trumps any access error + *o_data = 0; } + // read centaur scom - PPE_LVD(oci_addr, *o_data); + access_rc = centaur_access(i_config, + instance, + oci_addr, + o_data, + CENTAUR_ACCESS_READ); + if(!rc && access_rc) + { + // not critical, but don't touch this centaur again. + rc = access_rc; + *o_data = 0; + // continue + } } else { @@ -240,10 +295,6 @@ int centaur_get_scom_vector(CentaurConfiguration_t* i_config, pbaslvctl_reset(&(i_config->scomParms)); PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save); - if(!rc) - { - rc = rc_from_sibrc(); - } return rc; } @@ -267,7 +318,11 @@ int centaur_get_scom(CentaurConfiguration_t* i_config, if( !rc && (CHIP_CONFIG_CENTAUR(i_centaur_instance) & (i_config->config))) { // read centaur scom - rc = getscom_abs(oci_addr, o_data); + rc = centaur_access(i_config, + i_centaur_instance, + oci_addr, + o_data, + CENTAUR_ACCESS_READ); } else { @@ -288,44 +343,50 @@ int centaur_put_scom_all(CentaurConfiguration_t* i_config, uint64_t i_data) { int rc = 0; + int pba_rc = 0; + int access_rc = 0; int instance = 0; uint64_t pba_slvctln_save; pbaslvctl_reset(&(i_config->scomParms)); pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms)); - // clear SIB errors in MSR - mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA))); - for(instance = 0; instance < OCCHW_NCENTAUR; ++instance) { if( CHIP_CONFIG_CENTAUR(instance) & (i_config->config)) { uint32_t oci_addr; - rc = centaur_scom_setup(i_config, + pba_rc = centaur_scom_setup(i_config, instance, i_scom_address, &oci_addr); - if(rc) + if(pba_rc) { // Already traced in centaur_scom_setup - break; + // Trumps access_rc + rc = pba_rc; } // centaur scom - PPE_STVD(oci_addr, i_data); + access_rc = centaur_access(i_config, + instance, + oci_addr, + &i_data, + CENTAUR_ACCESS_WRITE); + if(!rc && access_rc) + { + // Centaur won't be touched again. + rc = access_rc; + // continue + } } } - // gpe_pba_cntl function? + // reset pba slave pbaslvctl_reset(&(i_config->scomParms)); PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save); - if(!rc) - { - rc = rc_from_sibrc(); - } return rc; } @@ -351,15 +412,15 @@ int centaur_put_scom(CentaurConfiguration_t* i_config, if(CHIP_CONFIG_CENTAUR(i_centaur_instance) & (i_config->config)) { // write centaur scom - rc = putscom_abs(oci_addr, i_data); - } - else - { - rc = CENTAUR_INVALID_SCOM; + rc = centaur_access(i_config, + i_centaur_instance, + oci_addr, + &i_data, + CENTAUR_ACCESS_WRITE); } } - // gpe_pba_cntl function? + // reset pba slave pbaslvctl_reset(&(i_config->scomParms)); PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save); @@ -388,13 +449,22 @@ int centaur_scom_rmw(CentaurConfiguration_t* i_config, if(!rc) { - rc = getscom_abs(oci_addr, &data64); + rc = centaur_access(i_config, + i_centaur_instance, + oci_addr, + &data64, + CENTAUR_ACCESS_READ); + if(!rc) { data64 &= (i_mask ^ 0xffffffffffffffffull); data64 |= *i_data; - rc = putscom_abs(oci_addr, data64); + rc = centaur_access(i_config, + i_centaur_instance, + oci_addr, + &data64, + CENTAUR_ACCESS_WRITE); } } @@ -411,35 +481,55 @@ int centaur_scom_rmw_all(CentaurConfiguration_t* i_config, uint64_t i_data) { int rc = 0; + int pba_rc = 0; + int access_rc = 0; int instance = 0; uint64_t pba_slvctln_save; pbaslvctl_reset(&(i_config->scomParms)); pba_slvctln_save = pbaslvctl_setup(&(i_config->scomParms)); - // clear SIB errors in MSR - mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA))); - for(instance = 0; (instance < OCCHW_NCENTAUR); ++instance) { if( CHIP_CONFIG_CENTAUR(instance) & (i_config->config)) { uint64_t data64; uint32_t oci_addr; - rc = centaur_scom_setup(i_config, - instance, - i_scom_address, - &oci_addr); - if(rc) + pba_rc = centaur_scom_setup(i_config, + instance, + i_scom_address, + &oci_addr); + if(pba_rc) { + rc = pba_rc; // Already traced in centaur_scom_setup - break; + // Trumps any access_rc } + if(!pba_rc) + { - PPE_LVD(oci_addr, data64); - data64 &= (i_mask ^ 0xffffffffffffffffull); - data64 |= i_data; - PPE_STVD(oci_addr, data64); + access_rc = centaur_access(i_config, + instance, + oci_addr, + &data64, + CENTAUR_ACCESS_READ); + + if(!access_rc) + { + data64 &= (i_mask ^ 0xffffffffffffffffull); + data64 |= i_data; + + access_rc = centaur_access(i_config, + instance, + oci_addr, + &data64, + CENTAUR_ACCESS_WRITE); + } + } + if(!rc && access_rc) + { + rc = access_rc; + } pbaslvctl_reset(&(i_config->scomParms)); } @@ -447,10 +537,6 @@ int centaur_scom_rmw_all(CentaurConfiguration_t* i_config, PPE_STVD((i_config->scomParms).slvctl_address, pba_slvctln_save); - if(!rc) - { - rc = rc_from_sibrc(); - } return rc; } @@ -469,6 +555,10 @@ int centaur_get_mem_data(CentaurConfiguration_t* i_config, pbaslvctl_reset(&(i_config->dataParms)); pba_slvctln_save = pbaslvctl_setup(&(i_config->dataParms)); + // Clear SIB error accumulator bits & mask SIB errors from + // generating machine checks + mtmsr((mfmsr() & ~(MSR_SIBRC | MSR_SIBRCA)) | MSR_SEM); + if(i_parms->collect != -1) { if((i_parms->collect >= OCCHW_NCENTAUR) || @@ -482,6 +572,9 @@ int centaur_get_mem_data(CentaurConfiguration_t* i_config, if(!rc) { + uint32_t org_msr = mfmsr(); + mtmsr(org_msr | MSR_SEM); // Mask off SIB errors from gen mck + g_centaur_access_state = CENTAUR_ACCESS_IN_PROGRESS; // Read 128 bytes from centaur cache int i; for(i = 0; i < 128; i += 8) @@ -489,29 +582,53 @@ int centaur_get_mem_data(CentaurConfiguration_t* i_config, PPE_LVDX(oci_addr, i, data64); PPE_STVDX((i_parms->data), i, data64); } + + // Poll for SIB errors or machine check + if((mfmsr() & MSR_SIBRC) || + g_centaur_access_state != CENTAUR_ACCESS_IN_PROGRESS) + { + // Take centaur out of config list + PK_TRACE("Removing Centaur %d from list of configured Centaurs", + i_parms->collect); + i_config->config &= ~(CHIP_CONFIG_CENTAUR(i_parms->collect)); + + // This rc will cause the 405 to remove this centaur sensor + rc = CENTAUR_CHANNEL_CHECKSTOP; + } + mtmsr(org_msr); + g_centaur_access_state = CENTAUR_ACCESS_INACTIVE; } } } - if(!rc && i_parms->update != -1) + if(i_parms->update != -1) { + int update_rc = 0; if((i_parms->update >= OCCHW_NCENTAUR) || (0 == (CHIP_CONFIG_CENTAUR(i_parms->update) & (i_config->config)))) { - rc = CENTAUR_GET_MEM_DATA_UPDATE_INVALID; + update_rc = CENTAUR_GET_MEM_DATA_UPDATE_INVALID; } else { - rc = centaur_sensorcache_setup(i_config, i_parms->update,&oci_addr); + update_rc = centaur_sensorcache_setup(i_config, i_parms->update,&oci_addr); - if(!rc) + if(!update_rc) { // Writing a zero to this address tells the centaur to update - // the sensor cache. + // the sensor cache for the next centaur. data64 = 0; - PPE_STVD(oci_addr, data64); + update_rc = centaur_access(i_config, + i_parms->update, + oci_addr, + &data64, + CENTAUR_ACCESS_WRITE); } } + if(!rc && update_rc) + { + rc = update_rc; + } } pbaslvctl_reset(&(i_config->dataParms)); diff --git a/src/occ_gpe1/occ_gpe1_machine_check_handler.c b/src/occ_gpe1/occ_gpe1_machine_check_handler.c new file mode 100644 index 0000000..33424c6 --- /dev/null +++ b/src/occ_gpe1/occ_gpe1_machine_check_handler.c @@ -0,0 +1,44 @@ +#include "pk_panic_codes.h" +#include "gpe_centaur.h" +#include "pk.h" + +#define OCI_ADDR_BAR_MASK 0xf0000000 +#define OCI_ADDR_BAR1 0x90000000 + +extern uint32_t gpe1_machine_check_handler(uint32_t srr0, + uint32_t srr1, + uint32_t edr); +extern uint32_t g_centaur_access_state; + +uint32_t gpe1_machine_check_handler(uint32_t srr0, + uint32_t srr1, + uint32_t edr) +{ + PK_TRACE("GPE1 Machine check! SRR0:%08x SRR1: %08x EDR:%08x", + srr0, + srr1, + edr); + + // It's possible to get back-to-back machine checks for the same condition + // so CENTAUR_CHANNEL_CHECKSTOP may already be set. Also check that the + // machine check was due to a Centaur Access (PBABAR1) + if((g_centaur_access_state == CENTAUR_ACCESS_IN_PROGRESS || + g_centaur_access_state == CENTAUR_CHANNEL_CHECKSTOP) && + ((edr & OCI_ADDR_BAR_MASK) == OCI_ADDR_BAR1)) + { + // Returning this to OCC405 will cause sensor to be removed from + // active list + g_centaur_access_state = CENTAUR_CHANNEL_CHECKSTOP; + + // The instruction that caused the machine check should + // be a double word load or store. + // move the IAR to the instruction after the one that caused + // the machine check. + srr0 += 4; + } + else + { + PK_PANIC( PPE42_MACHINE_CHECK_PANIC ); + } + return srr0; +} diff --git a/src/occ_gpe1/occ_gpe1_mck_handler.S b/src/occ_gpe1/occ_gpe1_mck_handler.S new file mode 100644 index 0000000..6583bc8 --- /dev/null +++ b/src/occ_gpe1/occ_gpe1_mck_handler.S @@ -0,0 +1,64 @@ +.nolist +#include "pk.h" +.list + +.section .text, "ax", @progbits +.global __gpe1_machine_check_handler +.global __pk_ctx_pop + +__gpe1_machine_check_handler: +#if !defined(__PPE42X__) + stwu %r1, -PK_CTX_SIZE(%r1) + stw %r0, PK_CTX_GPR0(%r1) + stvd %d3, PK_CTX_GPR3(%r1) + stvd %d5, PK_CTX_GPR5(%r1) + stvd %d7, PK_CTX_GPR7(%r1) + stvd %d9, PK_CTX_GPR9(%r1) + stvd %d28, PK_CTX_GPR28(%r1) + stvd %d30, PK_CTX_GPR30(%r1) + mflr %r3 + stw %r3, PK_CTX_LR(%r1) + mfcr %r3 + mfsprg0 %r4 + stvd %d3, PK_CTX_CR(%r1) + mfxer %r3 + mfctr %r4 + stvd %d3, PK_CTX_XER(%r1) + mfsrr0 %r3 + mfsrr1 %r4 + stvd %d3, PK_CTX_SRR0(%r1) +#else + stcxtu %r1, -PK_CTX_SIZE(%r1) + mfsrr0 %r3 + mfsrr1 %r4 +#endif + + mfedr %r5 + + bl gpe1_machine_check_handler + stw %r3, PK_CTX_SRR0(%r1) + +#if !defined(__PPE42X__) + lwz %r0, PK_CTX_GPR0(%r1) + lvd %d7, PK_CTX_SRR0(%r1) + mtsrr1 %r8 + mtsrr0 %r7 + lvd %d5, PK_CTX_XER(%r1) + mtctr %r6 + mtxer %r5 + lvd %d30, PK_CTX_GPR30(%r1) + lvd %d28, PK_CTX_GPR28(%r1) + lvd %d9, PK_CTX_GPR9(%r1) + lvd %d7, PK_CTX_GPR7(%r1) + lvd %d5, PK_CTX_GPR5(%r1) + lvd %d3, PK_CTX_CR(%r1) ## CR,SPRG0 + mtcr0 %r3 + lwz %r4, PK_CTX_LR(%r1) + mtlr %r4 + lvd %d3, PK_CTX_GPR3(%r1) + addi %r1, %r1, PK_CTX_SIZE +#else + lcxt %r1,%r1 +#endif + rfi + diff --git a/src/occ_gpe1/pk_app_cfg.h b/src/occ_gpe1/pk_app_cfg.h index 39c1a25..2cd085c 100644 --- a/src/occ_gpe1/pk_app_cfg.h +++ b/src/occ_gpe1/pk_app_cfg.h @@ -60,4 +60,7 @@ // PBA Slave allocated to Gpe 1 is PBA_SLAVE 2. SET PBASLVCTLN to 2 here. #define PBASLVCTLN 2 +#define PPE42_MACHINE_CHECK_HANDLER \ + b __gpe1_machine_check_handler + #endif /*__PK_APP_CFG_H__*/ diff --git a/src/occ_gpe1/topfiles.mk b/src/occ_gpe1/topfiles.mk index 672d1f7..53d35b5 100644 --- a/src/occ_gpe1/topfiles.mk +++ b/src/occ_gpe1/topfiles.mk @@ -26,8 +26,9 @@ TOP-C-SOURCES = gpe1_main.c gpe1_dimm_read.c gpe1_dimm_reset.c nop.c \ pk_app_irq_table.c ipc_func_tables.c gpe1_dimm_control.c \ gpe1_24x7.c gpe1_memory_power_control.c gpe_gpu_init.c \ - gpe_centaur_scom.c gpe_centaur_configuration.c gpe_centaur.c + gpe_centaur_scom.c gpe_centaur_configuration.c \ + gpe_centaur.c occ_gpe1_machine_check_handler.c -TOP-S-SOURCES = +TOP-S-SOURCES = occ_gpe1_mck_handler.S TOP_OBJECTS = $(TOP-C-SOURCES:.c=.o) $(TOP-S-SOURCES:.S=.o) |