-
-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added
OSSetPerformanceMonitor()
. (#400)
* Added `OSSetPerformanceMonitor()`. --HG-- branch : perf-mon * Renamed everything. --HG-- branch : perf-mon * Added header to tests. --HG-- branch : perf-mon --------- Co-authored-by: Daniel K. O. (dkosmari) <none@none>
- Loading branch information
Showing
2 changed files
with
207 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
#pragma once | ||
#include <wut.h> | ||
|
||
/** | ||
* \defgroup coreinit_performancemonitor Performance Monitor | ||
* \ingroup coreinit | ||
* | ||
* @{ | ||
*/ | ||
|
||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
|
||
/// Used to tell OSSetPerformanceMonitor() which arguments are valid. | ||
typedef enum OSPerfMonArg { | ||
OS_PM_ARG_MMCR0 = 1u << 0u, | ||
OS_PM_ARG_MMCR1 = 1u << 1u, | ||
OS_PM_ARG_PMC1 = 1u << 2u, | ||
OS_PM_ARG_PMC2 = 1u << 3u, | ||
OS_PM_ARG_PMC3 = 1u << 4u, | ||
OS_PM_ARG_PMC4 = 1u << 5u, | ||
} OSPerfMonArg; | ||
|
||
/** | ||
* Flags to write to (U)MMCR0 register. | ||
* | ||
* \sa OSSetPerformanceMonitor | ||
*/ | ||
typedef enum OSPerfMonMMCR0Flags { | ||
OS_PM_MMCR0_PMC1_CURRENT = 0b0000000u << 6, | ||
OS_PM_MMCR0_PMC1_CPU_CYCLES = 0b0000001u << 6, | ||
OS_PM_MMCR0_PMC1_INSTRUCTIONS_COMPLETED = 0b0000010u << 6, | ||
OS_PM_MMCR0_PMC1_TBL_RISING_TRANSITIONS = 0b0000011u << 6, | ||
OS_PM_MMCR0_PMC1_INSTRUCTIONS_DISPATCHED = 0b0000100u << 6, | ||
OS_PM_MMCR0_PMC1_EIEIO_INSTRUCTIONS_COMPLETED = 0b0000101u << 6, | ||
OS_PM_MMCR0_PMC1_ITLB_SEARCH_CYCLES = 0b0000110u << 6, | ||
OS_PM_MMCR0_PMC1_L2_HITS = 0b0000111u << 6, | ||
OS_PM_MMCR0_PMC1_INSTRUCTIONS_EA_DELIVERED = 0b0001000u << 6, | ||
OS_PM_MMCR0_PMC1_INSTRUCTIONS_COMPLETED_MATCHES_IABR = 0b0001001u << 6, | ||
OS_PM_MMCR0_PMC1_SLOW_L1_MISSES = 0b0001010u << 6, | ||
OS_PM_MMCR0_PMC1_UNRESOLVED_BRANCHES = 0b0001011u << 6, | ||
OS_PM_MMCR0_PMC1_UNRESOLVED_STALL_CYCLES = 0b0001100u << 6, | ||
OS_PM_MMCR0_PMC1_L1_SHARED_STORES = 0b0001110u << 6, | ||
OS_PM_MMCR0_PMC1_L2_SHARED_INTERVENTIONS = 0b0001111u << 6, | ||
OS_PM_MMCR0_PMC1_CACHE_PARADOXES = 0b0010000u << 6, | ||
OS_PM_MMCR0_PMC1_CIU_LOAD_REQUESTS = 0b0010100u << 6, | ||
OS_PM_MMCR0_PMC1_BIU_ADDRESS_ONLY_REQUESTS = 0b0010101u << 6, | ||
OS_PM_MMCR0_PMC1_CIU_PARADOXES = 0b0010110u << 6, | ||
OS_PM_MMCR0_PMC1_60XE_BUS_DATA_BEATS = 0b0010111u << 6, | ||
|
||
OS_PM_MMCR0_PMC2_CURRENT = 0b000000u, | ||
OS_PM_MMCR0_PMC2_CPU_CYCLES = 0b000001u, | ||
OS_PM_MMCR0_PMC2_INSTRUCTIONS_COMPLETED = 0b000010u, | ||
OS_PM_MMCR0_PMC2_TBL_RISING_TRANSITIONS = 0b000011u, | ||
OS_PM_MMCR0_PMC2_INSTRUCTIONS_DISPATCHED = 0b000100u, | ||
OS_PM_MMCR0_PMC2_L1_ICACHE_MISSES = 0b000101u, | ||
OS_PM_MMCR0_PMC2_ITLB_MISSES = 0b000110u, | ||
OS_PM_MMCR0_PMC2_L2_INSTRUCTION_MISSES = 0b000111u, | ||
OS_PM_MMCR0_PMC2_PRED_BRANCHES_NOT_TAKEN = 0b001000u, | ||
OS_PM_MMCR0_PMC2_RESERVED_LOADS = 0b001010u, | ||
OS_PM_MMCR0_PMC2_LOADS_AND_STORES = 0b001011u, | ||
OS_PM_MMCR0_PMC2_CACHE_SNOOPS = 0b001100u, | ||
OS_PM_MMCR0_PMC2_L1_TO_L2_CASTOUTS = 0b001101u, | ||
OS_PM_MMCR0_PMC2_SYSTEM_UNIT_INSTRUCTIONS = 0b001110u, | ||
OS_PM_MMCR0_PMC2_L1_INSTRUCTION_MISS_CYCLES = 0b001111u, | ||
OS_PM_MMCR0_PMC2_FIRST_SPECULATIVE_BRANCH_RESOLVES = 0b010000u, | ||
OS_PM_MMCR0_PMC2_L2_SHARED_STORES = 0b010001u, | ||
OS_PM_MMCR0_PMC2_L1_SHARED_INTERVENTIONS = 0b010010u, | ||
OS_PM_MMCR0_PMC2_CIU_STORE_REQUESTS = 0b010100u, | ||
OS_PM_MMCR0_PMC2_SLOW_OUTSTANDING_BIU_TRANSACTIONS = 0b010101u, | ||
OS_PM_MMCR0_PMC2_CIU_MODIFIED_INTERVENTIONS = 0b010110u, | ||
} OSPerfMonMMCR0Flags; | ||
|
||
/** | ||
* Flags to write to (U)MMCR1 register. | ||
* | ||
* \sa OSSetPerformanceMonitor | ||
*/ | ||
typedef enum OSPerfMonMMCR1Flags { | ||
OS_PM_MMCR1_PMC3_CURRENT = 0b00000u << 27, | ||
OS_PM_MMCR1_PMC3_CPU_CYCLES = 0b00001u << 27, | ||
OS_PM_MMCR1_PMC3_INSTRUCTIONS_COMPLETED = 0b00010u << 27, | ||
OS_PM_MMCR1_PMC3_TBL_RISING_TRANSITIONS = 0b00011u << 27, | ||
OS_PM_MMCR1_PMC3_INSTRUCTIONS_DISPATCHED = 0b00100u << 27, | ||
OS_PM_MMCR1_PMC3_L1_DCACHE_MISSES = 0b00101u << 27, | ||
OS_PM_MMCR1_PMC3_DTLB_MISSES = 0b00110u << 27, | ||
OS_PM_MMCR1_PMC3_L2_DATA_MISSES = 0b00111u << 27, | ||
OS_PM_MMCR1_PMC3_PRED_BRANCHES_TAKEN = 0b01000u << 27, | ||
OS_PM_MMCR1_PMC3_COND_STORES_COMPLETED = 0b01010u << 27, | ||
OS_PM_MMCR1_PMC3_FPU_INSTRUCTIONS_COMPLETED = 0b01011u << 27, | ||
OS_PM_MMCR1_PMC3_L2_CASTOUTS_BY_SNOOPS = 0b01100u << 27, | ||
OS_PM_MMCR1_PMC3_L2_CACHE_OPERATIONS = 0b01101u << 27, | ||
OS_PM_MMCR1_PMC3_L1_LOAD_MISS_CYCLES = 0b01111u << 27, | ||
OS_PM_MMCR1_PMC3_SECOND_SPECULATIVE_BRANCH_RESOLVES = 0b10000u << 27, | ||
OS_PM_MMCR1_PMC3_BPU_STALL_LR_CR_CYCLES = 0b10001u << 27, | ||
OS_PM_MMCR1_PMC3_L1_MODIFIED_INTERVENTIONS = 0b10010u << 27, | ||
OS_PM_MMCR1_PMC3_ICBI_SNOOPS = 0b10011u << 27, | ||
OS_PM_MMCR1_PMC3_CIU_ADDRESS_ONLY_REQUESTS = 0b10100u << 27, | ||
OS_PM_MMCR1_PMC3_BIU_LOAD_REQUESTS = 0b10101u << 27, | ||
OS_PM_MMCR1_PMC3_CIU_SHARED_INTERVENTIONS = 0b10110u << 27, | ||
|
||
OS_PM_MMCR1_PMC4_CURRENT = 0b00000u << 22, | ||
OS_PM_MMCR1_PMC4_CPU_CYCLES = 0b00001u << 22, | ||
OS_PM_MMCR1_PMC4_INSTRUCTIONS_COMPLETED = 0b00010u << 22, | ||
OS_PM_MMCR1_PMC4_TBL_RISING_TRANSITIONS = 0b00011u << 22, | ||
OS_PM_MMCR1_PMC4_INSTRUCTIONS_DISPATCHED = 0b00100u << 22, | ||
OS_PM_MMCR1_PMC4_L2_CASTOUTS = 0b00101u << 22, | ||
OS_PM_MMCR1_PMC4_DTLB_SEARCH_CYCLES = 0b00110u << 22, | ||
OS_PM_MMCR1_PMC4_BRANCHES_MISPREDICTED = 0b01000u << 22, | ||
OS_PM_MMCR1_PMC4_INTACT_COND_STORES_COMPLETED = 0b01010u << 22, | ||
OS_PM_MMCR1_PMC4_SYNC_INSTRUCTIONS_COMPLETED = 0b01011u << 22, | ||
OS_PM_MMCR1_PMC4_SNOOP_RETRIES = 0b01100u << 22, | ||
OS_PM_MMCR1_PMC4_INTEGER_OPERATIONS = 0b01101u << 22, | ||
OS_PM_MMCR1_PMC4_BPU_STALL_TWO_BRANCHES_CYCLES = 0b01110u << 22, | ||
OS_PM_MMCR1_PMC4_L2_MODIFIED_INTERVENTIONS = 0b10000u << 22, | ||
OS_PM_MMCR1_PMC4_TLBIE_SNOOPS = 0b10001u << 22, | ||
OS_PM_MMCR1_PMC4_L2_BANK_REFRESH_OVERFLOWS = 0b10010u << 22, | ||
OS_PM_MMCR1_PMC4_CIU_ARTRY_COUNT = 0b10100u << 22, | ||
OS_PM_MMCR1_PMC4_BIU_STORE_REQUESTS = 0b10101u << 22, | ||
OS_PM_MMCR1_PMC4_CIU_TWO_CORE_SHARED_INTERVENTIONS = 0b10110u << 22, | ||
} OSPerfMonMMCR1Flags; | ||
|
||
/** | ||
* Write to performance monitor registers. | ||
* | ||
* Performance monitor registers can only be written by the kernel, this allows userspace | ||
* to write to them. | ||
* | ||
* \param arg_mask OR-ed values from `OSPerfMonArg`, indicating which of the following | ||
* arguments are to be written to registers. | ||
* | ||
* \param mmcr0 OR-ed values from `OSPerfMonMMCR0Flags` to write to register MMCR0. | ||
* \param mmcr1 OR-ed values from `OSPerfMonMMCR1Flags` to write to register MMCR1. | ||
* \param pmc1 Value to write to register PMC1. | ||
* \param pmc2 Value to write to register PMC2. | ||
* \param pmc3 Value to write to register PMC3. | ||
* \param pmc4 Value to write to register PMC4. | ||
*/ | ||
void OSSetPerformanceMonitor(uint32_t arg_mask, | ||
uint32_t mmcr0, | ||
uint32_t mmcr1, | ||
uint32_t pmc1, | ||
uint32_t pmc2, | ||
uint32_t pmc3, | ||
uint32_t pmc4); | ||
|
||
/** | ||
* Convenience function to read from UPMC1. | ||
*/ | ||
static inline | ||
uint32_t | ||
OSGetUPMC1() | ||
{ | ||
uint32_t result; | ||
asm("mfupmc1 %[result]" | ||
: [result] "=r"(result)); | ||
return result; | ||
} | ||
|
||
/** | ||
* Convenience function to read from UPMC2. | ||
*/ | ||
static inline | ||
uint32_t | ||
OSGetUPMC2() | ||
{ | ||
uint32_t result; | ||
asm("mfupmc2 %[result]" | ||
: [result] "=r"(result)); | ||
return result; | ||
} | ||
|
||
/** | ||
* Convenience function to read from UPMC3. | ||
*/ | ||
static inline | ||
uint32_t | ||
OSGetUPMC3() | ||
{ | ||
uint32_t result; | ||
asm("mfupmc3 %[result]" | ||
: [result] "=r"(result)); | ||
return result; | ||
} | ||
|
||
/** | ||
* Convenience function to read from UPMC4. | ||
*/ | ||
static inline | ||
uint32_t | ||
OSGetUPMC4() | ||
{ | ||
uint32_t result; | ||
asm("mfupmc4 %[result]" | ||
: [result] "=r"(result)); | ||
return result; | ||
} | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
|
||
/** @} */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters