Commit 5d8ba826 authored by Jeffrey Lee's avatar Jeffrey Lee
Browse files

Initial support for per-core privileged mode stacks

There are several situations in which the kernel/OS needs to check or
reset the privileged mode stack pointers. Until now the kernel would
have been using hardcoded addresses for this, but that won't work for
SMP setups, where each core will need to have its own unique privileged
mode stacks, or for SVC-mode threading, where each thread is given its
own SVC stack.

To resolve this, store the default stack pointers in a struct in kernel
workspace, and fetch the values from there as needed.

ARMv7 introduces extra, core-local, CP15 registers for storing
thread/process IDs. So on ARMv7+, we'll use the TPIDRPRW register to
hold the pointer to the workspace struct. On startup the kernel will
correctly initialise this register for the primary core; the SMP module
is expected to initialise the register & workspace for the other cores,
as needed. Older CPUs (which are assumed to be single-core) will access
the struct directly via a hardcoded address.
parent 2a3ad40a
......@@ -33,6 +33,7 @@ CUSTOMROM = custom
CUSTOMEXP = custom
CUSTOMSA = custom
EXPORTS = ${EXP_HDR}.AMBControl \
${EXP_HDR}.CPUCoreWS \
${EXP_HDR}.DBellDevice \
${EXP_HDR}.EnvNumbers \
${EXP_HDR}.HALDevice \
......@@ -49,6 +50,7 @@ EXPORTS = ${EXP_HDR}.AMBControl \
${EXP_HDR}.VduExt \
${EXP_HDR}.VIDCList \
${EXP_HDR}.VideoDevice \
${C_EXP_HDR}.CPUCoreWS \
${C_EXP_HDR}.HALDevice \
${C_EXP_HDR}.HALEntries \
${C_EXP_HDR}.ModHand \
......@@ -108,6 +110,9 @@ ${EXP_HDR}.EnvNumbers: hdr.EnvNumbers
${EXP_HDR}.DBellDevice: hdr.DBellDevice
${CP} hdr.DBellDevice $@ ${CPFLAGS}
${EXP_HDR}.CPUCoreWS: hdr.CPUCoreWS
${CP} hdr.CPUCoreWS $@ ${CPFLAGS}
${EXP_HDR}.HALDevice: hdr.HALDevice
${CP} hdr.HALDevice $@ ${CPFLAGS}
......@@ -150,6 +155,9 @@ ${EXP_HDR}.VIDCList: hdr.VIDCList
${EXP_HDR}.VideoDevice: hdr.VideoDevice
${CP} hdr.VideoDevice $@ ${CPFLAGS}
${C_EXP_HDR}.CPUCoreWS: Global.h.CPUCoreWS h.CPUCoreWS
${FAPPEND} $@ h.CPUCoreWS Global.h.CPUCoreWS
${C_EXP_HDR}.HALDevice: Global.h.HALDevice h.HALDevice
${FAPPEND} $@ h.HALDevice Global.h.HALDevice
......@@ -191,6 +199,10 @@ ${C_EXP_HDR}.VduExt: hdr.VduExt
${C_EXP_HDR}.VIDCList: Global.h.VIDCList h.VIDCList
${FAPPEND} $@ h.VIDCList Global.h.VIDCList
Global.h.CPUCoreWS: hdr.CPUCoreWS
${MKDIR} Global.h
${HDR2H} hdr.CPUCoreWS $@
Global.h.HALDevice: hdr.HALDevice
${MKDIR} Global.h
${HDR2H} hdr.HALDevice $@
......
/*
* Copyright (c) 2017, RISC OS Open Ltd
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef GLOBAL_CPUCOREWS_H
#include <stddef.h>
#include <stdint.h>
typedef struct {
size_t Size; /* Size of structure */
int ID; /* CPU core number */
uintptr_t UNDSTK; /* Stack top pointers for each privileged mode */
uintptr_t ABTSTK;
uintptr_t IRQSTK;
uintptr_t SVCSTK;
} KernelCWS;
#endif
/* In the exported copy of this file, the Hdr2H translation of hdr.CPUCoreWS will follow. */
;
; Copyright (c) 2017, RISC OS Open Ltd
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
; * Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; * Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
; * Neither the name of RISC OS Open Ltd nor the names of its contributors
; may be used to endorse or promote products derived from this software
; without specific prior written permission.
;
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
; ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
; POSSIBILITY OF SUCH DAMAGE.
;
; Per-CPU core workspace
^ 0
KernelCWS_Size # 4 ; Size of structure
KernelCWS_ID # 4 ; CPU core number
KernelCWS_UNDSTK # 4 ; Stack top pointers for each privileged mode
KernelCWS_ABTSTK # 4
KernelCWS_IRQSTK # 4
KernelCWS_SVCSTK # 4
KernelCWS_DefSize # 0 ; Defined size of structure
END
......@@ -1333,6 +1333,8 @@ ExtendedROMFooter # 4 ; Pointer to the extended ROM footer structure. 0 if not i
CPUFeatures # 2*4
Core0WS # KernelCWS_DefSize
[ :DEF: ShowWS
! 0, "Free space after EnvString = ":CC::STR:(&500-@)
]
......
......@@ -80,6 +80,7 @@
GET Hdr:OSRSI6
GET Hdr:PL310
GET Hdr:AMBControl
GET Hdr:CPUCoreWS
; now the main parts of the MOS
......
......@@ -1589,14 +1589,36 @@ ROMDecompAlign_$pt * 20
40
Pull "v1-v7"
; Set up core 0 workspace and stack pointers
LDR a1, =ZeroPage + Core0WS
[ NoARMv7
[ SupportARMv7
; TPIDRPRW only supported on ARMv7+; check the cache type register
ASSERT :LNOT: NoARMv6 ; Assume we don't have to worry about pre-ARMv6
MRC p15, 0, ip, c0, c0, 1 ; Cache type register
TST ip, #1<<31
MCRNE p15, 0, a1, c13, c0, 4 ; Set TIPDRPRW
]
|
MCR p15, 0, a1, c13, c0, 4 ; Set TPIDRPRW
]
LDR ip, =KernelCWS_DefSize
STR ip, [a1, #KernelCWS_Size]
MOV ip, #0
STR ip, [a1, #KernelCWS_ID]
MSR CPSR_c, #F32_bit+I32_bit+IRQ32_mode
LDR sp, =IRQSTK
STR sp, [a1, #KernelCWS_IRQSTK]
MSR CPSR_c, #F32_bit+I32_bit+ABT32_mode
LDR sp, =ABTSTK
STR sp, [a1, #KernelCWS_ABTSTK]
MSR CPSR_c, #F32_bit+I32_bit+UND32_mode
LDR sp, =UNDSTK
STR sp, [a1, #KernelCWS_UNDSTK]
MSR CPSR_c, #F32_bit+SVC2632
LDR sp, =SVCSTK
STR sp, [a1, #KernelCWS_SVCSTK]
BL ConstructCAMfromPageTables
......
......@@ -205,6 +205,28 @@ access SETA access :OR: CMA_Partially_PrivR
]
MEND
; *********************************************************
; *** GetCoreWS - Get a pointer to the core workspace ***
; *** for the calling CPU core. ***
; *********************************************************
MACRO
GetCoreWS $reg
[ NoARMv7
[ SupportARMv7
; TPIDRPRW only supported on ARMv7+; check the cache type register
ASSERT :LNOT: NoARMv6 ; Assume we don't have to worry about pre-ARMv6
MRC p15, 0, $reg, c0, c0, 1 ; Cache type register
TST $reg, #1<<31
LDREQ $reg, =ZeroPage + Core0WS
MRCNE p15, 0, $reg, c13, c0, 4 ; Read TPIDRPRW
|
LDR $reg, =ZeroPage + Core0WS
]
|
MRC p15, 0, $reg, c13, c0, 4 ; Read TPIDRPRW
]
MEND
a1 RN 0
a2 RN 1
a3 RN 2
......@@ -839,7 +861,9 @@ ErrHandler ROUT
Pull "r0-r2"
LDR r11, [r10, #ErrBuf] ; Get pointer to error buffer
LDR sp_svc, =SVCSTK-4*4 ; Just below top of stack
GetCoreWS r12
LDR r12, [r12, #KernelCWS_SVCSTK]
SUB sp_svc, r12, #4*4 ; Just below top of stack
Pull r14
STR r14, [r11], #4 ; Return PC for error
......@@ -934,7 +958,9 @@ Do_CallBack_postpone_already_clear
BEQ back_to_user
; Check that SVC_sp is empty (apart from r14,r10-r12), i.e. system truly is idle
LDR r12, =SVCSTK-4*4 ; What SVC_sp should be if system idle
GetCoreWS r12
LDR r12, [r12, #KernelCWS_SVCSTK]
SUB r12, r12, #4*4 ; What SVC_sp should be if system idle
CMP sp, r12 ; Stack empty?
BLO back_to_user ; No then no call back
BIC r11, r11, #CBack_OldStyle
......@@ -1373,7 +1399,8 @@ SEXIT ROUT
LDR lr, [r0, #SExitA]
STR lr, [r0, #Curr_Active_Object]
LDR r12, [r0, #SExitA_ws]
LDR sp_svc, =SVCSTK
GetCoreWS r0
LDR sp_svc, [r0, #KernelCWS_SVCSTK]
MRS r0, CPSR
MSR CPSR_c, #I32_bit+SVC2632 ; IRQs off (to protect SPSR_svc)
BIC r0, r0, #I32_bit+F32_bit+&0F
......
......@@ -282,7 +282,9 @@ SBRKPT ROUT
NOP
]
10 LDR stack, =SVCSTK
10
GetCoreWS r12
LDR stack, [r12, #KernelCWS_SVCSTK]
LDR r12, =ZeroPage+BrkAd_ws
LDMIA r12, {r12, pc} ; call breakpoint handler
......@@ -675,7 +677,8 @@ UNDEF1
BL CallVector
MSR CPSR_c, #I32_bit+F32_bit+SVC32_mode ; into SVC mode
LDR sp, =SVCSTK ; Flatten superstack
GetCoreWS r10
LDR sp, [r10, #KernelCWS_SVCSTK] ; Flatten superstack
; Check that ExceptionDump is safe to use
Push "R7" ; Preserve error ptr
......@@ -777,14 +780,15 @@ UNDEF1
; Flatten UND and ABT stacks, jic
; Also a convenient way of getting rid of the temp exception dump
GetCoreWS r10
MRS R2, CPSR
BIC R2, R2, #F32_bit + &1F
ORR R3, R2, #ABT32_mode
MSR CPSR_c, R3 ; FIQs back on
LDR r13_abort, =ABTSTK
LDR r13_abort, [r10, #KernelCWS_ABTSTK]
ORR R3, R2, #UND32_mode
MSR CPSR_c, R3
LDR r13_undef, =UNDSTK
LDR r13_undef, [r10, #KernelCWS_UNDSTK]
ORR R3, R2, #IRQ32_mode
MSR CPSR_c, R3
LDR R1, =ZeroPage
......@@ -794,7 +798,7 @@ UNDEF1
MOV R3, #0
STR R3, [R1, #IRQsema]
]
LDR r13_irq, =IRQSTK
LDR r13_irq, [r10, #KernelCWS_IRQSTK]
; Trigger exception dump processing
ORR R3, R2, #SVC32_mode
......@@ -1491,38 +1495,59 @@ ExitNoEthernetAddress
STMEQIA sp,{r2,r4} ; Set up single-entry list on stack
MOVEQ r1,sp ; r1 -> input list
ADDEQ r2,sp,#8+8 ; r2 -> stacked R2 for result
B %FT62
61 ; Common loop body end (store R0 and process next item)
STR r0,[r2],#4
62
LDR r4,[r1],#4
CMP r4,#-1
BEQ %FT66
BEQ %FT69
CMP r4,#osri6_maxvalue
LDRLS r0,[r3,r4,LSL #2]
LDRLS r0,[r3,r4,LSL #2] ; Get default value from the table
MOVHI r0,#0
[ LongDesc :LAND: ShortDesc
; Zero the ShortDesc page table pointers if LongDesc is in use
TEQ r4,#OSRSI6_L1PT
TEQNE r4,#OSRSI6_L2PT
BEQ %FT63
BNE %FT63
PTWhich r4
MOVNE r0,#0
B %BT61
63
]
; Fix up the DevicesEnd values
TEQ r4,#OSRSI6_Danger_DevicesEnd
TEQNE r4,#OSRSI6_DevicesEnd
STRNE r0,[r2],#4
BNE %BT62
BNE %FT64
LDR r4,=ZeroPage
LDR r4,[r4,#IRQMax]
ADD r0,r0,r4,LSL #3
ADD r0,r0,r4,LSL #2
STR r0,[r2],#4
B %BT62
[ LongDesc :LAND: ShortDesc
63
PTWhich r4
MOVNE r0,#0
STR r0,[r2],#4
B %BT62
]
66
B %BT61
64
; Fix up stack pointers
TEQ r4,#OSRSI6_UNDSTK
TEQNE r4,#OSRSI6_SVCSTK
TEQNE r4,#OSRSI6_Danger_IRQSTK
TEQNE r4,#OSRSI6_ROL_IRQSTK
TEQNE r4,#OSRSI6_IRQSTK
TEQNE r4,#OSRSI6_ABTSTK
BNE %BT61 ; Other values: No fix up needed
GetCoreWS r0
TEQ r4,#OSRSI6_UNDSTK
LDREQ r0,[r0,#KernelCWS_UNDSTK]
TEQ r4,#OSRSI6_SVCSTK
LDREQ r0,[r0,#KernelCWS_SVCSTK]
TEQ r4,#OSRSI6_Danger_IRQSTK
TEQNE r4,#OSRSI6_ROL_IRQSTK
TEQNE r4,#OSRSI6_IRQSTK
LDREQ r0,[r0,#KernelCWS_IRQSTK]
TEQ r4,#OSRSI6_ABTSTK
LDREQ r0,[r0,#KernelCWS_ABTSTK]
B %BT61
69
ADD sp,sp,#8
Pull "r0-r4"
ExitSWIHandler
......
......@@ -818,7 +818,8 @@ EnterIt
SWI XOS_FSControl
BVS CantGoIntoModule
LDR stack, =SVCSTK
GetCoreWS r0
LDR stack, [r0, #KernelCWS_SVCSTK]
MOV R0, R10
WritePSRc 0, R14
MOV r0, r0 ; NOP because we've changed mode
......
......@@ -458,7 +458,8 @@ GOEX SUB R1, R4, #1
SWI XOS_FSControl
Pull "R7, PC", VS
LDR sp_svc, =SVCSTK ; remove supervisor stuff
GetCoreWS R14
LDR sp_svc, [R14, #KernelCWS_SVCSTK] ; remove supervisor stuff
WritePSRc 0, R14 ; in to user mode
MOV PC, R7
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment