summaryrefslogtreecommitdiffstats
path: root/src/occ_405
diff options
context:
space:
mode:
authorAndres Lugo-Reyes <aalugore@us.ibm.com>2016-12-19 16:07:30 -0600
committerWilliam A. Bryan <wilbryan@us.ibm.com>2017-02-01 11:06:24 -0500
commit009f439d2aa9df1944eb08b7f1fc30006abd8137 (patch)
tree719f526548b4c125984d45aeaa30051ae32c7afe /src/occ_405
parent11bf85d22eed50613085dfea02c4df9e53e1a380 (diff)
downloadtalos-occ-009f439d2aa9df1944eb08b7f1fc30006abd8137.tar.gz
talos-occ-009f439d2aa9df1944eb08b7f1fc30006abd8137.zip
WOF: Function to calculate VDD/VDN step number
1. Calculate VDN/VDD step number 2. Extract the WOF header address from the PGPE header 3. Save important data from WOF header into global struct 4. Create global pointer struct to save important addresses to a pinned location in memory. Change-Id: I2249777134608d9f79bdc85692a3acbf7907c3f5 RTC:130216 Depends-on: Ic323321b8c66945732a6b7345ad85d6f41a62edd Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/34300 Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com> Reviewed-by: William A. Bryan <wilbryan@us.ibm.com>
Diffstat (limited to 'src/occ_405')
-rwxr-xr-xsrc/occ_405/amec/amec_slave_smh.c16
-rwxr-xr-xsrc/occ_405/linkocc.cmd33
-rwxr-xr-xsrc/occ_405/main.c156
-rw-r--r--src/occ_405/occ_service_codes.h3
-rw-r--r--src/occ_405/pgpe/pgpe_shared.h11
-rw-r--r--src/occ_405/wof/wof.c106
-rw-r--r--src/occ_405/wof/wof.h40
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
OpenPOWER on IntegriCloud