summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-07-17 21:57:58 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-07-28 13:04:48 -0500
commitb866f4173f605d8dcdf83b3239dd7fb9a5a8768b (patch)
treeabb7ddef100518198c44202293d9042b8922ae50 /src
parentac9ad22f261cd391c0d5163e82ff02ae4929f820 (diff)
downloadblackbird-hostboot-b866f4173f605d8dcdf83b3239dd7fb9a5a8768b.tar.gz
blackbird-hostboot-b866f4173f605d8dcdf83b3239dd7fb9a5a8768b.zip
Execute 'doze' in idle loop.
Change-Id: Ifd611129c2d7173b5e0dec36c870e06a4d851009 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1384 Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com> Reviewed-by: Daniel M. Crowell <dcrowell@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rwxr-xr-xsrc/build/debug/Hostboot/Ps.pm7
-rw-r--r--src/include/kernel/cpumgr.H3
-rw-r--r--src/include/kernel/ppcconsts.S23
-rw-r--r--src/include/kernel/syscalls.H2
-rw-r--r--src/include/kernel/task.H46
-rw-r--r--src/kernel/exception.C91
-rw-r--r--src/kernel/misc.C48
-rw-r--r--src/kernel/start.S79
-rw-r--r--src/kernel/syscall.C30
-rw-r--r--src/sys/prof/idletask.C59
10 files changed, 256 insertions, 132 deletions
diff --git a/src/build/debug/Hostboot/Ps.pm b/src/build/debug/Hostboot/Ps.pm
index a5a56ba02..e8a238c11 100755
--- a/src/build/debug/Hostboot/Ps.pm
+++ b/src/build/debug/Hostboot/Ps.pm
@@ -6,7 +6,7 @@
#
# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2011
+# COPYRIGHT International Business Machines Corp. 2011-2012
#
# p1
#
@@ -20,8 +20,7 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
-
+# IBM_PROLOG_END_TAG
use strict;
package Hostboot::Ps;
@@ -47,7 +46,7 @@ use constant PS_TRACKER_RETVAL_OFFSET => 8 + PS_TRACKER_STATUS_OFFSET;
use constant PS_TRACKER_WAITINFO_OFFSET => 8 + PS_TRACKER_RETVAL_OFFSET;
use constant PS_TRACKER_ENTRYPOINT_OFFSET => 8 + PS_TRACKER_WAITINFO_OFFSET;
-use constant PS_TASK_STATE_OFFSET => 8*42;
+use constant PS_TASK_STATE_OFFSET => 8*43;
use constant PS_TASK_STATEEXTRA_OFFSET => 8 + PS_TASK_STATE_OFFSET;
sub main
diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H
index bbd16fcd8..8cf6d0fc3 100644
--- a/src/include/kernel/cpumgr.H
+++ b/src/include/kernel/cpumgr.H
@@ -111,10 +111,11 @@ class CpuManager
/** Desired value for LPCR after wakeup.
*
* bit 49 - Wake-up from external interrupt.
+ * bit 50 - Wake-up from decrementer.
* bit 51 - Wake-up from machine check.
* bit 60, 61 - LPES(0,1) = 1 (see ISA).
*/
- static const uint64_t WAKEUP_LPCR_VALUE = 0x000000000000500C;
+ static const uint64_t WAKEUP_LPCR_VALUE = 0x000000000000700C;
protected:
CpuManager();
diff --git a/src/include/kernel/ppcconsts.S b/src/include/kernel/ppcconsts.S
index 89a52a008..1568bb911 100644
--- a/src/include/kernel/ppcconsts.S
+++ b/src/include/kernel/ppcconsts.S
@@ -1,25 +1,25 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
-#
+#
# $Source: src/include/kernel/ppcconsts.S $
-#
+#
# IBM CONFIDENTIAL
-#
-# COPYRIGHT International Business Machines Corp. 2010 - 2011
-#
+#
+# COPYRIGHT International Business Machines Corp. 2010-2012
+#
# p1
-#
+#
# Object Code Only (OCO) source materials
# Licensed Internal Code Source Materials
# IBM HostBoot Licensed Internal Code
-#
+#
# The source code for this program is not published or other-
# wise divested of its trade secrets, irrespective of what has
# been deposited with the U.S. Copyright Office.
-#
+#
# Origin: 30
-#
-# IBM_PROLOG_END
+#
+# IBM_PROLOG_END_TAG
#*--------------------------------------------------------------------*#
#* Register Constants *#
#*--------------------------------------------------------------------*#
@@ -206,8 +206,9 @@
.set TASK_CR, TASK_LR+8
.set TASK_CTR, TASK_CR+8
.set TASK_XER, TASK_CTR+8
+.set TASK_MSR_MASK, TASK_XER+8
-.set TASK_FP_CONTEXT, TASK_XER+8
+.set TASK_FP_CONTEXT, TASK_MSR_MASK+8
.set TASK_FPR_0, 0
.set TASK_FPR_1, TASK_FPR_0+8
.set TASK_FPR_2, TASK_FPR_1+8
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index 28e13628c..5523fc158 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -92,6 +92,8 @@ namespace Systemcalls
MISC_CPUSTARTCORE,
/** cpu_spr_value() */
MISC_CPUSPRVALUE,
+ /** cpu_doze() - Hidden syscall */
+ MISC_CPUDOZE,
/** mm_alloc_block() */
MM_ALLOC_BLOCK,
diff --git a/src/include/kernel/task.H b/src/include/kernel/task.H
index 9ff0401ba..f9ceab994 100644
--- a/src/include/kernel/task.H
+++ b/src/include/kernel/task.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/include/kernel/task.H $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2010 - 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/include/kernel/task.H $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2010-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
/** @file task.H
* @brief Defines kernel information about tasks.
*/
@@ -42,6 +43,7 @@ struct context_t
uint64_t cr;
uint64_t ctr;
uint64_t xer;
+ uint64_t msr_mask; // XOR mask applied to MSR.
};
/** @struct context_fp_t
diff --git a/src/kernel/exception.C b/src/kernel/exception.C
index 6115b5bd8..0d63d0a73 100644
--- a/src/kernel/exception.C
+++ b/src/kernel/exception.C
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/kernel/exception.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2010 - 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/kernel/exception.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2010-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
#include <assert.h>
#include <kernel/types.h>
#include <kernel/console.H>
@@ -29,14 +30,16 @@
#include <kernel/vmmmgr.H>
#include <kernel/cpuid.H>
#include <kernel/intmsghandler.H>
+#include <errno.h>
+#include <kernel/vmmmgr.H>
namespace ExceptionHandles
{
- bool HvEmulation(task_t*);
+ bool PrivInstr(task_t*);
}
const uint64_t EXCEPTION_SRR1_MASK = 0x00000000783F0000;
-const uint64_t EXCEPTION_SRR1_HVEMUL = 0x0000000000080000;
+const uint64_t EXCEPTION_SRR1_PRIVINS = 0x0000000000040000;
extern "C"
void kernel_execute_prog_ex()
@@ -47,9 +50,9 @@ void kernel_execute_prog_ex()
bool handled = false;
switch(exception)
{
- case EXCEPTION_SRR1_HVEMUL:
- handled = ExceptionHandles::HvEmulation(t);
- break;
+ case EXCEPTION_SRR1_PRIVINS:
+ handled = ExceptionHandles::PrivInstr(t);
+ break;
}
if (!handled)
{
@@ -157,22 +160,26 @@ void kernel_execute_hype_emu_assist()
namespace ExceptionHandles
{
- bool HvEmulation(task_t* t)
+ bool PrivInstr(task_t* t)
{
- /*printk("NIP = %lx : Inst = %x\n",
- t->context.nip,
- (*(uint32_t*)t->context.nip));*/
-
- uint32_t instruction = *(uint32_t*)t->context.nip;
-
- // check for mfsprg3
- if ((instruction & 0xfc1fffff) == 0x7c1342a6)
- {
- t->context.gprs[(instruction & 0x03E00000) >> 21] =
- (uint64_t) t;
- t->context.nip = (void*) (((uint64_t)t->context.nip)+4);
- return true;
- }
+ uint64_t phys_addr = VmmManager::findPhysicalAddress(
+ reinterpret_cast<uint64_t>(t->context.nip));
+
+ if (-EFAULT != static_cast<int64_t>(phys_addr))
+ {
+ uint32_t* instruction = reinterpret_cast<uint32_t*>(phys_addr);
+
+ // Check for 'doze' and skip over. This avoids a task-crash
+ // if for some reason we entered back into the task without
+ // priviledge raised.
+ if (*instruction == 0x4c000324)
+ {
+ printk("Error: Doze executed with lowered permissions on %d\n",
+ t->tid);
+ t->context.nip = static_cast<void*>(instruction + 1);
+ return true;
+ }
+ }
return false;
}
diff --git a/src/kernel/misc.C b/src/kernel/misc.C
index 74be12de1..a29aaea21 100644
--- a/src/kernel/misc.C
+++ b/src/kernel/misc.C
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/kernel/misc.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2011
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/kernel/misc.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2011-2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
#include <kernel/misc.H>
#include <kernel/cpumgr.H>
#include <kernel/cpuid.H>
@@ -84,6 +85,9 @@ namespace KernelMisc
printk("No payload... doze'ing all threads.\n");
}
+ // Clear LPCR values that wakes up from doze. LPCR[49, 50, 51]
+ setLPCR(getLPCR() & (~0x0000000000007000));
+
while(1)
{
doze();
diff --git a/src/kernel/start.S b/src/kernel/start.S
index 2e4cd1784..7d2d77845 100644
--- a/src/kernel/start.S
+++ b/src/kernel/start.S
@@ -146,11 +146,41 @@ finished_relocate:
.org _start + 0x100
intvect_system_reset:
- b _start
+ /* TODO: Add handling for SRESET from winkle for master. */
+ ;// Need to identify reason for SRESET and then perform appropriate
+ ;// action.
+ ;// Current support:
+ ;// - Decrementer wake-up from doze.
+ ;// - External interrupt (also wake-up from doze).
+ ;// - IPI wake-up from winkle of slave core.
+
+ ;// Free up two registers temporarily.
+ mtsprg0 r1
+ mtsprg1 r2
+
+ ;// Save CR.
+ mfcr r1
+
+ ;// Find bit 42:44 of SRR1 (reason for SRESET).
+ mfsrr1 r2
+ extrdi r2, r2, 3, 42
+ ;// Check for decrementer (bits = 011).
+ cmpi cr0, r2, 0x3
+ beq+ intvect_system_reset_decrementer
+ ;// Check for external interrupt (bits = 010).
+ cmpi cr0, r2, 0x4
+ beq+ intvect_system_reset_external
+ ;// Check for HMI (bits = 101).
+ cmpi cr0, r2, 0x5
+ beq+ _start
+ ;// Check for bits 000, which is probably a Simics bug right now.
+ cmpi cr0, r2, 0x0
+ beq+ _start
+1: ;// Unknown reason.
+ b 1b
-.org _start + 0x17C
-hbi_pre_phyp_breakpoint:
- attn; /* TODO: Add actual breakpoint attention. */
+.org _start + 0x180
+intvect_inst_start:
b _start
/* TODO: Eventually we likely need specific code for machine check
@@ -436,10 +466,10 @@ kernel_dispatch_task:
mfmsr r2 ;// Get current MSR
ori r2,r2, 0xC030 ;// Enable MSR[EE,PR,IR,DR].
- rldicl r2,r2,1,1 ;// Clear ...
- rotldi r2,r2,63 ;// MSR[TA]
rldicl r2,r2,50,1 ;// Clear ...
rotldi r2,r2,14 ;// MSR[FP]
+ ld r3, TASK_MSR_MASK(r1) ;// Load MSR mask.
+ xor r2, r2, r3 ;// Apply MSR mask (XOR).
mtsrr1 r2 ;// Set task MSR (SRR1)
ld r2, TASK_NIP(r1) ;// Load NIP from context.
@@ -544,7 +574,44 @@ kernel_dispatch_task:
b 2b
+ ;// @fn intvect_system_reset_decrementer
+ ;// Handle SRESET due to decrementer wake-up.
+ ;// This is a wake-up from 'doze'. Clear priviledge escalation and
+ ;// perform decrementer.
+intvect_system_reset_decrementer:
+ ;// Restore CR.
+ mtcr r1
+
+ ;// Clear MSR mask, since privilaged instruction was now executed (doze).
+ mfsprg3 r1 ;// Load task structure to r1.
+ li r2, 0 ;// Zero r2.
+ std r2, TASK_MSR_MASK(r1) ;// Zero msr_mask.
+
+ ;// Advance saved NIA (past doze).
+ mfsrr0 r1
+ addi r1, r1, 4
+ mtsrr0 r1
+
+ ;// Restore save registers.
+ mfsprg0 r1
+ mfsprg1 r2
+
+ b intvect_decrementer
+
+ ;// @fn intvect_system_reset_external
+ ;// Handle SRESET due to wake-up from external interrupt.
+ ;// This is a wake-up from 'doze', but not due to the decrementer
+ ;// itself firing. Therefore, leave 'doze' process state alone
+ ;// including NIA and handle the external interrupt.
+intvect_system_reset_external:
+ ;// Restore CR.
+ mtcr r1
+
+ ;// Restore save registers.
+ mfsprg0 r1
+ mfsprg1 r2
+ b intvect_external
;// @fn system_call_fast_path
;// Handle fast path system calls.
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 061971f96..6dcbe0c25 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -98,6 +98,7 @@ namespace Systemcalls
void CpuDDLevel(task_t *t);
void CpuStartCore(task_t *t);
void CpuSprValue(task_t *t);
+ void CpuDoze(task_t *t);
void MmAllocBlock(task_t *t);
void MmRemovePages(task_t *t);
void MmSetPermission(task_t *t);
@@ -133,6 +134,7 @@ namespace Systemcalls
&CpuDDLevel, // MISC_CPUDDLEVEL
&CpuStartCore, // MISC_CPUSTARTCORE
&CpuSprValue, // MISC_CPUSPRVALUE
+ &CpuDoze, // MISC_CPUDOZE
&MmAllocBlock, // MM_ALLOC_BLOCK
&MmRemovePages, // MM_REMOVE_PAGES
@@ -668,6 +670,34 @@ namespace Systemcalls
};
/**
+ * Allow a task to request priviledge escalation to execute the 'doze'
+ * instruction.
+ *
+ * Verifies the instruction to execute is, in fact, doze and then sets
+ * an MSR mask in the task structure to allow escalation on next
+ * execution.
+ *
+ * When 'doze' is executed the processor will eventually issue an
+ * SRESET exception with flags in srr1 to indication that the
+ * decrementer caused the wake-up. The kernel will then need to
+ * advance the task to the instruction after the doze and remove
+ * priviledge escalation.
+ *
+ */
+ void CpuDoze(task_t *t)
+ {
+
+ uint32_t* instruction = static_cast<uint32_t*>(t->context.nip);
+ if (0x4c000324 == (*instruction)) // Verify 'doze' instruction,
+ // otherwise just return.
+ {
+ // Disable PR, IR, DR so 'doze' can be executed.
+ // (which means to stay in HV state)
+ t->context.msr_mask = 0x4030;
+ }
+ };
+
+ /**
* Allocate a block of virtual memory within the base segment
* @param[in] t: The task used to allocate a block in the base segment
*/
diff --git a/src/sys/prof/idletask.C b/src/sys/prof/idletask.C
index 843f26628..da568f955 100644
--- a/src/sys/prof/idletask.C
+++ b/src/sys/prof/idletask.C
@@ -1,26 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/sys/prof/idletask.C $
-//
-// IBM CONFIDENTIAL
-//
-// COPYRIGHT International Business Machines Corp. 2012
-//
-// p1
-//
-// Object Code Only (OCO) source materials
-// Licensed Internal Code Source Materials
-// IBM HostBoot Licensed Internal Code
-//
-// The source code for this program is not published or other-
-// wise divested of its trade secrets, irrespective of what has
-// been deposited with the U.S. Copyright Office.
-//
-// Origin: 30
-//
-// IBM_PROLOG_END
-
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/sys/prof/idletask.C $
+ *
+ * IBM CONFIDENTIAL
+ *
+ * COPYRIGHT International Business Machines Corp. 2012
+ *
+ * p1
+ *
+ * Object Code Only (OCO) source materials
+ * Licensed Internal Code Source Materials
+ * IBM HostBoot Licensed Internal Code
+ *
+ * The source code for this program is not published or other-
+ * wise divested of its trade secrets, irrespective of what has
+ * been deposited with the U.S. Copyright Office.
+ *
+ * Origin: 30
+ *
+ * IBM_PROLOG_END_TAG
+ */
/** @file idletask.C
* @brief Code for the kernel idle-loop.
*
@@ -31,11 +31,22 @@
#include <kernel/taskmgr.H>
#include <arch/ppc.H>
+#include <sys/syscall.h>
+
+using namespace Systemcalls;
void TaskManager::idleTaskLoop(void* unused)
{
while(1)
{
- setThreadPriorityLow();
+ // Lower priority (and yield simics thread).
+ setThreadPriorityLow();
+
+ // Request privilege escalation for doze.
+ register uint64_t syscall = MISC_CPUDOZE;
+ asm volatile("or 3, %0, %0; sc" :: "r" (syscall) : "r3");
+
+ // Execute doze.
+ doze();
}
}
OpenPOWER on IntegriCloud