summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/proc_shared.h1
-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
8 files changed, 345 insertions, 21 deletions
diff --git a/src/include/proc_shared.h b/src/include/proc_shared.h
index ecee9c0..71ad050 100644
--- a/src/include/proc_shared.h
+++ b/src/include/proc_shared.h
@@ -31,7 +31,6 @@
#include "gpe_export.h"
// Paramaters for gpe_get_core_data()
-
typedef struct ipc_core_data_parms
{
GpeErrorStruct error;
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