diff options
Diffstat (limited to 'src/occ_405')
-rwxr-xr-x | src/occ_405/amec/amec_slave_smh.c | 16 | ||||
-rwxr-xr-x | src/occ_405/linkocc.cmd | 33 | ||||
-rwxr-xr-x | src/occ_405/main.c | 156 | ||||
-rw-r--r-- | src/occ_405/occ_service_codes.h | 3 | ||||
-rw-r--r-- | src/occ_405/pgpe/pgpe_shared.h | 11 | ||||
-rw-r--r-- | src/occ_405/wof/wof.c | 106 | ||||
-rw-r--r-- | src/occ_405/wof/wof.h | 40 |
7 files changed, 345 insertions, 20 deletions
diff --git a/src/occ_405/amec/amec_slave_smh.c b/src/occ_405/amec/amec_slave_smh.c index 18db711..bf33cc4 100755 --- a/src/occ_405/amec/amec_slave_smh.c +++ b/src/occ_405/amec/amec_slave_smh.c @@ -55,13 +55,13 @@ #include <amec_health.h> #include <amec_analytics.h> #include <common.h> +#include <occhw_async.h> #include <wof.h> //************************************************************************* // Externs //************************************************************************* extern dcom_slv_inbox_t G_dcom_slv_inbox_rx; - //************************************************************************* // Macros //************************************************************************* @@ -510,26 +510,28 @@ void amec_slv_state_4(void) //------------------------------------------------------- if( IS_OCC_STATE_ACTIVE() ) { - /* TODO: RTC: 166301 - Logic to determine if WOF algorithm should run. - static bool run_wof_algoritm = true; - if( !run_wof_algorithm ) + /* TODO: RTC 166301 - Logic to determine if WOF algorithm should run. + // The WOF algorithm is to be run every 4ms. Since amec_slv_state_4 + // is run every 2ms, we need to skip every other invocation. + static bool L_run_wof_algorithm = true; + if( !L_run_wof_algorithm ) { // When false, the last invocation decided we need to wait 2 ms // run wof algo next time. - run_wof_algorithm = true; + L_run_wof_algorithm = true; } else { //if IPC command is idle and ready to go //{ //wof_main(); - run_wof_algorithm = false; + L_run_wof_algorithm = false; //} //else if IPC command is still waiting //make thread wait another 2 ms //{ - // run_wof_algorithm = true; + // L_run_wof_algorithm = true; //} //else if IPC command is returning an error //{ diff --git a/src/occ_405/linkocc.cmd b/src/occ_405/linkocc.cmd index e15a4f3..1dbf362 100755 --- a/src/occ_405/linkocc.cmd +++ b/src/occ_405/linkocc.cmd @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2016 */ +/* Contributors Listed Below - COPYRIGHT 2011,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -533,14 +533,36 @@ SECTIONS #if EXECUTABLE_FREE_SPACE _DATA_SECTION_SIZE = . - _DATA_SECTION_BASE; __WRITEABLE_DATA_LEN__ = . - __WRITEABLE_DATA_ADDR__ ; - _EX_FREE_SECTION_SIZE = _TRACE_BUFFERS_START_BASE - _EX_FREE_SECTION_BASE; + _EX_FREE_SECTION_SIZE = _GLOBAL_DATA_BASE - _EX_FREE_SECTION_BASE; #else - _DATA_SECTION_SIZE = _TRACE_BUFFERS_START_BASE - _DATA_SECTION_BASE; - __WRITEABLE_DATA_LEN__ = _TRACE_BUFFERS_START_BASE - __WRITEABLE_DATA_ADDR__ ; + _DATA_SECTION_SIZE = _GLOBAL_DATA_BASE - _DATA_SECTION_BASE; + __WRITEABLE_DATA_LEN__ = _GLOBAL_DATA_BASE - __WRITEABLE_DATA_ADDR__ ; _EX_FREE_SECTION_SIZE = 0; #endif - _SSX_FREE_END = _TRACE_BUFFERS_START_BASE - 1; + _SSX_FREE_END = _GLOBAL_DATA_BASE - 1; + + + //////////////////////////////// + // Global Data Section + // + // Contains pointers to important Global variables + // + //////////////////////////////// + __CUR_COUNTER__ = .; + _GLOBAL_DATA_BASE = 0xfffb3f00; + _GLOBAL_DATA_SIZE = 0x100; + . = _GLOBAL_DATA_BASE; +#if !PPC405_MMU_SUPPORT + . = . - writethrough_offset; + _LMA = . + writethrough_offset; + .global_data . : AT(_LMA) {*(global_data) . = ALIGN(_GLOBAL_DATA_SIZE);} + . = . + writethrough_offset; +#else + .global_data . : {*(global_data) . = ALIGN(_GLOBAL_DATA_SIZE);} > sram +#endif + . = __CUR_COUNTER__; + //////////////////////////////// // Trace Buffers @@ -668,3 +690,4 @@ SECTIONS _PPC405_END_OF_MEMORY = 0; } + diff --git a/src/occ_405/main.c b/src/occ_405/main.c index defb159..e1ffd57 100755 --- a/src/occ_405/main.c +++ b/src/occ_405/main.c @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2016 */ +/* Contributors Listed Below - COPYRIGHT 2011,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -60,6 +60,7 @@ #include <pgpe_shared.h> #include <gpe_register_addresses.h> #include <p9_pstates_occ.h> +#include <wof.h> extern uint32_t __ssx_boot; // Function address is 32 bits extern uint32_t G_occ_phantom_critical_count; @@ -76,6 +77,19 @@ extern apss_complete_args_t G_gpe_complete_pwr_meas_read_args; extern uint32_t G_pgpe_beacon_address; +extern uint32_t G_proc_fmin_khz; +extern uint32_t G_proc_fmax_khz; +extern uint32_t G_wof_active_quads_sram_addr; +extern uint32_t G_wof_tables_main_mem_addr; +extern uint32_t G_wof_tables_len; +extern bool G_run_wof_main; +extern wof_header_data_t G_wof_header; + +extern uint32_t G_khz_per_pstate; + +extern uint8_t G_proc_pmin; +extern uint8_t G_proc_pmax; + IMAGE_HEADER (G_mainAppImageHdr,__ssx_boot,MAIN_APP_ID,ID_NUM_INVALID); // PGPE Image Header Parameters @@ -87,9 +101,11 @@ OCCPstateParmBlock G_oppb; // OCC Pstate Parameters Block Structure extern uint16_t G_proc_fmax_mhz; // max(turbo,uturbo) frequencies -//Set main thread timer for one second +// Set main thread timer for one second #define MAIN_THRD_TIMER_SLICE ((SsxInterval) SSX_SECONDS(1)) + + // SIMICS printf/printk SimicsStdio G_simics_stdout; SimicsStdio G_simics_stderr; @@ -98,6 +114,8 @@ SimicsStdio G_simics_stderr; uint8_t G_noncritical_stack[NONCRITICAL_STACK_SIZE]; uint8_t G_critical_stack[CRITICAL_STACK_SIZE]; + + //NOTE: Three semaphores are used so that if in future it is decided // to move health monitor and FFDC into it's own threads, then // it can be done easily without more changes. @@ -461,6 +479,120 @@ void create_tlb_entry(uint32_t address, uint32_t size) /* * Function Specification * + * Name: read_wof_header + * + * Description: Read WOF Tables header and populate global variables + * needed for WOF + * + * End Function Specification + */ +void read_wof_header(void) +{ + int l_ssxrc = SSX_OK; + uint32_t l_reasonCode = 0; + uint32_t l_extReasonCode = 0; + + do + { + // use block copy engine to read WOF header + BceRequest l_wof_header_req; + + // 128 byte aligned buffer to read the data + temp_bce_request_buffer_t l_temp_bce_buff = {{0}}; + + uint32_t pad = G_wof_tables_main_mem_addr%128; + // Force WOF tables address is on 128 byte boundary + uint32_t wof_main_mem_addr_128 = G_wof_tables_main_mem_addr - pad; + // Create request + l_ssxrc = bce_request_create(&l_wof_header_req, // block copy object + &G_pba_bcde_queue, // main to sram copy engine + wof_main_mem_addr_128, // mainstore address + (uint32_t) &l_temp_bce_buff, // SRAM start address + MIN_BCE_REQ_SIZE, // size of copy + SSX_WAIT_FOREVER, // no timeout + NULL, // no call back + NULL, // no call back args + ASYNC_REQUEST_BLOCKING);// blocking request + + if(l_ssxrc != SSX_OK) + { + CMDH_TRAC_ERR("read_wof_header: BCDE request create failure rc=[%08X]", -l_ssxrc); + /* + * @errortype + * @moduleid READ_WOF_HEADER + * @reasoncode SSX_GENERIC_FAILURE + * @userdata1 RC for BCE block-copy engine + * @userdata2 Internal function checkpoint + * @userdata4 ERC_BCE_REQUEST_CREATE_FAILURE + * @devdesc Failed to create BCDE request + */ + l_reasonCode = SSX_GENERIC_FAILURE; + l_extReasonCode = ERC_BCE_REQUEST_CREATE_FAILURE; + break; + } + + + // Do the actual copy + l_ssxrc = bce_request_schedule(&l_wof_header_req); + + if(l_ssxrc != SSX_OK) + { + CMDH_TRAC_ERR("read_wof_header: BCE request schedule failure rc=[%08X]", -l_ssxrc); + /* + * @errortype + * @moduleid READ_WOF_HEADER + * @reasoncode SSX_GENERIC_FAILURE + * @userdata1 RC for BCE block-copy engine + * @userdata4 ERC_BCE_REQUEST_SCHEDULE_FAILURE + * @devdesc Failed to read PPMR data by using BCDE + */ + l_reasonCode = SSX_GENERIC_FAILURE; + l_extReasonCode = ERC_BCE_REQUEST_SCHEDULE_FAILURE; + break; + } + + // Copy the data into Global WOF header struct + memcpy(&G_wof_header, &(l_temp_bce_buff.data[pad]), sizeof(wof_header_data_t)); + + + + + }while( 0 ); + + // Check for errors and log, if any + if( l_ssxrc != SSX_OK ) + { + errlHndl_t l_errl = createErrl(READ_WOF_HEADER, //modId + l_reasonCode, //reasoncode + l_extReasonCode, //Extended reason code + ERRL_SEV_UNRECOVERABLE, //Severity + NULL, //Trace Buf + 0, //Trace Size + -l_ssxrc, //userdata1 + 0); //userdata2 + + // Callout firmware + addCalloutToErrl(l_errl, + ERRL_CALLOUT_TYPE_COMPONENT_ID, + ERRL_COMPONENT_ID_FIRMWARE, + ERRL_CALLOUT_PRIORITY_HIGH); + + // Commit error log + commitErrl(&l_errl); + + // We were unable to get the WOF header thus it should not be run. + G_run_wof_main = false; + + return; + + } +} + + + +/* + * Function Specification + * * Name: read_pgpe_header * * Description: Initialize PGPE image header entry in DTLB, @@ -470,7 +602,6 @@ void create_tlb_entry(uint32_t address, uint32_t size) * * End Function Specification */ - void read_pgpe_header(void) { uint64_t magic_number; @@ -517,6 +648,20 @@ void read_pgpe_header(void) MAIN_TRAC_IMP("Read PGPE Beacon Address[0x%08x]", G_pgpe_beacon_address); + // Read active quads address, wof tables address, and wof tables len + G_wof_active_quads_sram_addr = in32(PGPE_ACTIVE_QUAD_ADDR_PTR); + G_wof_tables_main_mem_addr = in32(PGPE_WOF_TBLS_ADDR_PTR); + G_wof_tables_len = in32(PGPE_WOF_TBLS_LEN_PTR); + + MAIN_TRAC_IMP("Read WOF Tables Main Memory Address[0x%08x], Len[0x%08x]," + " Active Quads Address[0x%08x]", + G_wof_tables_main_mem_addr, + G_wof_tables_len, + G_wof_active_quads_sram_addr ); + + // Extract important WOF data into global space + read_wof_header(); + // Read OCC/PGPE Shared SRAM address and size G_pgpe_shared_sram_address = in32(PGPE_SHARED_SRAM_ADDR_PTR); G_pgpe_shared_sram_sz = in32(PGPE_SHARED_SRAM_SZ_PTR); @@ -742,6 +887,11 @@ void read_oppb_params(const OCCPstateParmBlock* oppb_offset) } } while (0); + // Read WOF addresses + + MAIN_TRAC_IMP("Read PGPE Shared SRAM Start Address[0x%08x], Size[0x%08x]", + G_pgpe_shared_sram_address, G_pgpe_shared_sram_sz); + if ( l_ssxrc != SSX_OK ) { errlHndl_t l_errl = createErrl(READ_OPPB_PARAMS, //modId diff --git a/src/occ_405/occ_service_codes.h b/src/occ_405/occ_service_codes.h index 569f6b6..d101582 100644 --- a/src/occ_405/occ_service_codes.h +++ b/src/occ_405/occ_service_codes.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2016 */ +/* Contributors Listed Below - COPYRIGHT 2011,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -266,6 +266,7 @@ enum occModuleId READ_PPMR_HEADER = MAIN_COMP_ID | 0x13, READ_OPPB_PARAMS = MAIN_COMP_ID | 0x14, MAIN_SMGR_MID = MAIN_COMP_ID | 0x15, + READ_WOF_HEADER = MAIN_COMP_ID | 0x16, }; enum occUserDataType diff --git a/src/occ_405/pgpe/pgpe_shared.h b/src/occ_405/pgpe/pgpe_shared.h index eb4b27a..0610953 100644 --- a/src/occ_405/pgpe/pgpe_shared.h +++ b/src/occ_405/pgpe/pgpe_shared.h @@ -5,7 +5,7 @@ /* */ /* OpenPOWER OnChipController Project */ /* */ -/* Contributors Listed Below - COPYRIGHT 2011,2016 */ +/* Contributors Listed Below - COPYRIGHT 2011,2017 */ /* [+] International Business Machines Corp. */ /* */ /* */ @@ -32,6 +32,9 @@ #define PGPE_SHARED_SRAM_ADDR_OFFSET 0x0c #define PGPE_SHARED_SRAM_SZ_OFFSET 0x14 #define PGPE_BEACON_ADDR_OFFSET 0x48 +#define PGPE_ACTIVE_QUAD_ADDR_OFFSET 0x4c +#define PGPE_WOF_TBLS_ADDR_OFFSET 0x50 +#define PGPE_WOF_TBLS_LEN_OFFSET 0x54 // PGPE Image Header Parameter addresses @@ -42,6 +45,12 @@ // A pointer to PGPE Beacon Address #define PGPE_BEACON_ADDR_PTR (PGPE_HEADER_ADDR + PGPE_BEACON_ADDR_OFFSET) +// Pointers to data needed by WOF +#define PGPE_ACTIVE_QUAD_ADDR_PTR (PGPE_HEADER_ADDR + PGPE_ACTIVE_QUAD_ADDR_OFFSET) +#define PGPE_WOF_TBLS_ADDR_PTR (PGPE_HEADER_ADDR + PGPE_WOF_TBLS_ADDR_OFFSET) +#define PGPE_WOF_TBLS_LEN_PTR (PGPE_HEADER_ADDR + PGPE_WOF_TBLS_LEN_OFFSET) + + // PMMR (Pstates PM region) in HOMMR #define PPMR_OPPM_ADDR_OFFSET 0x40 //offset of the OCC Pstates Parameter Block address in the PPMR header diff --git a/src/occ_405/wof/wof.c b/src/occ_405/wof/wof.c index 2adde1f..f222359 100644 --- a/src/occ_405/wof/wof.c +++ b/src/occ_405/wof/wof.c @@ -24,8 +24,114 @@ /* IBM_PROLOG_END_TAG */ #include <errl.h> #include <trac.h> +#include <sensor.h> +#include <occhw_async.h> #include "wof.h" +//****************************************************************************** +// Globals +//****************************************************************************** +uint32_t G_wof_active_quads_sram_addr; +uint32_t G_wof_tables_main_mem_addr; +uint32_t G_wof_tables_len; +bool G_run_wof_main; +wof_header_data_t G_wof_header __attribute__ ((section (".global_data"))); + + +/** + * wof_main + * + * Description: Main Wof algorithm + * + * Param: None + * + * Return: None + */ +void wof_main(void) +{ + + // TODO Read out necessary Sensor data for WOF calculation + // uint16_t l_current_vdd = getSensorByGsid(CURVDD)->sample; + // uint16_t l_current_vdn = getSensorByGsid(CURVDN)->sample + // Functions to calculate Ceff_vdd and Ceff_vdn here. + uint16_t ceff_vdd = 0; // TODO: replace with future function call + uint16_t ceff_vdn = 0; // TODO: replace with future function call + + + // Calculate how many steps from the beginning for VDD and VDN + uint16_t vdn_step_from_start = + calculate_step_from_start( ceff_vdd, + G_wof_header.vdn_step, + G_wof_header.vdn_start, + G_wof_header.vdn_size ); + + uint16_t vdd_step_from_start = + calculate_step_from_start( ceff_vdn, + G_wof_header.vdd_step, + G_wof_header.vdd_start, + G_wof_header.vdd_size ); + + // TODO: REMOVE THESE TRACES + // NOTE to Reviewers: This trace is here just to put references to the above + // variables such that compilation is successful. Will be removed in final + // version + TRAC_INFO("Step from start VDN = %d, VDN = %d", + vdn_step_from_start, + vdd_step_from_start ); + + + +} + + +/** + * calculate_step + * + * Description: Calculates the step number for the current VDN/VDD + * + * Param[in]: i_ceff_vdx - The current Ceff_vdd or Ceff_vdn to calculate the step + * for. + * Param[in]: i_step_size - The size of each step. + * Param[in]: i_min_ceff - The minimum step number for this VDN/VDD + * Param[in]: i_max_step - The maximum step number for this VDN/VDD + * + * Return: The calculated step for current Ceff_vdd/Ceff_vdn + */ +uint16_t calculate_step_from_start(uint16_t i_ceff_vdx, + uint8_t i_step_size, + uint8_t i_min_ceff, + uint8_t i_max_step ) +{ + uint16_t l_current_step; + + // Ensure ceff is at least the min step + if( (i_ceff_vdx <= i_min_ceff) || (i_step_size == 0) ) + { + l_current_step = 0; + } + else + { + // Add step size to current vdd/vdn to round up. + // -1 to prevent overshoot when i_ceff_vdx is equal to Ceff table value + l_current_step = i_ceff_vdx + i_step_size - 1; + + // Subtract the starting ceff to skip the 0 table entry + l_current_step -= i_min_ceff; + + // Divide by step size to determine how many from the 0 entry ceff is + l_current_step /= i_step_size; + + // If the calculated step is greater than the max step, use max step + if( l_current_step >= i_max_step ) + { + // Since function returns number of steps from start + // (first entry is 0 from start) subtract 1. + l_current_step = i_max_step-1; + } + } + + return l_current_step; +} diff --git a/src/occ_405/wof/wof.h b/src/occ_405/wof/wof.h index ba19383..6d3948d 100644 --- a/src/occ_405/wof/wof.h +++ b/src/occ_405/wof/wof.h @@ -27,14 +27,48 @@ - - //****************************************************************************** -// Globals +// Define //****************************************************************************** +#define MIN_BCE_REQ_SIZE 256 + + +typedef struct __attribute__ ((packed)) +{ + uint64_t magic_number; + uint8_t size_of_vfrt; + uint8_t vfrt_data_size; + uint8_t active_quads_start; + uint8_t active_quads_size; + uint8_t vdn_start; + uint8_t vdn_step; + uint8_t vdn_size; + uint8_t vdd_start; + uint8_t vdd_step; + uint8_t vdd_size; +} wof_header_data_t; + + + +typedef struct +{ + // There is no guarantee that we can fit everything into the min BceRequest + // size of 128 given that there may be a need to padding in the event the + // Main Memory address is not 128-byte aligned. The data here is 256 to + // ensure we have enough room for any and all padding that may be needed. + uint8_t data[MIN_BCE_REQ_SIZE]; +} temp_bce_request_buffer_t __attribute ((aligned(128))); //****************************************************************************** // Function Prototypes //****************************************************************************** + +void wof_main( void ); + +uint16_t calculate_step_from_start( uint16_t i_ceff_vdx, + uint8_t i_step_size, + uint8_t i_min_step, + uint8_t i_max_step ); + #endif |