Skip to content

Commit

Permalink
PGPE: Add Comments(No functional change)
Browse files Browse the repository at this point in the history
    Key_Cronus_Test=PM_REGRESS

Change-Id: I51755982ff23cb5e2e0cac72eb06308a492fcccd
CQ: SW429661
Reviewed-on: http://ralgit01.raleigh.ibm.com/gerrit1/60312
Tested-by: FSP CI Jenkins <fsp-CI-jenkins+hostboot@us.ibm.com>
Tested-by: Jenkins Server <pfd-jenkins+hostboot@us.ibm.com>
Reviewed-by: Jennifer A. Stofer <stofer@us.ibm.com>
  • Loading branch information
rbatraAustinIBM authored and op-jenkins committed Jun 12, 2018
1 parent ee19339 commit 7da841c
Show file tree
Hide file tree
Showing 14 changed files with 710 additions and 197 deletions.
61 changes: 58 additions & 3 deletions import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,20 +137,75 @@ extern uint32_t G_OCB_OIMR0_CLR;


/// PGPE PState

//
// This is the common handler for OISR[2/OCC_ERROR], OISR[8/GPE3_ERROR],
// OISR[20/PVREF_ERROR] and OISR[50/PCB_TYPE5]
// All these interrupts are same priority in UIH(unified interrupt handler),
// but OCB_ERROR is higher priority from HW perspective so UIH will always
// call its handler. Therefore, we have one handler, and then check to see
// which interrupt(s) fired
//
void p9_pgpe_irq_handler_occ_sgpe_cme_pvref_error(void* arg, PkIrqId irq);

//
// Handles system xstop. PGPE does NOT do anything in response
// except logs it in the trace
//
void p9_pgpe_irq_handler_system_xstop(void* arg, PkIrqId irq);

//
// Handler for PCB Type 1 interrupt which is forwarding of Pstates
// Requests by CME
//
void p9_pgpe_irq_handler_pcb_type1(void* arg, PkIrqId irq);

//
// Handles PCB Type4 interrupts from CME which are CME registration
// messages.
void p9_pgpe_irq_handler_pcb_type4(void* arg, PkIrqId irq);

//
// Entry Point for Process Thread
//
void p9_pgpe_thread_process_requests(void* arg);

//
// Entry Point for Actuate Thread
//
void p9_pgpe_thread_actuate_pstates(void* arg);

///PGPE PState Info
//
// p9_pgpe_gen_pstate_info
//
// Generates Pstate info into main memory which then can be read.
//
// This function is called during PGPE boot. It writes data related to
// pstate as defined in the GeneratedPstateInfo struct in predetermined location
// in main memory. This data can then be read for informational and debug purpose.
// Note, There are multiple versions of GeneratedPstateInfo struct, but PGPE Hcode is
// built using one of them. The reason for multiple structs is to ensure compatibility with
// different versions of dump tool. Ideally, both PGPE Hcode and dump tool on machine will be
// built using the same version. However, during development where Hcode and dump tool are released
// independently of each other it is possible for versions to be different.
//
void p9_pgpe_gen_pstate_info();

///PGPE FIT
// p9_pgpe_fit_init
//
// This is called during PGPE Boot to intialize FIT(Fixed Internal Timer) related
// data.
// For nest frequency of 2000Mhz, it is expected FIT interrupt will happen
// every 262us
//
void p9_pgpe_fit_init();

///PGPE IPC
///
// p9_pgpe_ipc_init
//
// Called during PGPE initialziation to enable IPC functions
// and initialize static ipc task list
//
void p9_pgpe_ipc_init();

//IRQ initialization and setup
Expand Down
86 changes: 65 additions & 21 deletions import/chips/p9/procedures/ppe_closed/pgpe/pstate_gpe/p9_pgpe_fit.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,29 +59,35 @@ void (*p9_pgpe_auxiliary_task)() = (void*)OCC_SRAM_AUX_TASK_ADDR;


//
//Local function declarations
// Local function declarations
//
void p9_pgpe_fit_handler(void* arg, PkIrqId irq);

//
//p9_pgpe_fit_init
// p9_pgpe_fit_init
//
// This is called during PGPE Boot to intialize FIT(Fixed Internal Timer) related
// data.
// For nest frequency of 2000Mhz, it is expected FIT interrupt will happen
// every 262us
//
//We set fit_count_threshold based on nest frequency
//and also enable and setup the fit handler
void p9_pgpe_fit_init()
{
uint16_t freq = G_gppb->nest_frequency_mhz;

PK_TRACE_DBG("Fit NestFreq=0x%dMhz", G_gppb->nest_frequency_mhz);

//Set fit count threshold
//Set PGPE beacon count threshold. PGPE beacon should be incremented
//every 2ms. This is monitored by OCC
G_beacon_count_threshold = (freq < 1573) ? 6 :
(freq < 1835) ? 7 :
(freq < 2097) ? 8 :
(freq < 2359) ? 9 :
(freq < 2621) ? 10 : 11;
PK_TRACE_DBG("Fit BeaconThr=0x%d", G_beacon_count_threshold);
//ATTR_AUX_FUNC_INVOCATION_TIME_MS * 1 ms

//Determine how often to call the auxillary function. It should be
//attribute ATTR_AUX_FUNC_INVOCATION_TIME_MS * 1 ms
G_aux_task_count_threshold = (freq < 1573) ? 3 :
(freq < 2097) ? 4 :
(freq < 2621) ? 5 : 6;
Expand All @@ -97,20 +103,34 @@ void p9_pgpe_fit_init()
#else
uint32_t tsel = 0xA;
#endif

//Determine how often to sync timebase
G_tb_sync_count_threshold = ((0x2 << tsel) - 1);
//Calculated to be twice the interval between FIT interrupts in Quad HBR
PK_TRACE_DBG("Fit TimebaseSyncThr=0x%d", G_tb_sync_count_threshold);

//Determine PGPE heartbeat value to be written in each quad(monitored by CME)
//This should be twice the interval between FIT interrupts in Quad HBR
//ticks
uint32_t sub = (((1 << (29 - tsel)) / G_gppb->nest_frequency_mhz) <<
4) * (G_beacon_count_threshold + 1);
G_quad_hb_value = ((0x10000 - sub) << 16) | BIT32(OCB_OCI_OCCHBR_OCC_HEARTBEAT_EN);
PK_TRACE_DBG("Fit TimebaseSyncThr=0x%d", G_tb_sync_count_threshold);

G_throttleOn = 0;
G_throttleCount = 0;
G_beacon_count = 0;
G_tb_sync_count = 0;

//Set FIT handler which is called on every FIT interrupt tick
ppe42_fit_setup(p9_pgpe_fit_handler, NULL);
}


//
// handle_core_throttle
//
// This function throttle/unthrottle the cores as determine by the OCC Scratch Register2 fields
//
//
__attribute__((always_inline)) inline void handle_core_throttle()
{
uint32_t config = in32(G_OCB_OCCS2); //bits 16-18 in OCC Scratch Register 2
Expand Down Expand Up @@ -181,10 +201,15 @@ __attribute__((always_inline)) inline void handle_quad_hb_update()
}
}

//PGPE beacon needs to be written every 2ms. However, we
//set the FIT interrupt period smaller than that, and
//update PGPE beacon only when we have seen "G_beacon_count_threshold"
//number of FIT interrupts
//
// handle_occ_beacon
//
// Updates Heart Beat Register in every quad, and increments PGPE Beacon
//
// PGPE beacon needs to be written every 2ms. However, we
// set the FIT interrupt period smaller than that, and
// update PGPE beacon only when we have seen "G_beacon_count_threshold"
// number of FIT interrupts
__attribute__((always_inline)) inline void handle_occ_beacon()
{
if (G_beacon_count == G_beacon_count_threshold)
Expand All @@ -205,6 +230,12 @@ __attribute__((always_inline)) inline void handle_occ_beacon()
}
}

//
// handle_occflg_requests
//
// This function samples OCCFLG[0/Pstate Stop,2/Safe mode Request,3/PM Complex Suspend] and
// updates PstateStatus accordingly
//
__attribute__((always_inline)) inline void handle_occflg_requests()
{
ocb_occflg_t occFlag;
Expand Down Expand Up @@ -263,10 +294,16 @@ __attribute__((always_inline)) inline void handle_occflg_requests()
}
}

//PGPE characterization thread is called based on . However, we
//set the FIT interrupt period smaller than that, and
//call characterization method only when we have seen "G_characterization_count_threshold"
//number of FIT interrupts
//
// handle_aux_task
//
// This function calls auxilliary task if enabled at period determined
// by G_aux_task_count_threshold
//
// PGPE characterization thread is called based on OCB_OCCFLG[AUX_THREAD_ACTIVATE] .
// We set the FIT interrupt period smaller than that, and
// call characterization method only when we have seen "G_aux_task_count_threshold"
// number of FIT interrupts
__attribute__((always_inline)) inline void handle_aux_task()
{
if(in32(G_OCB_OCCFLG) & BIT32(AUX_THREAD_ACTIVATE))
Expand All @@ -289,8 +326,14 @@ __attribute__((always_inline)) inline void handle_aux_task()
}
}

//FIT Timebase Sync is called every time bottom 3B of OTBR
//roll over so it's clear in tracing how much time has passed

//
// handle_fit_timebase_sync
//
// This function syncs up timebase for pgpe op trace
//
// FIT Timebase Sync is called every time bottom 3B of OTBR
// roll over so it's clear in tracing how much time has passed
__attribute__((always_inline)) inline void handle_fit_timebase_sync()
{
if (G_tb_sync_count == G_tb_sync_count_threshold)
Expand Down Expand Up @@ -323,10 +366,11 @@ __attribute__((always_inline)) inline void handle_fit_timebase_sync()
}
}

//p9_pgpe_fit_handler
// p9_pgpe_fit_handler
//
// This is a periodic FIT Handler which is called up at fixed period
// as determined by GPE_TIMER_SELECT register
//
//This is a periodic FIT Handler whose period is determined
//by GPE_TIMER_SELECT register
void p9_pgpe_fit_handler(void* arg, PkIrqId irq)
{

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,18 @@ void p9_pgpe_gen_occ_pstate_tbl();
void p9_pgpe_gen_vratio_vindex_tbl(VRatioVIndexTable* tbl);

//
//p9_pgpe_gen_pstate_info
// p9_pgpe_gen_pstate_info
//
// Generates Pstate info into main memory which then can be read.
//
// This function is called during PGPE boot. It writes data related to
// pstate as defined in the GeneratedPstateInfo struct in predetermined location
// in main memory. This data can then be read for informational and debug purpose.
// Note, There are multiple versions of GeneratedPstateInfo struct, but PGPE Hcode is
// built using one of them. The reason for multiple structs to ensure compatibility with
// different versions of dump tool. Ideally, both PGPE Hcode and dump tool on machine will be
// built using the same version. However, during development where Hcode and dump tool are released
// independently of each other it is possible for versions to be different
void p9_pgpe_gen_pstate_info()
{
uint32_t* ps0, *highest_pstate;
Expand Down Expand Up @@ -155,10 +165,11 @@ void p9_pgpe_gen_pstate_info()
}

//
//p9_pgpe_gen_raw_pstates
// p9_pgpe_gen_raw_pstates
//
//Generates pstate table without biasing
// Generates pstate table using VPD without biasing applied
//
// tbl - Pointer to where Pstate Table is to be written
void p9_pgpe_gen_raw_pstates(PstateTable* tbl)
{
int32_t p;
Expand All @@ -183,10 +194,11 @@ void p9_pgpe_gen_raw_pstates(PstateTable* tbl)
}

//
//p9_pgpe_gen_biased_pstates
// p9_pgpe_gen_biased_pstates
//
//Generates pstate table with biasing and system parameters
// Generates pstate table using VPD with biasing and system parameters applied
//
// tbl - Pointer to where Pstate Table is to be written
void p9_pgpe_gen_biased_pstates(PstateTable* tbl)
{
int32_t p;
Expand All @@ -213,9 +225,9 @@ void p9_pgpe_gen_biased_pstates(PstateTable* tbl)


//
//p9_pgpe_gen_occ_pstate_tbl
// p9_pgpe_gen_occ_pstate_tbl
//
//Generates pstate table for OCC consumption
// Generates pstate table for OCC consumption
//
void p9_pgpe_gen_occ_pstate_tbl()
{
Expand All @@ -233,7 +245,12 @@ void p9_pgpe_gen_occ_pstate_tbl()
PK_TRACE_DBG("INIT: Generated OCC Tbl");
}


//
// p9_pgpe_gen_vratio_vindex_tbl
//
// Generates WOF(Workload Optimized Frequency) vratio/vindex table
//
// tbl - Pointer to where vratio/vindex table is to be written
void p9_pgpe_gen_vratio_vindex_tbl(VRatioVIndexTable* tbl)
{
uint32_t ac, sc, idx = 0;
Expand Down

0 comments on commit 7da841c

Please sign in to comment.