diff options
-rw-r--r-- | src/include/arch/ppc.H | 11 | ||||
-rw-r--r-- | src/include/kernel/task.H | 7 | ||||
-rw-r--r-- | src/kernel/cpumgr.C | 1 | ||||
-rw-r--r-- | src/kernel/exception.C | 2 | ||||
-rw-r--r-- | src/kernel/start.S | 3 | ||||
-rw-r--r-- | src/kernel/syscall.C | 4 |
6 files changed, 15 insertions, 13 deletions
diff --git a/src/include/arch/ppc.H b/src/include/arch/ppc.H index 7e8b768c2..007f4f2b7 100644 --- a/src/include/arch/ppc.H +++ b/src/include/arch/ppc.H @@ -337,16 +337,7 @@ inline void icbi(void* _ptr) ALWAYS_INLINE inline void nap() { - // @todo-RTC:130186 Add new stop command support - //asm volatile("nap"); - - // Nap should be equivalent to 'stop 1' (no state loss) - // 855 reg for HYPV, 823 reg otherwise - // using EC(bit43) as 1 here (system reset or LPCR event) - // PHYP uses bit 42 as 1 also -// register uint64_t psscr = 0x0000000000310001; -// asm volatile("mtspr 823, %0; isync" :: "r" (psscr)); -// asm volatile(".long 0x4C0002E4"); // When GCC supports 'stop', use it + asm volatile(".long 0x4C0002E4"); // When GCC supports 'stop', use it } ALWAYS_INLINE diff --git a/src/include/kernel/task.H b/src/include/kernel/task.H index 0981dc3ab..c24084bf0 100644 --- a/src/include/kernel/task.H +++ b/src/include/kernel/task.H @@ -30,6 +30,13 @@ #include <kernel/types.h> + +// Stop/Nap instruction +#define STOP_INSTRUCTION 0x4C0002E4 +// Default PSSCR value for NAP'ing +#define PSSCR_NAP_VALUE 0x0000000000310001ull + + /** @struct context_t * @brief Defines the save-restore context for the task. * diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C index c1733bb7c..93248ea98 100644 --- a/src/kernel/cpumgr.C +++ b/src/kernel/cpumgr.C @@ -332,6 +332,7 @@ void CpuManager::activateCPU(cpu_t * i_cpu) kassert(WAKEUP_MSR_VALUE == msr); setLPCR(WAKEUP_LPCR_VALUE); setRPR(WAKEUP_RPR_VALUE); + setPSSCR(PSSCR_NAP_VALUE); // init NAP value (stop level 1) } void CpuManager::deactivateCPU(cpu_t * i_cpu) diff --git a/src/kernel/exception.C b/src/kernel/exception.C index 5b891ff63..dad6ff676 100644 --- a/src/kernel/exception.C +++ b/src/kernel/exception.C @@ -191,7 +191,7 @@ namespace ExceptionHandles // Check for 'nap' and skip over. This avoids a task-crash // if for some reason we entered back into the task without // privilege raised. - if (*instruction == 0x4c000364) + if (*instruction == STOP_INSTRUCTION) { printk("Error: Nap executed with lowered permissions on %d\n", t->tid); diff --git a/src/kernel/start.S b/src/kernel/start.S index f9b5a95ce..190717257 100644 --- a/src/kernel/start.S +++ b/src/kernel/start.S @@ -41,6 +41,9 @@ _start: mtsrr1 r2 li r2, _start_postmsr@l mtsrr0 r2 + lis r9,49 ;// Want to default the NAP value + ori r9,r9,1 ;// Value is 0x0000000000310001 + mtspr 855,r9 ;// set actual PSSCR rfid _start_postmsr: diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C index cc1cc3e5d..035f7c8e2 100644 --- a/src/kernel/syscall.C +++ b/src/kernel/syscall.C @@ -759,8 +759,8 @@ namespace Systemcalls { uint32_t* instruction = static_cast<uint32_t*>(t->context.nip); - if (0x4c000364 == (*instruction)) // Verify 'nap' instruction, - // otherwise just return. + if (STOP_INSTRUCTION == (*instruction)) // Verify 'nap' instruction, + // otherwise just return. { // Disable EE, PR, IR, DR so 'nap' can be executed. // (which means to stay in HV state) |