summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2012-07-31 10:26:12 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2012-08-10 11:38:42 -0500
commit99f217daf307b3cd963bcbce8eb7b025d58f734e (patch)
tree87a82faba5be946460ff25f222f0f10a03afdfce /src
parentda472c60655393f0bb49113713a8be2bdd2a9b6f (diff)
downloadtalos-hostboot-99f217daf307b3cd963bcbce8eb7b025d58f734e.tar.gz
talos-hostboot-99f217daf307b3cd963bcbce8eb7b025d58f734e.zip
Support for master winkle.
RTC: 44730 Change-Id: Ifaeecc659e1bfd8ded4744dc591fc993471519ba Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/1471 Tested-by: Jenkins Server Reviewed-by: Mark W. Wenning <wenning@us.ibm.com> Reviewed-by: A. Patrick Williams III <iawillia@us.ibm.com>
Diffstat (limited to 'src')
-rw-r--r--src/build/citest/etc/bbuild2
-rw-r--r--src/build/citest/etc/patches/p8.chip.patch32
-rw-r--r--src/build/citest/etc/patches/p8_inst.act1275
-rw-r--r--src/build/citest/etc/patches/p8_master.por.patch17
-rw-r--r--src/build/citest/etc/patches/patchlist.txt5
-rwxr-xr-xsrc/build/citest/etc/workarounds.postsimsetup11
-rw-r--r--src/include/arch/ppc.H14
-rw-r--r--src/include/kernel/cpu.H55
-rw-r--r--src/include/kernel/cpumgr.H43
-rw-r--r--src/include/kernel/deferred.H201
-rw-r--r--src/include/kernel/misc.H29
-rw-r--r--src/include/kernel/ppcconsts.S23
-rw-r--r--src/include/kernel/syscalls.H6
-rw-r--r--src/include/sys/misc.h3
-rw-r--r--src/kernel.ld5
-rw-r--r--src/kernel/cpumgr.C101
-rw-r--r--src/kernel/deferred.C268
-rw-r--r--src/kernel/exception.C30
-rw-r--r--src/kernel/kernel.C47
-rw-r--r--src/kernel/makefile8
-rw-r--r--src/kernel/misc.C82
-rw-r--r--src/kernel/start.S181
-rw-r--r--src/kernel/syscall.C53
-rw-r--r--src/lib/syscall_misc.C10
-rw-r--r--src/makefile3
-rw-r--r--src/sys/prof/idletask.C10
-rw-r--r--src/usr/hwpf/hwp/core_activate/core_activate.C9
27 files changed, 2222 insertions, 301 deletions
diff --git a/src/build/citest/etc/bbuild b/src/build/citest/etc/bbuild
index 91bbd50e7..89125a7b5 100644
--- a/src/build/citest/etc/bbuild
+++ b/src/build/citest/etc/bbuild
@@ -1 +1 @@
-/esw/fips810/Builds/b0719a_1229.810
+/esw/fips810/Builds/b0727a_1231.810
diff --git a/src/build/citest/etc/patches/p8.chip.patch b/src/build/citest/etc/patches/p8.chip.patch
deleted file mode 100644
index cd9227b20..000000000
--- a/src/build/citest/etc/patches/p8.chip.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-##### from src/build/etc/patches/p8_master.por.patch
-
-ACTIONS=p8_inst.act
-
-#dc01
-########################## Logical Instruction State ###################
-REGSPACE THREADSTATE CHIPLET ex
- ### Current State ###
- # 0: thread is in POR state
- # 1: thread is quiesced
- # 2: thread is running
- # 3: thread is in maint mode
- # 4: thread is active (not in SLEEP or NAP or POR)
- # 5: thread is in NAP state
- # 6: thread is in SLEEP state
- # 7: thread is in WINKLE state
-
- # One register per thread
- 0x0, 32
- 0x1, 32
- 0x2, 32
- 0x3, 32
- 0x4, 32
- 0x5, 32
- 0x6, 32
- 0x7, 32
-
-END
-
-##### end patch
diff --git a/src/build/citest/etc/patches/p8_inst.act b/src/build/citest/etc/patches/p8_inst.act
index 523acd32b..f9b47ae21 100644
--- a/src/build/citest/etc/patches/p8_inst.act
+++ b/src/build/citest/etc/patches/p8_inst.act
@@ -2,7 +2,8 @@
# Flag PTR/DCR# Userid Date Description
# ---- -------- -------- -------- -----------
-# D841334 dcrowell 06/11/11 File Created
+# D841334 dcrowell 06/11/11 File Created
+# @01 D846452 dcrowell 07/31/12 Add Winkle/IPI support
# Actions work like this:
@@ -11,10 +12,6 @@
#
# See p8.chip for THREADSTATE bit definitions
-#NOTE: Hostboot patched version is hardcoded to Core5
-#NOTE: Hostboot patched version does not set NIA for SRESET
-
-
###################
## Scom Triggers ##
@@ -24,8 +21,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt0]
WATCH=[REG(MYCHIPLET,0x013000)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013000)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 0)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 0)] OP=[MODULECALL]
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 0)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 0)] OP=[MODULECALL]
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x0)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -36,8 +33,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt1]
WATCH=[REG(MYCHIPLET,0x013010)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013010)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 1)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 1)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 1)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 1)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x1)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -48,8 +45,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt2]
WATCH=[REG(MYCHIPLET,0x013020)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013020)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 2)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 2)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 2)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 2)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x2)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -60,8 +57,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt3]
WATCH=[REG(MYCHIPLET,0x013030)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013030)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 3)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 3)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 3)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 3)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x3)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -72,8 +69,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt4]
WATCH=[REG(MYCHIPLET,0x013040)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013040)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 4)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 4)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 4)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 4)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x4)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -84,8 +81,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt5]
WATCH=[REG(MYCHIPLET,0x013050)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013050)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 5)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 5)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 5)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 5)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x5)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -96,8 +93,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt6]
WATCH=[REG(MYCHIPLET,0x013060)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013060)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 6)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 6)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 6)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 6)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x6)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -108,8 +105,8 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Sreset Instructions - cXt7]
WATCH=[REG(MYCHIPLET,0x013070)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013070)] OP=[BIT,ON] BIT=[60] # SRESET
- #EFFECT: TARGET=[PROCREG(nia, 5, 7)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
- EFFECT: TARGET=[MODULE(startInstructions, 5, 7)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[PROCREG(nia, MYCORE, 7)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000100)]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 7)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode, and all idle states
# Set running, active
EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x7)] OP=[EQUALTO,BUF] DATA=[LITERAL(32,28000000)]
@@ -123,7 +120,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt0]
WATCH=[REG(MYCHIPLET,0x013000)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013000)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 0)] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 0)] OP=[MODULECALL]
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -135,7 +132,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt1]
WATCH=[REG(MYCHIPLET,0x013010)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013010)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 1)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 1)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -147,7 +144,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt2]
WATCH=[REG(MYCHIPLET,0x013020)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013020)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 2)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 2)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -159,7 +156,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt3]
WATCH=[REG(MYCHIPLET,0x013030)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013030)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 3)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 3)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -171,7 +168,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt4]
WATCH=[REG(MYCHIPLET,0x013040)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013040)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 4)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 4)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -183,7 +180,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt5]
WATCH=[REG(MYCHIPLET,0x013050)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013050)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 5)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 5)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -195,7 +192,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt6]
WATCH=[REG(MYCHIPLET,0x013062)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013062)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 6)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 6)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -207,7 +204,7 @@ CAUSE_EFFECT CHIPLETS ex {
LABEL=[Start Instructions - cXt7]
WATCH=[REG(MYCHIPLET,0x013070)] # RAS Control Reg
CAUSE: TARGET=[REG(MYCHIPLET,0x013070)] OP=[BIT,ON] BIT=[62] # Start
- EFFECT: TARGET=[MODULE(startInstructions, 5, 7)] OP=[MODULECALL] # Start Hostboot
+ EFFECT: TARGET=[MODULE(startInstructions, MYCORE, 7)] OP=[MODULECALL] # Start Hostboot
# Clear quiesce, por, maint mode
# Set running
# Leave other bits alone
@@ -583,3 +580,1223 @@ CAUSE_EFFECT CHIPLETS ex {
ELSE: TARGET=[REG(MYCHIPLET,0x013072)] OP=[BIT,OFF] BIT=[21] #core_is_in_maintenance_mode
}
+#@01 begin
+##### Winkle #####
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt0]
+ WATCH=[THREADSTATE(MYCHIPLET,0x0)]
+ WATCH=[REG(MYCHIPLET,0x013004)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x0)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013004)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt1]
+ WATCH=[THREADSTATE(MYCHIPLET,0x1)]
+ WATCH=[REG(MYCHIPLET,0x013014)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x1)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013014)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt2]
+ WATCH=[THREADSTATE(MYCHIPLET,0x2)]
+ WATCH=[REG(MYCHIPLET,0x013024)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x2)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013024)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt3]
+ WATCH=[THREADSTATE(MYCHIPLET,0x3)]
+ WATCH=[REG(MYCHIPLET,0x013034)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x3)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013034)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt4]
+ WATCH=[THREADSTATE(MYCHIPLET,0x4)]
+ WATCH=[REG(MYCHIPLET,0x013044)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x4)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013044)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt5]
+ WATCH=[THREADSTATE(MYCHIPLET,0x5)]
+ WATCH=[REG(MYCHIPLET,0x013054)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x5)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013054)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt6]
+ WATCH=[THREADSTATE(MYCHIPLET,0x6)]
+ WATCH=[REG(MYCHIPLET,0x013064)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x6)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013064)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Winkle - cXt7]
+ WATCH=[THREADSTATE(MYCHIPLET,0x7)]
+ WATCH=[REG(MYCHIPLET,0x013074)]
+ # active=0,nap=0,sleep=0,winkle=1
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x7)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=111
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013074)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C0001C0 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+
+##### Sleep #####
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt0]
+ WATCH=[THREADSTATE(MYCHIPLET,0x0)]
+ WATCH=[REG(MYCHIPLET,0x013004)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x0)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013004)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt1]
+ WATCH=[THREADSTATE(MYCHIPLET,0x1)]
+ WATCH=[REG(MYCHIPLET,0x013014)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x1)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013014)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt2]
+ WATCH=[THREADSTATE(MYCHIPLET,0x2)]
+ WATCH=[REG(MYCHIPLET,0x013024)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x2)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013024)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt3]
+ WATCH=[THREADSTATE(MYCHIPLET,0x3)]
+ WATCH=[REG(MYCHIPLET,0x013034)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x3)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013034)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt4]
+ WATCH=[THREADSTATE(MYCHIPLET,0x4)]
+ WATCH=[REG(MYCHIPLET,0x013044)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x4)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013044)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt5]
+ WATCH=[THREADSTATE(MYCHIPLET,0x5)]
+ WATCH=[REG(MYCHIPLET,0x013054)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x5)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013054)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt6]
+ WATCH=[THREADSTATE(MYCHIPLET,0x6)]
+ WATCH=[REG(MYCHIPLET,0x013064)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x6)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013064)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Sleep - cXt7]
+ WATCH=[THREADSTATE(MYCHIPLET,0x7)]
+ WATCH=[REG(MYCHIPLET,0x013074)]
+ # active=0,nap=0,sleep=1,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x7)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,02000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=11, 23:25=110
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013074)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0C000180 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+
+##### Active #####
+
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt0]
+ WATCH=[THREADSTATE(MYCHIPLET,0x0)]
+ WATCH=[REG(MYCHIPLET,0x013004)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x0)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013004)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt1]
+ WATCH=[THREADSTATE(MYCHIPLET,0x1)]
+ WATCH=[REG(MYCHIPLET,0x013014)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x1)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013014)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt2]
+ WATCH=[THREADSTATE(MYCHIPLET,0x2)]
+ WATCH=[REG(MYCHIPLET,0x013024)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x2)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013024)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt3]
+ WATCH=[THREADSTATE(MYCHIPLET,0x3)]
+ WATCH=[REG(MYCHIPLET,0x013034)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x3)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013034)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt4]
+ WATCH=[THREADSTATE(MYCHIPLET,0x4)]
+ WATCH=[REG(MYCHIPLET,0x013044)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x4)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013044)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt5]
+ WATCH=[THREADSTATE(MYCHIPLET,0x5)]
+ WATCH=[REG(MYCHIPLET,0x013054)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x5)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013054)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt6]
+ WATCH=[THREADSTATE(MYCHIPLET,0x6)]
+ WATCH=[REG(MYCHIPLET,0x013064)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x6)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013064)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Status - Active - cXt7]
+ WATCH=[THREADSTATE(MYCHIPLET,0x7)]
+ WATCH=[REG(MYCHIPLET,0x013074)]
+ # active=1,nap=0,sleep=0,winkle=0
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x7)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,08000000)] MASK=[LITERAL(32,0F000000)]
+ # 4:5=00, 23:25=000
+ EFFECT: TARGET=[REG(MYCHIPLET,0x013074)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,00000000 00000000)] MASK=[LITERAL(64,0C0001C0 00000000)]
+}
+
+
+###################
+## HAP Triggers ##
+
+# HAP Actions work like this:
+# Simics sets bits in HAP regs (below)
+# Action will set status bit in THREADSTATE
+# Changes to THREADSTATE regspace will update status bits in Scom regs
+
+# Each bit represents the state of a given core/thread, and the bit
+# position is computed as:
+#
+# bit = core * threadsPerCore + thread
+#
+#0xFF000020, 64 # ADDR_LOGIC_THREAD_BREAKPOINT
+#0xFF000030, 64 # ADDR_LOGIC_THREAD_NAP
+#0xFF000040, 64 # ADDR_LOGIC_THREAD_SLEEP
+#0xFF000050, 64 # ADDR_LOGIC_THREAD_SRESET
+#0xFF000060, 64 # ADDR_LOGIC_THREAD_WINKLE
+
+#### Winkle ####
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t0]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[8]
+ EFFECT: TARGET=[THREADSTATE(0x11000000)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000000)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t1]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[9]
+ EFFECT: TARGET=[THREADSTATE(0x11000001)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000001)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t2]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[10]
+ EFFECT: TARGET=[THREADSTATE(0x11000002)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000002)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t3]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[11]
+ EFFECT: TARGET=[THREADSTATE(0x11000003)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000003)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t4]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[12]
+ EFFECT: TARGET=[THREADSTATE(0x11000004)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000004)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t5]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[13]
+ EFFECT: TARGET=[THREADSTATE(0x11000005)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000005)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t6]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[14]
+ EFFECT: TARGET=[THREADSTATE(0x11000006)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000006)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c1t7]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[15]
+ EFFECT: TARGET=[THREADSTATE(0x11000007)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x11000007)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t0]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[16]
+ EFFECT: TARGET=[THREADSTATE(0x12000000)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000000)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t1]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[17]
+ EFFECT: TARGET=[THREADSTATE(0x12000001)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000001)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t2]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[18]
+ EFFECT: TARGET=[THREADSTATE(0x12000002)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000002)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t3]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[19]
+ EFFECT: TARGET=[THREADSTATE(0x12000003)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000003)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t4]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[20]
+ EFFECT: TARGET=[THREADSTATE(0x12000004)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000004)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t5]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[21]
+ EFFECT: TARGET=[THREADSTATE(0x12000005)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000005)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t6]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[22]
+ EFFECT: TARGET=[THREADSTATE(0x12000006)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000006)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c2t7]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[23]
+ EFFECT: TARGET=[THREADSTATE(0x12000007)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x12000007)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t0]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[24]
+ EFFECT: TARGET=[THREADSTATE(0x13000000)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000000)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t1]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[25]
+ EFFECT: TARGET=[THREADSTATE(0x13000001)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000001)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t2]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[26]
+ EFFECT: TARGET=[THREADSTATE(0x13000002)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000002)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t3]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[27]
+ EFFECT: TARGET=[THREADSTATE(0x13000003)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000003)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t4]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[28]
+ EFFECT: TARGET=[THREADSTATE(0x13000004)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000004)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t5]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[29]
+ EFFECT: TARGET=[THREADSTATE(0x13000005)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000005)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t6]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[30]
+ EFFECT: TARGET=[THREADSTATE(0x13000006)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000006)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c3t7]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[31]
+ EFFECT: TARGET=[THREADSTATE(0x13000007)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x13000007)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t0]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[32]
+ EFFECT: TARGET=[THREADSTATE(0x14000000)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000000)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t1]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[33]
+ EFFECT: TARGET=[THREADSTATE(0x14000001)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000001)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t2]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[34]
+ EFFECT: TARGET=[THREADSTATE(0x14000002)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000002)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t3]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[35]
+ EFFECT: TARGET=[THREADSTATE(0x14000003)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000003)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t4]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[36]
+ EFFECT: TARGET=[THREADSTATE(0x14000004)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000004)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t5]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[37]
+ EFFECT: TARGET=[THREADSTATE(0x14000005)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000005)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t6]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[38]
+ EFFECT: TARGET=[THREADSTATE(0x14000006)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000006)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c4t7]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[39]
+ EFFECT: TARGET=[THREADSTATE(0x14000007)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x14000007)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t0]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[40]
+ EFFECT: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t1]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[41]
+ EFFECT: TARGET=[THREADSTATE(0x15000001)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000001)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t2]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[42]
+ EFFECT: TARGET=[THREADSTATE(0x15000002)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000002)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t3]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[43]
+ EFFECT: TARGET=[THREADSTATE(0x15000003)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000003)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t4]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[44]
+ EFFECT: TARGET=[THREADSTATE(0x15000004)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000004)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t5]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[45]
+ EFFECT: TARGET=[THREADSTATE(0x15000005)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000005)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t6]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[46]
+ EFFECT: TARGET=[THREADSTATE(0x15000006)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000006)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c5t7]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[47]
+ EFFECT: TARGET=[THREADSTATE(0x15000007)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x15000007)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t0]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[48]
+ EFFECT: TARGET=[THREADSTATE(0x16000000)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000000)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t1]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[THREADSTATE(0x16000001)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000001)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t2]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[50]
+ EFFECT: TARGET=[THREADSTATE(0x16000002)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000002)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t3]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[51]
+ EFFECT: TARGET=[THREADSTATE(0x16000003)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000003)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t4]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[52]
+ EFFECT: TARGET=[THREADSTATE(0x16000004)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000004)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t5]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[53]
+ EFFECT: TARGET=[THREADSTATE(0x16000005)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000005)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t6]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[54]
+ EFFECT: TARGET=[THREADSTATE(0x16000006)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000006)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+CAUSE_EFFECT {
+ LABEL=[HAP - Winkle - c6t7]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[55]
+ EFFECT: TARGET=[THREADSTATE(0x16000007)] OP=[BIT,ON] BIT=[7] #winkle=1
+ ELSE: TARGET=[THREADSTATE(0x16000007)] OP=[BIT,OFF] BIT=[7] #winkle=0
+}
+
+
+#### Active ####
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t0]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[8] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[8] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[8] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000000)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000000)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t1]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[9] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[9] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[9] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000001)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000001)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t2]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[10] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[10] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[10] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000002)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000002)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t3]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[11] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[11] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[11] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000003)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000003)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t4]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[12] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[12] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[12] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000004)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000004)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t5]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[13] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[13] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[13] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000005)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000005)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t6]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[14] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[14] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[14] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000006)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000006)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c1t7]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[15] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[15] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[15] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x11000007)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x11000007)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t0]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[16] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[16] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[16] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000000)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000000)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t1]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[17] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[17] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[17] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000001)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000001)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t2]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[18] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[18] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[18] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000002)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000002)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t3]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[19] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[19] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[19] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000003)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000003)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t4]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[20] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[20] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[20] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000004)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000004)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t5]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[21] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[21] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[21] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000005)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000005)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t6]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[22] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[22] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[22] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000006)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000006)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c2t7]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[23] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[23] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[23] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x12000007)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x12000007)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t0]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[24] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[24] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[24] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000000)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000000)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t1]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[25] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[25] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[25] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000001)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000001)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t2]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[26] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[26] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[26] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000002)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000002)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t3]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[27] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[27] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[27] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000003)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000003)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t4]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[28] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[28] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[28] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000004)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000004)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t5]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[29] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[29] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[29] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000005)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000005)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t6]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[30] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[30] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[30] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000006)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000006)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c3t7]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[31] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[31] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[31] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x13000007)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x13000007)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t0]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[32] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[32] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[32] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000000)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000000)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t1]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[33] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[33] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[33] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000001)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000001)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t2]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[34] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[34] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[34] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000002)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000002)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t3]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[35] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[35] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[35] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000003)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000003)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t4]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[36] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[36] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[36] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000004)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000004)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t5]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[37] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[37] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[37] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000005)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000005)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t6]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[38] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[38] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[38] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000006)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000006)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c4t7]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[39] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[39] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[39] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x14000007)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x14000007)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t0]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[40] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[40] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[40] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t1]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[41] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[41] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[41] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000001)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000001)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t2]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[42] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[42] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[42] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000002)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000002)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t3]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[43] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[43] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[43] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000003)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000003)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t4]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[44] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[44] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[44] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000004)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000004)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t5]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[45] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[45] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[45] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000005)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000005)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t6]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[46] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[46] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[46] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000006)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000006)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c5t7]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[47] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[47] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[47] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x15000007)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x15000007)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t0]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[48] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[48] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[48] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000000)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000000)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t1]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[49] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[49] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[49] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000001)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000001)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t2]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[50] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[50] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[50] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000002)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000002)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t3]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[51] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[51] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[51] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000003)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000003)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t4]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[52] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[52] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[52] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000004)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000004)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t5]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[53] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[53] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[53] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000005)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000005)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t6]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[54] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[54] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[54] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000006)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000006)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+CAUSE_EFFECT {
+ LABEL=[HAP - Active - c6t7]
+ WATCH=[LOGIC(0xFF000030)]
+ WATCH=[LOGIC(0xFF000050)]
+ WATCH=[LOGIC(0xFF000060)]
+ CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,OFF] BIT=[55] #no winkle
+ CAUSE: TARGET=[LOGIC(0xFF000030)] OP=[BIT,OFF] BIT=[55] #no nap
+ CAUSE: TARGET=[LOGIC(0xFF000050)] OP=[BIT,OFF] BIT=[55] #no sleep
+ EFFECT: TARGET=[THREADSTATE(0x16000007)] OP=[BIT,ON] BIT=[4] #active=1
+ ELSE: TARGET=[THREADSTATE(0x16000007)] OP=[BIT,OFF] BIT=[4] #active=0
+}
+
+
+
+#### Sreset ####
+#CAUSE_EFFECT {
+# LABEL=[HAP - Sreset - c5t0]
+# WATCH=[LOGIC(0xFF000050)]
+# CAUSE: TARGET=[LOGIC(0xFF000060)] OP=[BIT,ON] BIT=[40] #c5t0
+# EFFECT: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,ON] BIT=[4] #active=1
+# EFFECT: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,OFF] BIT=[5] #nap=0
+# EFFECT: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,OFF] BIT=[6] #sleep=0
+# EFFECT: TARGET=[THREADSTATE(0x15000000)] OP=[BIT,OFF] BIT=[7] #winkle=0
+#}
+
+##########################################
+# SBE Master Winkle Wakeup
+CAUSE_EFFECT CHIPLETS ex {
+ LABEL=[Master Winkle Wakeup]
+ WATCH=[THREADSTATE(MYCHIPLET,0x0)]
+ WATCH=[THREADSTATE(MYCHIPLET,0x1)]
+ WATCH=[THREADSTATE(MYCHIPLET,0x2)]
+ WATCH=[THREADSTATE(MYCHIPLET,0x3)]
+ WATCH=[THREADSTATE(MYCHIPLET,0x4)]
+ WATCH=[THREADSTATE(MYCHIPLET,0x5)]
+ WATCH=[THREADSTATE(MYCHIPLET,0x6)]
+ WATCH=[THREADSTATE(MYCHIPLET,0x7)]
+ # active=0,nap=0,sleep=0,winkle=1 on all 8 threads
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x0)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x1)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x2)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x3)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x4)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x5)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x6)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ CAUSE: TARGET=[THREADSTATE(MYCHIPLET,0x7)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(32,01000000)] MASK=[LITERAL(32,0F000000)]
+ # check that substep_deadman_start program is running in SBE @todo: Hostboot RTC:41412
+ #CAUSE: TARGET=[FSIMBOX(0x1C)] OP=[EQUALTO,BUF,MASK] DATA=[LITERAL(64,0000F012 00000000)] MASK=[LITERAL(64,0000FFFF 00000000)]
+ # Restore LPCR for wake-up options.
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 0)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 1)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 2)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 3)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 4)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 5)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 6)] OP=[BIT,ON] BIT=[49]
+ EFFECT: TARGET=[PROCREG(lpcr, MYCORE, 7)] OP=[BIT,ON] BIT=[49]
+ # Clear Timebase (to simulate core losing state).
+ EFFECT: TARGET=[PROCREG(tb, MYCORE, 0)] OP=[EQUALTO,BUF] DATA=[LITERAL(64,00000000 00000000)]
+ # Send IPI to thread
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 0 )] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 1 )] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 2 )] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 3 )] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 4 )] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 5 )] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 6 )] OP=[MODULECALL]
+ EFFECT: TARGET=[MODULE(interProcessorInterrupt, MYCORE, 7 )] OP=[MODULECALL]
+ EFFECT: TARGET=[THREADSTATE(MYCHIPLET,0x0)] OP=[BIT,OFF] BIT=[7]
+}
+
+#@01 end
diff --git a/src/build/citest/etc/patches/p8_master.por.patch b/src/build/citest/etc/patches/p8_master.por.patch
deleted file mode 100644
index f74f75465..000000000
--- a/src/build/citest/etc/patches/p8_master.por.patch
+++ /dev/null
@@ -1,17 +0,0 @@
-
-##### from src/build/etc/patches/p8_master.por.patch
-
-#dc01
-#Flush state is : por=0,quiesced=1,running=0,maintmode=1,active=0,nap/sleep/winkle=0
-THREADSTATE(0x15000001)=0x10000000
-THREADSTATE(0x15000002)=0x10000000
-THREADSTATE(0x15000003)=0x10000000
-THREADSTATE(0x15000004)=0x10000000
-THREADSTATE(0x15000005)=0x10000000
-THREADSTATE(0x15000006)=0x10000000
-THREADSTATE(0x15000007)=0x10000000
-
-#Master thread is started by SBE : running=1,active=1
-THREADSTATE(0x15000000)=0x28000000
-
-##### end patch
diff --git a/src/build/citest/etc/patches/patchlist.txt b/src/build/citest/etc/patches/patchlist.txt
index c9732b104..4cdb8d248 100644
--- a/src/build/citest/etc/patches/patchlist.txt
+++ b/src/build/citest/etc/patches/patchlist.txt
@@ -5,9 +5,8 @@ Brief description of the problem or reason for patch
-Files: list of files
-Coreq: list of associated changes, e.g. workarounds.presimsetup
-
-New actions for instruction state processing
+New actions for master-winkle wakeup
-RTC: Task 43959 will remove the patches
--CMVC: D841334 is integrating the changes
+-CMVC: D846452 is integrating the changes
-Files: p8_inst.act
-Coreq: there are related changes in workarounds.postsimsetup
diff --git a/src/build/citest/etc/workarounds.postsimsetup b/src/build/citest/etc/workarounds.postsimsetup
index 51b45d176..2ff683e94 100755
--- a/src/build/citest/etc/workarounds.postsimsetup
+++ b/src/build/citest/etc/workarounds.postsimsetup
@@ -27,17 +27,8 @@
##
### Updates to handle instruction states (Remove with RTC:43959)
-echo "+++ Update cec-chip files for instruction state processing"
+echo "+++ Update cec-chip files for master-winkle wakeup"
mkdir -p $sb/simu/data/cec-chip/
-cp --update $bb/src/simu/data/cec-chip/p8.chip $sb/simu/data/cec-chip/
-cat $HOSTBOOTROOT/src/build/citest/etc/patches/p8.chip.patch >> $sb/simu/data/cec-chip/p8.chip
-grep -v DONE $sb/simu/data/cec-chip/p8.chip > $sb/simu/data/cec-chip/p8.chip.tmp
-echo "DONE" >> $sb/simu/data/cec-chip/p8.chip.tmp
-mv $sb/simu/data/cec-chip/p8.chip.tmp $sb/simu/data/cec-chip/p8.chip
-
-cp --update $bb/src/simu/data/cec-chip/p8_master.por $sb/simu/data/cec-chip/
-cat $HOSTBOOTROOT/src/build/citest/etc/patches/p8_master.por.patch >> $sb/simu/data/cec-chip/p8_master.por
-
cp $HOSTBOOTROOT/src/build/citest/etc/patches/p8_inst.act $sb/simu/data/cec-chip/
###
diff --git a/src/include/arch/ppc.H b/src/include/arch/ppc.H
index 9ba62ff9e..4e6add553 100644
--- a/src/include/arch/ppc.H
+++ b/src/include/arch/ppc.H
@@ -159,6 +159,16 @@ inline uint64_t getTB()
}
ALWAYS_INLINE
+inline void setTB(uint64_t _tb)
+{
+ // The bottom 24 bits of the timebase can't be written so round it up.
+ register uint64_t tb = (_tb + 0x1000000);
+ // Note that SPR 286 is intended (while getTB is 268) here.
+ // This is the mttbu40 instruction and not the mttb, which doesn't exist.
+ asm volatile("mtspr 286, %0" :: "r" (tb));
+}
+
+ALWAYS_INLINE
inline void setDEC(uint64_t _dec)
{
register uint64_t dec = _dec;
@@ -277,9 +287,9 @@ inline void icbi(void* _ptr)
}
ALWAYS_INLINE
-inline void doze()
+inline void nap()
{
- asm volatile("doze");
+ asm volatile("nap");
}
ALWAYS_INLINE
diff --git a/src/include/kernel/cpu.H b/src/include/kernel/cpu.H
index e395b2920..2efa89df2 100644
--- a/src/include/kernel/cpu.H
+++ b/src/include/kernel/cpu.H
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/include/kernel/cpu.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/cpu.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 cpu.H
* @brief Defines kernel information and functions about CPUs.
*
@@ -42,7 +43,7 @@ class Scheduler;
* @brief Stores per-CPU kernel information.
*
* @note kernel_stack and master need to be at fixed locations in this
- * structure due to usages in start.S.
+ * structure due to usages in start.S (see ppcconsts.S).
*
* - kernel_stack is a double-word at cpu_t[0 bytes].
* - master is a byte at cpu_t[12 bytes].
@@ -63,8 +64,11 @@ struct cpu_t
/** If the CPU is active */
bool active:1;
+ /** If the CPU is winkled */
+ bool winkled:1;
+
/** Ensure alignment of master attribute for asm code. */
- uint64_t __reserved_master:30;
+ uint64_t __reserved_master:29;
} PACKED;
/** Pointer to the scheduler for this CPU (may not be unique) */
@@ -86,6 +90,9 @@ struct cpu_t
/** counter for executePeriodics */
size_t periodic_count;
+
+ /** Sequence ID of CPU initialization. */
+ uint64_t cpu_start_seqid;
};
/** @fn getCpuId
diff --git a/src/include/kernel/cpumgr.H b/src/include/kernel/cpumgr.H
index 8cf6d0fc3..fc7b68547 100644
--- a/src/include/kernel/cpumgr.H
+++ b/src/include/kernel/cpumgr.H
@@ -82,10 +82,39 @@ class CpuManager
*/
static void activateCPU(cpu_t * i_cpu);
+ /** @fn deactivateCPU
+ * Deactivate a cpu to show it is not running.
+ * @param[in] cpu_t the CPU
+ * @post Active flag is off in cpu_t structure.
+ */
+ static void deactivateCPU(cpu_t * i_cpu);
+
/** @fn getCpuCount
- * Return the number of active CPUs.
+ * Return the number of active CPUs.
+ */
+ static size_t getCpuCount() { return cv_cpuSeq & 0xFFFFFFFF; }
+
+ /** @fn getCpuSeqId
+ * Return the current CPU start sequence ID.
+ */
+ static size_t getCpuSeqId() { return cv_cpuSeq >> 32; }
+
+ /** @fn getCpuCountAndSeqId
+ * Atomically retrieve both the current active CPU count and
+ * sequence ID.
+ *
*/
- static size_t getCpuCount() { return cv_cpuCount; }
+ static void getCpuCountAndSeqId(uint32_t& o_count, uint32_t& o_seq)
+ {
+ uint64_t cpuSeq = cv_cpuSeq;
+ o_count = cpuSeq & 0xFFFFFFFF;
+ o_seq = cpuSeq >> 32;
+ }
+
+ /** @fn getThreadCount
+ * Return the number of HW threads for this CPU core type.
+ */
+ static size_t getThreadCount();
/** @fn startCore
* Create structures to support a core activating and start the core.
@@ -127,16 +156,16 @@ class CpuManager
void startCPU(ssize_t i = -1);
void startSlaveCPU(cpu_t*);
- static size_t getThreadCount();
-
private:
static cpu_t** cv_cpus; // Need to be able to access this
// from start.S to get initial stacks
// of secondary cpus / threads.
- static Barrier cv_barrier; //!< barrier for cpus
- static bool cv_defrag; //!< mem heap defrag
- static size_t cv_cpuCount; //!< # of active CPUs
+ /** Number of active CPUs.
+ * Stored as "(seqID << 32) | cpus"
+ */
+ static uint64_t cv_cpuSeq;
+
static bool cv_forcedMemPeriodic; //!< force free / coalesce.
// If a shutdown of all CPUs is requested
diff --git a/src/include/kernel/deferred.H b/src/include/kernel/deferred.H
new file mode 100644
index 000000000..6d8950acb
--- /dev/null
+++ b/src/include/kernel/deferred.H
@@ -0,0 +1,201 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/include/kernel/deferred.H $
+ *
+ * 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
+ */
+#ifndef __KERNEL_DEFERRED_H
+#define __KERNEL_DEFERRED_H
+
+/** @file deferred.H
+ * @brief Definition of kernel's deferred work constructs.
+ *
+ * These classes allow the kernel to synchronize all CPUs into kernel-mode
+ * and execute a task. These work items are queued up to be executed at
+ * the next time-slice expiration (decrementer exception).
+ */
+
+#include <kernel/types.h>
+#include <kernel/spinlock.H>
+#include <kernel/barrier.H>
+
+/** @class DeferredWork
+ * @brief The base work-item type for deferred work.
+ *
+ * This class implements the synchronization and state transition for a
+ * general deferred work object. This class has methods for defining
+ * the behavior at specific points in its execution. A real behavior
+ * implementation should be defined by inheriting this class and overloading
+ * the desired virtual methods.
+ *
+ * The class is closely associated with the DeferredQueue, which is meant to
+ * hold pending DeferredWork objects. When a DeferredWork is complete it
+ * will remove itself from the DeferredQueue and self-delete.
+ *
+ * The state transition is as follows:
+ *
+ * <pre>
+ * MASTER Both NON-MASTER
+ * 1. Sync all
+ * 2. masterPreWork block
+ * 3. activeMainWork
+ * 4. Sync all
+ * 5. masterPostWork block
+ * 6. Last thread out deletes
+ * </pre>
+ *
+ * With the deferred work there is concern as to what to do with CPUs that
+ * come online while a deferred work item is being executed. For instance,
+ * the Heap Coalescing work could cause data integrity issues if a freshly
+ * activated CPU were to not block with the rest of the CPUs and instead
+ * started executed user-space code. To deal with this condition a
+ * CPU which is activated after the DeferredWork object was created will
+ * block at masterPreWork and masterPostWork stages and call
+ * nonactiveMainWork. Typically, the non-active CPUs perform no action
+ * but an implementation could assert for a race-condition that cannot
+ * be handled properly (though should never occur).
+ */
+class DeferredWork
+{
+ public:
+ /** Default Constructor
+ * Initializes the work item and determines the CPU-activation
+ * sequence number at the time of creation.
+ */
+ DeferredWork();
+
+ /** Default destructor
+ * Verifies that the work item has completed properly and is
+ * detached from the DeferredQueue.
+ */
+ virtual ~DeferredWork();
+
+ /** Entry point for DeferredWork execution. */
+ void start();
+
+ protected:
+ // Functions to override for desired behavior:
+ /** Executed by master before "main" but after all active
+ * CPUs are sync'd.
+ */
+ virtual void masterPreWork() {};
+ /** Executed by master after "main" work is complete. */
+ virtual void masterPostWork() {};
+ /** Executed by all [active] CPUs as the "main" work. */
+ virtual void activeMainWork() {};
+ /** Executed by all non-active CPUs as the "main" work. */
+ virtual void nonactiveMainWork() {};
+
+ private:
+ friend class DeferredQueue;
+
+ /** Barrier for synchronization of active CPUs. */
+ Barrier iv_barrier;
+ /** Count of CPUs in object and pointer to next object.
+ *
+ * Stored as "(cpu count << 32) | (DeferredWork* next)". This
+ * is done so that we can atomically check and/or set both
+ * values.
+ */
+ volatile uint64_t iv_cpus_and_next;
+ /** Sequence ID at the time of creation. */
+ uint32_t iv_activeSeqId;
+ /** Boolean to indicate masterPreWork is complete. */
+ volatile bool iv_releasePre;
+ /** Boolean to indicate masterPostWork is complete. */
+ volatile bool iv_releasePost;
+
+ // Internal state transition functions.
+ void _waitForCpus();
+ void _masterPre();
+ void _waitAtPre();
+ void _masterPost();
+ void _waitAtPost();
+ void _cleanup();
+
+};
+
+/** @class DeferredQueue
+ * @brief Queue for DeferredWork objects.
+ *
+ * This class should have a Singleton instance for the whole kernel.
+ * Periodically, kernel threads can call the 'execute' function to execute
+ * pending work, if any is available. Additional work can be 'insert'ed.
+ */
+class DeferredQueue
+{
+ public:
+ /** Default constructor. */
+ DeferredQueue();
+ /** Default destructor. */
+ ~DeferredQueue();
+
+ /** Insert a work item into the queue.
+ *
+ * @param i_work - The item to add.
+ *
+ * Ownership of the work item is transfered to the queue, which is
+ * responsible for delete once the work is complete.
+ */
+ static void insert(DeferredWork* i_work);
+ /** Execute any pending work items. */
+ static void execute();
+
+ private:
+ friend class DeferredWork;
+
+ // Instance functions for static pair.
+ void _insert(DeferredWork* i_work);
+ void _execute();
+
+ /** Remove a completed work item from the queue.
+ *
+ * This function is to be called by the master CPU executing the
+ * work item being completed.
+ *
+ * The work item is atomically removed from the queue and the
+ * count of CPUs with a pointer to the work item is compared
+ * against the count of CPUs in the work item. This function
+ * returns when all CPUs that have a pointer are actually inside
+ * the work item (so we can accurately determine when there is
+ * only a single CPU in the work item for delete).
+ *
+ * @param i_work - The item to remove.
+ */
+ void _complete(DeferredWork* i_work);
+
+ /** Spinlock to protect insert / remove operations.
+ *
+ * This is effectively a "write" lock on the structure and all
+ * reads are done atomically. The writers have also use atomic
+ * update operations to ensure the readers (which are never
+ * locked) operate in a thread-safe manner.
+ */
+ Spinlock lock;
+ /** Count of CPUs in first object and pointer to it.
+ *
+ * Stored as "(cpu count << 32) | (DeferredWork* ptr)". This
+ * is done so that we can atomically check and/or set both
+ * values.
+ */
+ volatile uint64_t iv_cpus_and_next;
+};
+
+#endif
diff --git a/src/include/kernel/misc.H b/src/include/kernel/misc.H
index ebec9cc48..c970c337e 100644
--- a/src/include/kernel/misc.H
+++ b/src/include/kernel/misc.H
@@ -30,6 +30,8 @@
#include <stdint.h>
#include <usr/vmmconst.h>
+#include <kernel/deferred.H>
+#include <kernel/task.H>
namespace KernelMisc
{
@@ -59,5 +61,32 @@ namespace KernelMisc
}
return true;
}
+
+ /** @class WinkleCore
+ *
+ * @brief DeferredWork class for implementing cpu_master_winkle.
+ */
+ class WinkleCore : public ::DeferredWork
+ {
+ public:
+ /** ctor
+ *
+ * @param i_caller - Task calling cpu_master_winkle to be
+ * restored after winkle is complete.
+ */
+ WinkleCore(task_t* i_caller) :
+ iv_caller(i_caller), iv_timebase(0) {};
+
+ void masterPreWork();
+ void activeMainWork();
+ void masterPostWork();
+ void nonactiveMainWork();
+
+ private:
+ /** Caller of cpu_master_winkle() */
+ task_t* iv_caller;
+ /** Current time-base value for restore after winkle. */
+ uint64_t iv_timebase;
+ };
};
#endif
diff --git a/src/include/kernel/ppcconsts.S b/src/include/kernel/ppcconsts.S
index 1568bb911..8b84e9135 100644
--- a/src/include/kernel/ppcconsts.S
+++ b/src/include/kernel/ppcconsts.S
@@ -1,24 +1,24 @@
# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
-#
+#
# $Source: src/include/kernel/ppcconsts.S $
-#
+#
# 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
#*--------------------------------------------------------------------*#
#* Register Constants *#
@@ -243,3 +243,10 @@
.set TASK_FPR_31, TASK_FPR_30+8
.set TASK_FPSCR, TASK_FPR_31+8
+.set CPU_KERNEL_STACK, 0
+.set CPU_CPUID, CPU_KERNEL_STACK+8
+.set CPU_STATUS, CPU_CPUID+4
+
+.set CPU_STATUS_MASTER, 0
+.set CPU_STATUS_ACTIVE, CPU_STATUS_MASTER+1
+.set CPU_STATUS_WINKLED, CPU_STATUS_ACTIVE+1
diff --git a/src/include/kernel/syscalls.H b/src/include/kernel/syscalls.H
index 5523fc158..b02fd2216 100644
--- a/src/include/kernel/syscalls.H
+++ b/src/include/kernel/syscalls.H
@@ -92,8 +92,10 @@ namespace Systemcalls
MISC_CPUSTARTCORE,
/** cpu_spr_value() */
MISC_CPUSPRVALUE,
- /** cpu_doze() - Hidden syscall */
- MISC_CPUDOZE,
+ /** cpu_nap() - Hidden syscall */
+ MISC_CPUNAP,
+ /** cpu_master_winkle() */
+ MISC_CPUWINKLE,
/** mm_alloc_block() */
MM_ALLOC_BLOCK,
diff --git a/src/include/sys/misc.h b/src/include/sys/misc.h
index 1ffd8e6a7..f1c62273b 100644
--- a/src/include/sys/misc.h
+++ b/src/include/sys/misc.h
@@ -142,6 +142,9 @@ uint64_t cpu_spr_value(CpuSprNames spr);
*
* @retval 0 - Success
* @retval -EDEADLK - Cores other than the master are already running.
+ *
+ * @note This function will migrate the task to the master thread and in the
+ * process will unset any task affinity. See task_affinity_unpin().
*/
int cpu_master_winkle();
diff --git a/src/kernel.ld b/src/kernel.ld
index 368605e9b..3f9060548 100644
--- a/src/kernel.ld
+++ b/src/kernel.ld
@@ -5,7 +5,7 @@
*
* IBM CONFIDENTIAL
*
- * COPYRIGHT International Business Machines Corp. 2010 - 2011
+ * COPYRIGHT International Business Machines Corp. 2010-2012
*
* p1
*
@@ -19,7 +19,7 @@
*
* Origin: 30
*
- * IBM_PROLOG_END
+ * IBM_PROLOG_END_TAG
*/
base_load_address = 0x00000000;
text_load_address = 0x00003000;
@@ -31,6 +31,7 @@ SECTIONS
.text ALIGN(0x1000): {
*(.text.intvects)
. = text_load_address;
+ *(.text.kernelasm)
*(.text)
*(.text._*)
*(.rodata)
diff --git a/src/kernel/cpumgr.C b/src/kernel/cpumgr.C
index 943ef48fd..909661cca 100644
--- a/src/kernel/cpumgr.C
+++ b/src/kernel/cpumgr.C
@@ -38,13 +38,13 @@
#include <kernel/heapmgr.H>
#include <kernel/intmsghandler.H>
#include <errno.h>
+#include <kernel/deferred.H>
+#include <kernel/misc.H>
cpu_t** CpuManager::cv_cpus = NULL;
bool CpuManager::cv_shutdown_requested = false;
uint64_t CpuManager::cv_shutdown_status = 0;
-Barrier CpuManager::cv_barrier;
-bool CpuManager::cv_defrag = false;
-size_t CpuManager::cv_cpuCount = 0;
+size_t CpuManager::cv_cpuSeq = 0;
bool CpuManager::cv_forcedMemPeriodic = false;
InteractiveDebug CpuManager::cv_interactive_debug;
@@ -95,6 +95,35 @@ void CpuManager::requestShutdown(uint64_t i_status)
cv_shutdown_status = i_status;
__sync_synchronize();
cv_shutdown_requested = true;
+
+ class ExecuteShutdown : public DeferredWork
+ {
+ public:
+ void masterPreWork()
+ {
+ // The stats can be retrieved from global variables as needed.
+ // This can be uncommented for debug if desired
+ #ifdef __MEMSTATS__
+ if(c->master)
+ HeapManager::stats();
+ #endif
+ }
+
+ void activeMainWork()
+ {
+ KernelMisc::shutdown();
+ }
+
+ void nonactiveMainWork()
+ {
+ // Something wasn't synchronized correctly if we got to here.
+ // Should not have CPUs coming online while trying to execute
+ // a shutdown.
+ kassert(false);
+ }
+ };
+
+ DeferredQueue::insert(new ExecuteShutdown());
}
void CpuManager::startCPU(ssize_t i)
@@ -163,8 +192,20 @@ void CpuManager::activateCPU(cpu_t * i_cpu)
{
// Set active.
i_cpu->active = true;
- __sync_add_and_fetch(&cv_cpuCount, 1);
- lwsync();
+
+ // Update sequence ID.
+ do
+ {
+ uint64_t old_seq = cv_cpuSeq;
+ i_cpu->cpu_start_seqid = old_seq + 1 + (1ull << 32);
+
+ if (__sync_bool_compare_and_swap(&cv_cpuSeq, old_seq,
+ i_cpu->cpu_start_seqid))
+ {
+ break;
+ }
+ } while (1);
+ i_cpu->cpu_start_seqid >>= 32;
// Verify / set SPRs.
uint64_t msr = getMSR();
@@ -172,6 +213,24 @@ void CpuManager::activateCPU(cpu_t * i_cpu)
setLPCR(WAKEUP_LPCR_VALUE);
}
+void CpuManager::deactivateCPU(cpu_t * i_cpu)
+{
+ // Set inactive.
+ i_cpu->active = false;
+
+ // Update sequence ID.
+ do
+ {
+ uint64_t old_seq = cv_cpuSeq;
+ uint64_t new_seq = old_seq - 1 + (1ull << 32);
+
+ if (__sync_bool_compare_and_swap(&cv_cpuSeq, old_seq, new_seq))
+ {
+ break;
+ }
+ } while(1);
+}
+
void CpuManager::executePeriodics(cpu_t * i_cpu)
{
if(i_cpu->master)
@@ -211,32 +270,22 @@ void CpuManager::executePeriodics(cpu_t * i_cpu)
if((0 == (i_cpu->periodic_count % CPU_PERIODIC_DEFRAG)) ||
(forceMemoryPeriodic))
{
- // set up barrier based on # cpus cv_barrier;
- // TODO whatif other cpus become active?
- isync(); // Ensure all instructions complete before this point, so
- // we don't get a stale shutdown_requested.
- if(!cv_shutdown_requested)
+ class MemoryCoalesce : public DeferredWork
{
- cv_barrier.init(cv_cpuCount);
- lwsync(); // Ensure barrier init is globally visible before
- // setting defrag = true.
- cv_defrag = true;
- }
+ public:
+ void masterPreWork()
+ {
+ HeapManager::coalesce();
+ PageManager::coalesce();
+ }
+ };
+
+ DeferredQueue::insert(new MemoryCoalesce());
}
}
- if(cv_defrag)
- {
- cv_barrier.wait();
- if(i_cpu->master)
- {
- HeapManager::coalesce();
- PageManager::coalesce();
- cv_defrag = false;
- }
+ DeferredQueue::execute();
- cv_barrier.wait();
- }
}
int CpuManager::startCore(uint64_t pir)
diff --git a/src/kernel/deferred.C b/src/kernel/deferred.C
new file mode 100644
index 000000000..dc6494857
--- /dev/null
+++ b/src/kernel/deferred.C
@@ -0,0 +1,268 @@
+/* IBM_PROLOG_BEGIN_TAG
+ * This is an automatically generated prolog.
+ *
+ * $Source: src/kernel/deferred.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
+ */
+#include <kernel/deferred.H>
+#include <kernel/cpumgr.H>
+#include <util/singleton.H>
+#include <assert.h>
+#include <arch/ppc.H>
+
+/** Extract the DeferredWork pointer part of a iv_cpus_and_next instance var. */
+#define DEFERRED_QUEUE_GET_NEXT_PTR(item) \
+ reinterpret_cast<DeferredWork*>((item)->iv_cpus_and_next & 0xFFFFFFFF)
+
+/** Set the DeferredWork pointer part of a iv_cpus_and_next instance var. */
+#define DEFERRED_QUEUE_SET_NEXT_PTR(item) \
+ (item)->iv_cpus_and_next = \
+ ((item)->iv_cpus_and_next & 0xFFFFFFFF00000000ull) | \
+ reinterpret_cast<uint64_t>(item)
+
+/** Extract the CPU count portion of a iv_cpus_and_next instance var. */
+#define DEFERRED_QUEUE_GET_CPU_COUNT(item) (item)->iv_cpus_and_next >> 32
+
+// Initialize the work queue.
+DeferredQueue::DeferredQueue() : lock(), iv_cpus_and_next(0) {}
+
+DeferredQueue::~DeferredQueue()
+{
+ // Ensure that all work is completed.
+ kassert(0 == iv_cpus_and_next);
+}
+
+void DeferredQueue::insert(DeferredWork* i_work)
+{
+ // Call singleton insert.
+ Singleton<DeferredQueue>::instance()._insert(i_work);
+}
+
+void DeferredQueue::execute()
+{
+ // Call singleton execute.
+ Singleton<DeferredQueue>::instance()._execute();
+}
+
+void DeferredQueue::_insert(DeferredWork* i_work)
+{
+ lock.lock();
+
+ // NULL pointer implies empty, so just add work item.
+ if (0 == iv_cpus_and_next)
+ {
+ iv_cpus_and_next = reinterpret_cast<uint64_t>(i_work);
+ }
+ else
+ {
+ // Follow linked list to last work item.
+ DeferredWork* tail = DEFERRED_QUEUE_GET_NEXT_PTR(this);
+ while (NULL != DEFERRED_QUEUE_GET_NEXT_PTR(tail))
+ {
+ tail = DEFERRED_QUEUE_GET_NEXT_PTR(tail);
+ }
+
+ // Add work item to the end of the list.
+ DEFERRED_QUEUE_SET_NEXT_PTR(i_work);
+ }
+
+ lock.unlock();
+}
+
+void DeferredQueue::_execute()
+{
+ uint64_t cpus_and_next = 0;
+
+ // Increment the CPU count for pointer references.
+ do
+ {
+ cpus_and_next = iv_cpus_and_next;
+
+ if (0 == cpus_and_next) // No work to execute.
+ {
+ return;
+ }
+
+ } while(!__sync_bool_compare_and_swap(&iv_cpus_and_next,
+ cpus_and_next,
+ cpus_and_next + (1ull << 32)));
+
+ // Extract the item pointer.
+ DeferredWork* item =
+ reinterpret_cast<DeferredWork*>(cpus_and_next & 0xFFFFFFFF);
+
+ // Execute the extracted item.
+ item->start();
+}
+
+void DeferredQueue::_complete(DeferredWork* i_work)
+{
+ lock.lock();
+
+ // Update list-head to pop item off.
+ uint64_t new_ptr =
+ reinterpret_cast<uint64_t>(DEFERRED_QUEUE_GET_NEXT_PTR(i_work));
+ uint64_t old_ptr = 0;
+
+ do
+ {
+ old_ptr = iv_cpus_and_next;
+ } while(!__sync_bool_compare_and_swap(&iv_cpus_and_next, old_ptr, new_ptr));
+
+ // Get the CPU count from the old object pointer and wait until those
+ // CPUs get into i_work.
+ old_ptr >>= 32;
+ while (DEFERRED_QUEUE_GET_CPU_COUNT(i_work) != old_ptr)
+ {
+ setThreadPriorityLow();
+ }
+ setThreadPriorityHigh();
+
+ lock.unlock();
+}
+
+DeferredWork::DeferredWork() : iv_barrier(), iv_cpus_and_next(0),
+ iv_activeSeqId(0),
+ iv_releasePre(false), iv_releasePost(false)
+{
+ uint32_t cpuCount;
+
+ // Read the current CPU count and sequence number.
+ CpuManager::getCpuCountAndSeqId(cpuCount, iv_activeSeqId);
+ // Initialize the barrier with the number of active CPUs.
+ iv_barrier.init(cpuCount);
+}
+
+DeferredWork::~DeferredWork()
+{
+ // Ensure the work item was removed from the queue chain and no
+ // CPUs are still inside it.
+ kassert(0 == iv_cpus_and_next);
+}
+
+void DeferredWork::start()
+{
+ // Increment object reference count.
+ __sync_add_and_fetch(&iv_cpus_and_next, 1ull << 32);
+
+ // Get our CPU object and determine if we were active when the item
+ // was created. (Our sequence # being less or equal work item sequence #)
+ cpu_t* cpu = CpuManager::getCurrentCPU();
+ bool active = cpu->cpu_start_seqid <= iv_activeSeqId;
+
+ // Synchronize active CPUs.
+ if (active)
+ {
+ _waitForCpus();
+ }
+
+ // Call masterPre step.
+ if (cpu->master)
+ {
+ _masterPre();
+ }
+ else
+ {
+ _waitAtPre();
+ }
+
+ // Call MainWork step.
+ if (active)
+ {
+ activeMainWork();
+ _waitForCpus();
+ }
+ else
+ {
+ nonactiveMainWork();
+ }
+
+ // Call masterPost step.
+ if (cpu->master)
+ {
+ _masterPost();
+ }
+ else
+ {
+ _waitAtPost();
+ }
+
+ // Release reference to this object.
+ _cleanup();
+}
+
+void DeferredWork::_waitForCpus()
+{
+ iv_barrier.wait();
+}
+
+void DeferredWork::_masterPre()
+{
+ masterPreWork();
+
+ // Ensure memory ops are globally visible before releasing all CPUs.
+ lwsync();
+ iv_releasePre = true;
+}
+
+void DeferredWork::_waitAtPre()
+{
+ while(!iv_releasePre)
+ {
+ setThreadPriorityLow();
+ }
+ isync(); // Prevent spec. execution past this point until released.
+ setThreadPriorityHigh();
+}
+
+void DeferredWork::_masterPost()
+{
+ masterPostWork();
+
+ // Remove ourself from the queue chain now.
+ Singleton<DeferredQueue>::instance()._complete(this);
+
+ // Ensure memory ops are globally visible before releasing all CPUs.
+ lwsync();
+ iv_releasePost = true;
+}
+
+void DeferredWork::_waitAtPost()
+{
+ while(!iv_releasePost)
+ {
+ setThreadPriorityLow();
+ }
+ isync(); // Prevent spec. execution past this point until released.
+ setThreadPriorityHigh();
+}
+
+void DeferredWork::_cleanup()
+{
+ // Decrement reference count.
+ uint64_t cpu_count =
+ __sync_sub_and_fetch(&iv_cpus_and_next, 1ull << 32) >> 32;
+
+ // If the last object, delete this work item.
+ if (0 == cpu_count)
+ {
+ delete this;
+ }
+}
diff --git a/src/kernel/exception.C b/src/kernel/exception.C
index 0d63d0a73..071f10b1e 100644
--- a/src/kernel/exception.C
+++ b/src/kernel/exception.C
@@ -38,7 +38,7 @@ namespace ExceptionHandles
bool PrivInstr(task_t*);
}
-const uint64_t EXCEPTION_SRR1_MASK = 0x00000000783F0000;
+const uint64_t EXCEPTION_SRR1_MASK = 0x00000000783F0000;
const uint64_t EXCEPTION_SRR1_PRIVINS = 0x0000000000040000;
extern "C"
@@ -56,12 +56,12 @@ void kernel_execute_prog_ex()
}
if (!handled)
{
- printk("Program exception, killing task %d\n", t->tid);
- TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
+ printk("Program exception, killing task %d\n", t->tid);
+ TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
}
}
-const uint64_t EXCEPTION_DSISR_MASK = 0x0000000048000000;
+const uint64_t EXCEPTION_DSISR_MASK = 0x0000000048000000;
const uint64_t EXCEPTION_DSISR_PTEMISS = 0x0000000040000000;
const uint64_t EXCEPTION_DSISR_PERMERR = 0x0000000008000000;
const uint64_t EXCEPTION_DSISR_STORE = 0x0000000002000000;
@@ -75,7 +75,7 @@ void kernel_execute_data_storage()
bool handled = false;
switch(exception)
{
- case EXCEPTION_DSISR_PTEMISS:
+ case EXCEPTION_DSISR_PTEMISS:
{
uint64_t is_store = getDSISR() & EXCEPTION_DSISR_STORE;
handled = VmmManager::pteMiss(t, getDAR(), 0 != is_store);
@@ -87,16 +87,16 @@ void kernel_execute_data_storage()
uint64_t is_store = getDSISR() & EXCEPTION_DSISR_STORE;
if (is_store)
{
- handled = VmmManager::pteMiss(t, getDAR(), true);
+ handled = VmmManager::pteMiss(t, getDAR(), true);
}
- break;
+ break;
}
}
if (!handled)
{
- printk("Data Storage exception on %d: %lx, %lx @ %p\n",
- t->tid, getDAR(), getDSISR(), t->context.nip);
- TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
+ printk("Data Storage exception on %d: %lx, %lx @ %p\n",
+ t->tid, getDAR(), getDSISR(), t->context.nip);
+ TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
}
}
@@ -129,7 +129,7 @@ void kernel_execute_inst_storage()
{
printk("Inst Storage exception on %d: %lx, %lx\n",
t->tid, getSRR0(), getSRR1());
- TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
+ TaskManager::endTask(t, NULL, TASK_STATUS_CRASHED);
}
}
@@ -169,19 +169,19 @@ namespace ExceptionHandles
{
uint32_t* instruction = reinterpret_cast<uint32_t*>(phys_addr);
- // Check for 'doze' and skip over. This avoids a task-crash
+ // Check for 'nap' and skip over. This avoids a task-crash
// if for some reason we entered back into the task without
// priviledge raised.
- if (*instruction == 0x4c000324)
+ if (*instruction == 0x4c000364)
{
- printk("Error: Doze executed with lowered permissions on %d\n",
+ printk("Error: Nap executed with lowered permissions on %d\n",
t->tid);
t->context.nip = static_cast<void*>(instruction + 1);
return true;
}
}
- return false;
+ return false;
}
}
diff --git a/src/kernel/kernel.C b/src/kernel/kernel.C
index cbac9a20f..e29af240e 100644
--- a/src/kernel/kernel.C
+++ b/src/kernel/kernel.C
@@ -1,25 +1,26 @@
-// IBM_PROLOG_BEGIN_TAG
-// This is an automatically generated prolog.
-//
-// $Source: src/kernel/kernel.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/kernel.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 <stdint.h>
#include <kernel/console.H>
#include <kernel/pagemgr.H>
@@ -33,6 +34,7 @@
#include <kernel/vmmmgr.H>
#include <kernel/timemgr.H>
#include <sys/vfs.h>
+#include <kernel/deferred.H>
#include <stdlib.h>
@@ -85,6 +87,7 @@ int smp_slave_main(cpu_t* cpu)
CpuManager::init_slave_smp(cpu);
VmmManager::init_slb();
cpu->scheduler->setNextRunnable();
+ DeferredQueue::execute();
kernel_dispatch_task();
return 0;
}
diff --git a/src/kernel/makefile b/src/kernel/makefile
index 06c7536be..c23cb7fe9 100644
--- a/src/kernel/makefile
+++ b/src/kernel/makefile
@@ -1,11 +1,11 @@
-# IBM_PROLOG_BEGIN_TAG
+# IBM_PROLOG_BEGIN_TAG
# This is an automatically generated prolog.
#
# $Source: src/kernel/makefile $
#
# IBM CONFIDENTIAL
#
-# COPYRIGHT International Business Machines Corp. 2010 - 2011
+# COPYRIGHT International Business Machines Corp. 2010-2012
#
# p1
#
@@ -19,14 +19,14 @@
#
# Origin: 30
#
-# IBM_PROLOG_END
+# IBM_PROLOG_END_TAG
ROOTPATH = ../..
OBJS = start.o kernel.o console.o pagemgr.o heapmgr.o taskmgr.o cpumgr.o
OBJS += syscall.o scheduler.o spinlock.o exception.o vmmmgr.o timemgr.o
OBJS += futexmgr.o ptmgr.o segmentmgr.o devicesegment.o basesegment.o
OBJS += block.o cpuid.o misc.o msghandler.o blockmsghdlr.o stacksegment.o
-OBJS += softpatch_p7.o barrier.o idebug.o intmsghandler.o
+OBJS += softpatch_p7.o barrier.o idebug.o intmsghandler.o deferred.o
include ${ROOTPATH}/config.mk
diff --git a/src/kernel/misc.C b/src/kernel/misc.C
index a29aaea21..d45473259 100644
--- a/src/kernel/misc.C
+++ b/src/kernel/misc.C
@@ -26,6 +26,8 @@
#include <kernel/cpuid.H>
#include <kernel/console.H>
#include <kernel/barrier.H>
+#include <kernel/scheduler.H>
+#include <assert.h>
extern "C" void kernel_shutdown(size_t, uint64_t, uint64_t) NO_RETURN;
@@ -82,15 +84,15 @@ namespace KernelMisc
if (c->master)
{
- printk("No payload... doze'ing all threads.\n");
+ printk("No payload... nap'ing all threads.\n");
}
- // Clear LPCR values that wakes up from doze. LPCR[49, 50, 51]
+ // Clear LPCR values that wakes up from nap. LPCR[49, 50, 51]
setLPCR(getLPCR() & (~0x0000000000007000));
while(1)
{
- doze();
+ nap();
}
}
else
@@ -110,4 +112,78 @@ namespace KernelMisc
g_payload_entry);
}
}
+
+ void WinkleCore::masterPreWork()
+ {
+ printk("Winkle threads - ");
+
+ // Save away the current timebase. All threads are in this object
+ // now so they're not going to be using the time for anything else.
+ iv_timebase = getTB();
+ }
+
+ extern "C" void kernel_execute_winkle(task_t* t);
+
+ void WinkleCore::activeMainWork()
+ {
+ cpu_t* cpu = CpuManager::getCurrentCPU();
+ printk("%d", static_cast<int>(cpu->cpu & 0x7));
+
+ // Return current task to run-queue so it isn't lost.
+ cpu->scheduler->returnRunnable();
+ TaskManager::setCurrentTask(cpu->idle_task);
+
+ // Clear LPCR values that wakes up from winkle. LPCR[49, 50, 51]
+ // Otherwise, there may be an interrupt pending or something that
+ // prevents us from fully entering winkle.
+ setLPCR(getLPCR() & (~0x0000000000007000));
+
+ // Deactivate CPU from kernel.
+ cpu->winkled = true;
+ CpuManager::deactivateCPU(cpu);
+
+ // Create kernel save area and store ptr in bottom of kernel stack.
+ task_t* saveArea = new task_t;
+ memset(saveArea, '\0', sizeof(task_t));
+ saveArea->context.msr_mask = 0xC030; // EE, PR, IR, DR.
+ *(reinterpret_cast<task_t**>(cpu->kernel_stack)) = saveArea;
+
+ // Execute winkle.
+ kernel_execute_winkle(saveArea);
+
+ // Re-activate CPU in kernel and re-init VMM SPRs.
+ delete saveArea;
+ cpu->winkled = false;
+ CpuManager::activateCPU(cpu);
+ VmmManager::init_slb();
+
+ // Select a new task if not the master CPU. Master CPU will resume
+ // the code that called cpu_master_winkle().
+ if (!cpu->master)
+ {
+ cpu->scheduler->setNextRunnable();
+ }
+
+ }
+
+ void WinkleCore::masterPostWork()
+ {
+ printk(" - Awake!\n");
+
+ // Restore timebase.
+ setTB(iv_timebase);
+
+ // Restore caller of cpu_master_winkle().
+ TaskManager::setCurrentTask(iv_caller);
+
+ }
+
+ void WinkleCore::nonactiveMainWork()
+ {
+ // Race condition that should not occur...
+ //
+ // Attempted to winkle the master and another thread came online in
+ // the process.
+ kassert(false);
+ }
};
diff --git a/src/kernel/start.S b/src/kernel/start.S
index 7d2d77845..f26592245 100644
--- a/src/kernel/start.S
+++ b/src/kernel/start.S
@@ -145,39 +145,8 @@ finished_relocate:
b kernel_dispatch_task; /* Return to task */
.org _start + 0x100
-intvect_system_reset:
- /* 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
+intvect_system_reset_stub:
+ b intvect_system_reset
.org _start + 0x180
intvect_inst_start:
@@ -272,7 +241,7 @@ softpatch_stub:
mfsprg1 r1 ;// Restore R1 and use normal interrupt code.
STD_INTERRUPT_NOADDR(softpatch)
-.section .text
+.section .text.kernelasm
;// _main:
;// Set up stack and TOC and call kernel's main.
_main:
@@ -302,8 +271,7 @@ _other_thread_spinlock:
1:
ld r3, 0(r2)
;// Loop until value is 1...
- li r4, 1
- cmp cr0, r3, r4
+ cmpi cr0, r3, 1
beq _other_thread_spinlock_complete
or 1,1,1 ;// Lower thread priority.
b 1b
@@ -321,7 +289,7 @@ _other_thread_spinlock_complete:
ld r3, 0(r2) ;// Load CPU object.
cmpi cr0, r3, 0 ;// Check for NULL CPU object.
beq- cr0, 1f ;// Jump to handling if no CPU object found.
- ld r1, 0(r3) ;// Load initial stack.
+ ld r1, CPU_KERNEL_STACK(r3) ;// Load initial stack.
lis r2, smp_slave_main@h ;// Load TOC base.
ori r2, r2, smp_slave_main@l
@@ -329,11 +297,11 @@ _other_thread_spinlock_complete:
bl smp_slave_main ;// Call smp_slave_main
b _main_loop
1:
- ;// No CPU object available, doze this CPU.
+ ;// No CPU object available, nap this CPU.
;// We should only get to this point on simics. SBE will only wake up
;// a single core / thread at a time and we are responsible for
;// further sequencing.
- doze
+ nap
b 1b
@@ -399,8 +367,8 @@ kernel_save_task:
bne- cr0, 1f ;// Jump to FP-save if != NULL.
2:
- ld r1, 0(r1) ;// Get CPU pointer
- ld r1, 0(r1) ;// Get kernel stack pointer.
+ ld r1, TASK_CPUPTR(r1) ;// Get CPU pointer
+ ld r1, CPU_KERNEL_STACK(r1) ;// Get kernel stack pointer.
mfsprg0 r0 ;// Retrieve return address from SPRG0
mtlr r0 ;// Call
@@ -461,8 +429,8 @@ kernel_dispatch_task:
.global kernel_dispatch_task
mfsprg3 r1 ;// Load task structure to r1.
- ldarx r0, 0, r1 ;// Clear the reservation by loading / storing
- stdcx. r0, 0, r1 ;// the CPU pointer in the task.
+ ldarx r0, TASK_CPUPTR, r1 ;// Clear the reservation by loading / storing
+ stdcx. r0, TASK_CPUPTR, r1 ;// the CPU pointer in the task.
mfmsr r2 ;// Get current MSR
ori r2,r2, 0xC030 ;// Enable MSR[EE,PR,IR,DR].
@@ -574,20 +542,88 @@ kernel_dispatch_task:
b 2b
+intvect_system_reset:
+ ;// Need to identify reason for SRESET and then perform appropriate
+ ;// action.
+ ;// Current support:
+ ;// - Initial sreset.
+ ;// - Decrementer wake-up from nap.
+ ;// - External interrupt from nap or winkle.
+ ;// - IPI wake-up from winkle of slave core.
+
+ ;// Raise priority to high.
+ or 3,3,3
+
+ ;// Free up two registers temporarily.
+ mtsprg0 r1
+ mtsprg1 r2
+
+ ;// Check spinlock for 0, which implies we haven't started yet.
+ lis r2, kernel_other_thread_spinlock@h
+ ori r2, r2, kernel_other_thread_spinlock@l
+ ld r2, 0(r2)
+ cmpi cr0, r2, 0
+ beq- _start
+
+ ;// Get CPU object from thread ID, check for NULL which implies not
+ ;// started yet.
+ mfspr r1, PIR
+ lis r2, _ZN10CpuManager7cv_cpusE@h
+ ori r2, r2, _ZN10CpuManager7cv_cpusE@l
+ ld r2, 0(r2) ;// Dereference cv_cpus to get array.
+ muli r1, r1, 8
+ ldx r2, r1, r2 ;// Load CPU object.
+ cmpi cr0, r2, 0 ;// Check for NULL CPU object.
+ beq- _start
+
+ ;// Check for inactive CPU.
+ ld r1, CPU_STATUS(r2)
+ extrdi. r1, r1, 1, CPU_STATUS_ACTIVE
+ beq- intvect_system_reset_inactive
+
+ ;// Now we were an active processor so this must be a nap-wakeup.
+
+ ;// 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+ 1f ;// TODO: need to handle HMIs?
+1: ;// Unknown reason.
+ b 1b
+
+ ;// @fn intvect_system_reset_inactive
+ ;// Handle SRESET on an inactive processor.
+ ;// This is due to either instruction start or winkle-wakeup.
+intvect_system_reset_inactive:
+ ;// Check winkle state in CPU.
+ ld r1, CPU_STATUS(r2)
+ extrdi. r1, r1, 1, CPU_STATUS_WINKLED
+ beq+ _start
+
+ ;// Now we are a winkled processor that is awoken.
+ ld r1, CPU_KERNEL_STACK(r2)
+ ld r1, 0(r1)
+ mtsprg3 r1
+ b kernel_dispatch_task
+
;// @fn intvect_system_reset_decrementer
;// Handle SRESET due to decrementer wake-up.
- ;// This is a wake-up from 'doze'. Clear priviledge escalation and
+ ;// This is a wake-up from 'nap'. Clear priviledge escalation and
;// perform decrementer.
intvect_system_reset_decrementer:
- ;// Restore CR.
- mtcr r1
-
- ;// Clear MSR mask, since privilaged instruction was now executed (doze).
+ ;// Clear MSR mask, since privilaged instruction was now executed (nap).
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).
+ ;// Advance saved NIA (past nap).
mfsrr0 r1
addi r1, r1, 4
mtsrr0 r1
@@ -600,13 +636,10 @@ intvect_system_reset_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
+ ;// This is a wake-up from 'nap', but not due to the decrementer
+ ;// itself firing. Therefore, leave 'nap' 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
@@ -638,9 +671,9 @@ system_call_fast_path:
bne cr0, 4f
;// Check for being on master processor.
mfsprg3 r6 ;// Get task structure.
- ld r6, 0(r6) ;// Get CPU structure.
- lbz r6, 12(r6) ;// Read master boolean.
- cmpi cr0, r6, 0x0
+ ld r6, TASK_CPUPTR(r6) ;// Get CPU structure.
+ ld r6, CPU_STATUS(r6) ;// Read master boolean.
+ extrdi. r6, r6, 1, CPU_STATUS_MASTER
beq cr0, 300f ;// Call TASK_MIGRATE_TO_MASTER if not on master.
;// Read scratch.
mtspr 276, r4
@@ -665,9 +698,9 @@ system_call_fast_path:
bne cr0, 5f
;// Check for master processor.
mfsprg3 r6 ;// Get task structure.
- ld r6, 0(r6) ;// Get CPU structure.
- lbz r6, 12(r6) ;// Read master boolean.
- cmpi cr0, r6, 0x0
+ ld r6, TASK_CPUPTR(r6) ;// Get CPU structure.
+ ld r6, CPU_STATUS(r6) ;// Read master boolean.
+ extrdi. r6, r6, 1, CPU_STATUS_MASTER
beq cr0, 300b ;// Call TASK_MIGRATE_TO_MASTER if not on master.
;// Write scratch.
mtspr 276, r4
@@ -785,6 +818,34 @@ kernel_shutdown_ea0_1_mode:
STD_INTERRUPT_NOADDR(hype_emu_assist)
+ ;// @fn kernel_execute_winkle
+ ;//
+ ;// Saves kernel state into a specified task structure and then executes
+ ;// the winkle instruction.
+ ;//
+ ;// @param r3 - task_t* to save kernel state into.
+ ;//
+.global kernel_execute_winkle
+kernel_execute_winkle:
+ ;// Move save area to SPRG3 for kernel_save_task.
+ mtsprg3 r3
+
+ ;// Copy LR to SRR0 (since that is where kernel_save_task gets it from).
+ mflr r3
+ mtsrr0 r3
+
+ ;// Load winkle instruction address into the "return to" address (SPRG0).
+ lis r3, 1f@h
+ ori r3, r3, 1f@l
+ mtsprg0 r3
+
+ ;// Save kernel state.
+ b kernel_save_task
+
+ ;// Execute winkle.
+1:
+ rvwinkle
+
.section .data
.balign 1024
kernel_stack:
diff --git a/src/kernel/syscall.C b/src/kernel/syscall.C
index 6dcbe0c25..645691d70 100644
--- a/src/kernel/syscall.C
+++ b/src/kernel/syscall.C
@@ -52,19 +52,7 @@ void kernel_execute_decrementer()
task_t* current_task = TaskManager::getCurrentTask();
- CpuManager::executePeriodics(c);//TODO is there still a potential deadlock?
-
- if (CpuManager::isShutdownRequested())
- {
- // The code below could cause a hang during shutdown
- // The stats can be retrieved from global variables as needed.
- // This can be uncommented for debug if desired
-#ifdef __MEMSTATS__
- if(c->master)
- HeapManager::stats();
-#endif
- KernelMisc::shutdown();
- }
+ CpuManager::executePeriodics(c);
if (current_task == TaskManager::getCurrentTask())
{
@@ -98,7 +86,8 @@ namespace Systemcalls
void CpuDDLevel(task_t *t);
void CpuStartCore(task_t *t);
void CpuSprValue(task_t *t);
- void CpuDoze(task_t *t);
+ void CpuNap(task_t *t);
+ void CpuWinkle(task_t *t);
void MmAllocBlock(task_t *t);
void MmRemovePages(task_t *t);
void MmSetPermission(task_t *t);
@@ -134,7 +123,8 @@ namespace Systemcalls
&CpuDDLevel, // MISC_CPUDDLEVEL
&CpuStartCore, // MISC_CPUSTARTCORE
&CpuSprValue, // MISC_CPUSPRVALUE
- &CpuDoze, // MISC_CPUDOZE
+ &CpuNap, // MISC_CPUNAP
+ &CpuWinkle, // MISC_CPUWINKLE
&MmAllocBlock, // MM_ALLOC_BLOCK
&MmRemovePages, // MM_REMOVE_PAGES
@@ -670,33 +660,52 @@ namespace Systemcalls
};
/**
- * Allow a task to request priviledge escalation to execute the 'doze'
+ * Allow a task to request priviledge escalation to execute the 'nap'
* instruction.
*
- * Verifies the instruction to execute is, in fact, doze and then sets
+ * Verifies the instruction to execute is, in fact, nap 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
+ * When 'nap' 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
+ * advance the task to the instruction after the nap and remove
* priviledge escalation.
*
*/
- void CpuDoze(task_t *t)
+ void CpuNap(task_t *t)
{
uint32_t* instruction = static_cast<uint32_t*>(t->context.nip);
- if (0x4c000324 == (*instruction)) // Verify 'doze' instruction,
+ if (0x4c000364 == (*instruction)) // Verify 'nap' instruction,
// otherwise just return.
{
- // Disable PR, IR, DR so 'doze' can be executed.
+ // Disable PR, IR, DR so 'nap' can be executed.
// (which means to stay in HV state)
t->context.msr_mask = 0x4030;
}
};
+ /** Winkle all the threads so that the runtime SLW image can be loaded. */
+ void CpuWinkle(task_t *t)
+ {
+ cpu_t* cpu = CpuManager::getCurrentCPU();
+
+ if ((CpuManager::getCpuCount() > CpuManager::getThreadCount()) ||
+ (!cpu->master))
+ {
+ TASK_SETRTN(t, -EDEADLK);
+ }
+ else
+ {
+ TASK_SETRTN(t, 0);
+ DeferredQueue::insert(new KernelMisc::WinkleCore(t));
+ TaskManager::setCurrentTask(cpu->idle_task);
+ DeferredQueue::execute();
+ }
+ }
+
/**
* 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/lib/syscall_misc.C b/src/lib/syscall_misc.C
index 7b23ef22b..c1b47b772 100644
--- a/src/lib/syscall_misc.C
+++ b/src/lib/syscall_misc.C
@@ -25,6 +25,7 @@
#include <sys/misc.h>
#include <sys/syscall.h>
+#include <sys/task.h>
using namespace Systemcalls;
@@ -85,6 +86,13 @@ uint64_t cpu_spr_value(CpuSprNames spr)
int cpu_master_winkle()
{
- return 0;
+ task_affinity_pin();
+ task_affinity_migrate_to_master();
+
+ int rc = reinterpret_cast<int64_t>(_syscall0(MISC_CPUWINKLE));
+
+ task_affinity_unpin();
+
+ return rc;
}
diff --git a/src/makefile b/src/makefile
index 4a59af354..4dcc6006a 100644
--- a/src/makefile
+++ b/src/makefile
@@ -29,7 +29,8 @@ EXTRA_LIDS = dslid
BASE_OBJECTS = console.o spinlock.o string.o string_ext.o stdlib.o ctype.o \
assert.o stdio.o builtins.o vfs_init.o heapmgr.o pagemgr.o \
- math.o barrier.o idebug.o intmsghandler.o idletask.o splaytree.o
+ math.o barrier.o idebug.o intmsghandler.o deferred.o \
+ idletask.o splaytree.o
ifdef HOSTBOOT_PROFILE
BASE_OBJECTS += gcov.o
diff --git a/src/sys/prof/idletask.C b/src/sys/prof/idletask.C
index da568f955..1c38835ce 100644
--- a/src/sys/prof/idletask.C
+++ b/src/sys/prof/idletask.C
@@ -42,11 +42,11 @@ void TaskManager::idleTaskLoop(void* unused)
// 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");
+ // Request privilege escalation for nap.
+ register uint64_t syscall = MISC_CPUNAP;
+ asm volatile("or 3, %0, %0; sc" :: "r" (syscall) : "r3", "cc");
- // Execute doze.
- doze();
+ // Execute nap.
+ nap();
}
}
diff --git a/src/usr/hwpf/hwp/core_activate/core_activate.C b/src/usr/hwpf/hwp/core_activate/core_activate.C
index 99d02baab..7e50c93e3 100644
--- a/src/usr/hwpf/hwp/core_activate/core_activate.C
+++ b/src/usr/hwpf/hwp/core_activate/core_activate.C
@@ -134,6 +134,9 @@ using namespace ISTEP;
"proc_prep_master_winkle SUCCESS" );
}
+ if (is_vpo()) // TODO: RTC 46651 - Simics doesn't support winkle.
+ {
+
// put the master into winkle.
TRACFCOMP( ISTEPS_TRACE::g_trac_isteps_trace,
"call_host_activate_master: put master into winkle..." );
@@ -163,11 +166,7 @@ using namespace ISTEP;
break;
}
-
- // --------------------------------------------------------
- // $$ @todo do something to trigger IPI at this point.
- // MAGIC_INSTRUCTION( ???? );
- // --------------------------------------------------------
+ } // TODO: Remove with RTC 46651
// --------------------------------------------------------
OpenPOWER on IntegriCloud