summaryrefslogtreecommitdiffstats
path: root/src/kernel/start.S
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-04-18 16:18:22 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-04-24 09:52:42 -0500
commitf2dd13f86d803e241b835c5ca2a2a14d583ba01e (patch)
treeb46bd46aa359a19e460f2382bb2127b08d0ec3e6 /src/kernel/start.S
parentf4e49418fd0743ab0d143f0ab3c505baefe58bfa (diff)
downloadtalos-hostboot-f2dd13f86d803e241b835c5ca2a2a14d583ba01e.tar.gz
talos-hostboot-f2dd13f86d803e241b835c5ca2a2a14d583ba01e.zip
Allow kernel to shutdown-to-payload.
This code is currently unused, due to InitService not having the payload address and the start_host_os IPL step being unimplemented. For testing purposes the 'shutdown' call in initservice.C can be changed to pass a non-zero base address (such as 256MB). RTC: 40871 Change-Id: I0f4b6bae62ede1853aabbcb28082300005e31897 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/926 Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com> Tested-by: Jenkins Server Reviewed-by: Douglas R. Gilbert <dgilbert@us.ibm.com>
Diffstat (limited to 'src/kernel/start.S')
-rw-r--r--src/kernel/start.S64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/kernel/start.S b/src/kernel/start.S
index c5af8652f..6d0eab195 100644
--- a/src/kernel/start.S
+++ b/src/kernel/start.S
@@ -640,6 +640,67 @@ task_end_stub:
li r4, 0 ;// NULL -> r4 (status value)
sc
+ ;// @fn kernel_shutdown
+ ;// Leave the Hostboot kernel and switch to the payload.
+ ;//
+ ;// This code must first move itself into "EA[0]=1" mode, migrate to a
+ ;// new HRMOR, and then jump to the new code. The migration of the
+ ;// HRMOR must be synchronized, since the HRMOR is a core-shared SPR, so
+ ;// we must first ensure that all threads are in "EA[0]=1" mode.
+ ;//
+ ;// @param[in] r3 - CPU count - Number of active CPUs.
+ ;// @param[in] r4 - Payload Base
+ ;// @param[in] r5 - Payload Entry
+.global kernel_shutdown
+kernel_shutdown:
+ ;// Set R6 to 0x8000000000000000 so we can set "EA[0]=1" for addrs.
+ li r6, 1
+ rotldi r6, r6, 63
+ ;// Retrieve existing HRMOR.
+ mfspr r7, HRMOR
+ ;// Determine physical address of shutdown_barrier.
+ lis r8, kernel_shutdown_barrier@h
+ ori r8, r8, kernel_shutdown_barrier@l
+ or r8, r8, r7 ;// Apply HRMOR.
+ or r8, r8, r6 ;// Apply EA[0] = 1.
+ ;// Determine physical address of EA[0]=1 mode instruction.
+ lis r9, kernel_shutdown_ea0_1_mode@h
+ ori r9, r9, kernel_shutdown_ea0_1_mode@l
+ or r9, r9, r7 ;// Apply HRMOR.
+ or r9, r9, r6 ;// Apply EA[0] = 1.
+ ;// Jump to enter EA[0] = 1
+ mtlr r9
+ blr
+kernel_shutdown_ea0_1_mode:
+ ;// Perform barrier
+ ;// Increment thread count.
+1:
+ ldarx r11, 0, r8
+ addi r11, r11, 1
+ stdcx. r11, 0, r8
+ bne- 1b
+ isync
+ ;// Wait for count to reach CPU count.
+1:
+ or 1,1,1 ;// Drop thread priority
+ ld r11, 0(r8)
+ cmpd cr0, r11, r3
+ bne 1b
+ ;// Instruction barrier to ensure exit.
+ isync
+ or 3,3,3 ;// Increase thread priority
+ ;// Update HRMOR.
+ ;// TODO: There might be more to it than just this, such as clearing
+ ;// ERATs but this works for now in Simics.
+ mtspr HRMOR, r4
+ ;// Set HSRR0 to entry point.
+ mtspr HSRR0, r5
+ ;// Save MSR, move to HSRR1.
+ mfmsr r10
+ mtspr HSRR1, r10
+ ;// TODO: Any updates we need to do to HSRR1/MSR for payload?
+ ;// Jump to entry point. Causes HSRR0 -> NIA, HSSR1 -> MSR.
+ hrfid
STD_INTERRUPT_NOADDR(hype_emu_assist)
@@ -652,6 +713,9 @@ kernel_stack:
kernel_other_thread_spinlock:
.space 8
+kernel_shutdown_barrier:
+ .space 8
+
.global hbi_ImageId
hbi_ImageId:
.space 128
OpenPOWER on IntegriCloud