Commit ac1ea0f5 authored by ROOL's avatar ROOL 🤖

Change module initialisation to be a two pass scheme

Detail:
  To make it easier to support arbitrary complexity keyboard controllers (eg. USB via DWCDriver on the Pi) have the kernel do the early keyboard recovery key press detection instead of the HAL.
  During the first pass those modules used for reading the keyboard are started, ignoring the CMOS frugal bits.
  The keyboard is then scanned for 3s, during which time the RAM is cleared (unless the HAL indicated it has already been done).
  During the second pass the remaining modules are started respecting the CMOS frugal bits. Any which were already started in the first pass are inserted into the new chain, so the keyboard is reset once and only once.

  Boot times, with a 300cs key scan time in NewReset.
  Risc PC with 160MB RAM (128+32+0).
  Times from turning on power to initial "beep", using a stopwatch.
                RISC OS 3.70 RISC OS 5.22 This OS
  ARM610        12.5         10.4         10.3
  ARM710        11.8         10.2         9.7
  StrongARM 233 11.1         9.5          8.4

  In NewReset.s:
  Remove old KbdScan code (leave Reset_IRQ_Handler for IIC only)
  If HAL_KbdScanDependencies returns a null string then present KbdDone flag and skip to full init.
  A few vestiges of soft resets removed.
  Do RAM clear when waiting for INKEY (being careful not to trash the running modules...).
  Clearing just the freepool on a 2GB Titanium cleared 7EFD6 pages (99.2%).

  In ModHand.s:
  2nd pass need to sneaky renumber the nodes (so *ROMModules is in the right order, frugal bits line up) without resetting the chain

  In HAL.s:
  Change ClearPhysRAM to ClearWkspRAM, such that it only clears the kernel workspace rather than all RAM. The bulk of the RAM is cleared during the keyboard scan by new function ClearFreePoolSection.
  Add a variant of Init_MapInRAM which clears the mapped in RAM too (as these very early claims will not be in the free pool when the RAM is cleared later).
  Remove HAL keyboard scan setup & IRQ handler.
  Fix bug in HALDebugHexTX2, the input value needs pre-shifting by 16b before continuing.

  In GetAll.s, PMF/osbyte.s:
  Use Hdr:Countries and Hdr:OsBytes for constants.

  In PMF/key.s, PMF/osinit.s:
  Relocate the key post init from PostInit to KeyPostInit.
  Changed PostInit to not tail call KeyPostInit so they can be called independently.

  In hdr/KernelWs:
  Improve comments, add InitWsStart label to refer to.

  In hdr/HALEntries:
  Add HAL_KbdScanDependencies.
  Delete KbdFlag exports.
  Took the opportunity to reorder some of the higher numbered HAL entries and re-grouping, specifically (112,120) (84,106,108,117).
Admin:
  Tested on an ARM6/ARM7/SA Risc PC, BeagleBoard xM, Iyonix, Pandaboard ES, Wandboard Quad, IPEGv5, Titanium, Pi 2 and 3.
  Requires corresponding HAL change.
  Submission for USB bounty.

Version 5.89. Tagged as 'Kernel-5_89'
parent 93841f4b
......@@ -11,13 +11,13 @@
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.88"
Module_Version SETA 588
Module_MajorVersion SETS "5.89"
Module_Version SETA 589
Module_MinorVersion SETS ""
Module_Date SETS "27 Aug 2017"
Module_ApplicationDate SETS "27-Aug-17"
Module_Date SETS "09 Sep 2017"
Module_ApplicationDate SETS "09-Sep-17"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "castle/RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.88"
Module_HelpVersion SETS "5.88 (27 Aug 2017)"
Module_FullVersion SETS "5.89"
Module_HelpVersion SETS "5.89 (09 Sep 2017)"
END
/* (5.88)
/* (5.89)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 5.88
#define Module_MajorVersion_CMHG 5.89
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 27 Aug 2017
#define Module_Date_CMHG 09 Sep 2017
#define Module_MajorVersion "5.88"
#define Module_Version 588
#define Module_MajorVersion "5.89"
#define Module_Version 589
#define Module_MinorVersion ""
#define Module_Date "27 Aug 2017"
#define Module_Date "09 Sep 2017"
#define Module_ApplicationDate "27-Aug-17"
#define Module_ApplicationDate "09-Sep-17"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "castle/RiscOS/Sources/Kernel"
#define Module_FullVersion "5.88"
#define Module_HelpVersion "5.88 (27 Aug 2017)"
#define Module_LibraryVersionInfo "5:88"
#define Module_FullVersion "5.89"
#define Module_HelpVersion "5.89 (09 Sep 2017)"
#define Module_LibraryVersionInfo "5:89"
......@@ -124,8 +124,8 @@ EntryNo_HAL_UARTBreak # 1 ; 80
EntryNo_HAL_UARTModemControl # 1 ; 81
EntryNo_HAL_UARTModemStatus # 1 ; 82
EntryNo_HAL_UARTDevice # 1 ; 83
EntryNo_HAL_UARTDefault # 1 ; 84
EntryNo_HAL_Reset # 1 ; 84
EntryNo_HAL_DebugRX # 1 ; 85
EntryNo_HAL_DebugTX # 1 ; 86
......@@ -146,24 +146,22 @@ EntryNo_HAL_PlatformName # 1 ; 97, ReadSysInfo 9 subreason 7 (was H
EntryNo_HAL_InitDevices # 1 ; 100
EntryNo_HAL_KbdScanSetup # 1 ; 101
EntryNo_HAL_KbdScan # 1 ; 102
EntryNo_HAL_KbdScanFinish # 1 ; 103
EntryNo_HAL_KbdScanInterrupt # 1 ; 104
EntryNo_HAL_KbdScanDependencies # 1 ; 101
# 1 ; 102 (was HAL_KbdScan)
# 1 ; 103 (was HAL_KbdScanFinish)
# 1 ; 104 (was HAL_KbdScanInterrupt)
EntryNo_HAL_PhysInfo # 1 ; 105
EntryNo_HAL_USBControllerInfo # 1 ; 106
EntryNo_HAL_Reset # 1 ; 106
EntryNo_HAL_IRQMax # 1 ; 107 (was HAL_MonitorLeadID)
EntryNo_HAL_VideoRender # 1 ; 108
EntryNo_HAL_USBControllerInfo # 1 ; 108
EntryNo_HAL_USBPortPower # 1 ; 109
EntryNo_HAL_USBPortIRQStatus # 1 ; 110
EntryNo_HAL_USBPortIRQClear # 1 ; 111
EntryNo_HAL_VideoIICOp # 1 ; 112
EntryNo_HAL_USBPortDevice # 1 ; 112
EntryNo_HAL_TimerIRQClear # 1 ; 113
EntryNo_HAL_TimerIRQStatus # 1 ; 114
......@@ -171,13 +169,10 @@ EntryNo_HAL_TimerIRQStatus # 1 ; 114
EntryNo_HAL_ExtMachineID # 1 ; 115, ReadSysInfo 10
EntryNo_HAL_VideoFramestoreAddress # 1 ; 116
EntryNo_HAL_UARTDefault # 1 ; 117
EntryNo_HAL_VideoRender # 1 ; 117
EntryNo_HAL_VideoStartupMode # 1 ; 118
EntryNo_HAL_VideoPixelFormatList # 1 ; 119
EntryNo_HAL_USBPortDevice # 1 ; 120
EntryNo_HAL_VideoIICOp # 1 ; 120
EntryNo_HAL_Watchdog # 1 ; 121
......@@ -232,17 +227,6 @@ IICStatus_Busy # 1
IICStatus_Slave # 1
IICStatus_Error # 1
; Keyboard scan
KbdFlag_Ctrl * 1:SHL:0
KbdFlag_Shift * 1:SHL:1
KbdFlag_R * 1:SHL:4
KbdFlag_T * 1:SHL:5
KbdFlag_Delete * 1:SHL:6
KbdFlag_Copy * 1:SHL:7
KbdFlag_Present * 1:SHL:30
KbdFlag_Done * 1:SHL:31
; USB
^ 0
......
......@@ -996,18 +996,19 @@ IICBus_Size # 0
; *****************************************************************************
; Real workspace definition
; locations used during reset only. Not cleared by ClearPhysRAM, but
; locations used during reset only. Not cleared by ClearWkspRAM, but
; cleared later (just before DEFHAN).
; Note that these are all relative to ZeroPage!
^ &80 ; steer clear of FIQ code
InitWsStart # 0
InitIRQHandler # 4 ; pointer to IRQ handler (LDR PC'ed from IRQ HW vector)
InitIRQWs # 16 ; workspace for IRQ handler
InitUsedStart # 4 ; start of used pages (L2PT etc) not to be cleared
InitUsedEnd # 4 ; end of used pages
InitUsedBlock # 4 ; current block in PhysRamTable
InitClearRamWs # 10*4
InitClearRamWs # 10*4 ; preserve registers during ClearPhysRAM
InitDMABlock # 8 ; block of DMAable memory extracted from PhysRamTable
InitDMAOffset # 4 ; offset+8 into PhysRamTable where memory was taken
InitDMAEnd # 4 ; current DMA alloc pos
......
......@@ -64,6 +64,7 @@
GET Hdr:OsBytes
GET Hdr:Internatio
GET Hdr:Territory
GET Hdr:Countries
GET Hdr:Portable
GET Hdr:MsgTrans
GET Hdr:PaletteV
......
......@@ -762,8 +762,7 @@ RISCOS_Start
LDR a2, [sp, #0]
STR a2, [a1, #HAL_StartFlags]
; Set up a reset IRQ handler (used during RAM clear for keyboard
; scan, and later for IIC CMOS access)
; Set up a reset IRQ handler (for IIC CMOS access)
MSR CPSR_c, #IRQ32_mode + I32_bit + F32_bit
LDR sp_irq, =ScratchSpace + 1024 ; 1K is plenty since Reset_IRQ_Handler now runs in SVC mode
MSR CPSR_c, #SVC32_mode + I32_bit + F32_bit
......@@ -1041,16 +1040,6 @@ MMUon_nol1ptoverlap
BL IICInit
LDR a1, =ZeroPage+InitIRQWs
MOV a2, #1
STRB a2, [a1, #KbdScanActive]
DebugTX "HAL_KbdScanSetup"
CallHAL HAL_KbdScanSetup
MSR CPSR_c, #F32_bit+SVC32_mode ; enable IRQs for scan
; Remember some stuff that's about to get zapped
LDR ip, =ZeroPage
LDR v4, [ip, #ROMPhysAddr]
......@@ -1060,7 +1049,7 @@ MMUon_nol1ptoverlap
LDR a1, [ip, #HAL_StartFlags]
TST a1, #OSStartFlag_RAMCleared
BLEQ ClearPhysRAM ; Only clear the memory if the HAL didn't
BLEQ ClearWkspRAM ; Only clear the memory if the HAL didn't
; Put it back
LDR ip, =ZeroPage
......@@ -1069,7 +1058,7 @@ MMUon_nol1ptoverlap
STR v7, [ip, #MaxCamEntry]
STR v8, [ip, #IRQMax]
; Calculate CPU feature flags (if moving this to before ClearPhysRAM, ensure the workspace also gets moved into the skipped region)
; Calculate CPU feature flags
BL ReadCPUFeatures
MOV v8, ip
......@@ -1259,7 +1248,7 @@ ROMDecompWSAddr * 4<<20
LDR a1, =SysHeapAddress
LDR a2, =AreaFlags_SysHeap
LDR a3, =32*1024
BL Init_MapInRAM
BL Init_MapInRAM_Clear
; Allocate the cursor/system/sound block - first the cached bit
LDR a1, =CursorChunkAddress
......@@ -1275,14 +1264,14 @@ ROMDecompWSAddr * 4<<20
LDR a1, =KbuffsBaseAddress
LDR a2, =AreaFlags_Kbuffs
LDR a3, =(KbuffsSize + &FFF) :AND: &FFFFF000 ;(round to 4k)
BL Init_MapInRAM
BL Init_MapInRAM_Clear
[ HiProcVecs
; Map in DebuggerSpace
LDR a1, =DebuggerSpace
LDR a2, =AreaFlags_DebuggerSpace
LDR a3, =(DebuggerSpace_Size + &FFF) :AND: &FFFFF000
BL Init_MapInRAM
BL Init_MapInRAM_Clear
]
[ MinorL2PThack
......@@ -1348,14 +1337,6 @@ ROMDecompWSAddr * 4<<20
BL CountPageTablePages
[ {FALSE}
MOV a1, #InitIRQWs
MOV a2, #0
MOV a3, #0
STMIA a1!, {a2,a3}
STMIA a1!, {a2,a3}
]
B Continue_after_HALInit
LTORG
......@@ -1607,6 +1588,16 @@ Init_MapInRAM ROUT
MOV a1, v8
Pull "v4-v8,pc"
Init_MapInRAM_Clear ROUT ; same as Init_MapInRAM but also
Push "a1,a3,v5,lr" ; clears the mapped in result
BL Init_MapInRAM
MOV v5, a1
Pull "a1,a3"
MOV a2, #0
BL memset
MOV a1, v5
Pull "v5,pc"
; Allocate and map a physically contigous chunk of some DMAable RAM.
;
; On entry:
......@@ -1636,7 +1627,7 @@ Init_MapInRAM_DMA ROUT
MOV a2, a1
MOV a1, v5
BL Init_MapIn ; map it in
; DMA regions won't get cleared by ClearPhysRam, so do it manually
; DMA regions won't get cleared by ClearWkspRam, so do it manually
; Could potentially skip this if the HAL says RAM is already clear, but
; for now do it anyway (especially since startup flags haven't been set
; when we're first called)
......@@ -1925,28 +1916,22 @@ Init_PageTablesChanged
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ClearPhysRAM - Routine to clear "all" memory
;
; While this routine is running, keyboard IRQs may happen. For this reason
; it avoids the base of logical RAM (hardware IRQ vector and workspace).
; ClearWkspRAM - Routine to clear "all" workspace
;
; We also have to avoid anything between InitUsedStart and InitUsedEnd - i.e.
; We have to avoid anything between InitUsedStart and InitUsedEnd - i.e.
; the page tables, HAL workspace, etc.
;
; Note that zero page workspace isn't included in InitUsedStart/InitUsedEnd.
; Sensitive areas of it (e.g. PhysRamTable, IRQ vector) are skipped via the
; help of RamSkipTable
; We don't have to worry about trampling on the ROM image as it's already been
; excluded from PhysRamTable. We also don't have to worry about skipping the
; special DMA block, because at this point in time that won't be listed in
; PhysRamTable either.
;
; The bulk of RAM is cleared during the keyboard scan (ClearFreePoolSection).
;
; out: r4-r11, r13 preserved
;
ClearPhysRAM ROUT
ClearWkspRAM ROUT
MSR CPSR_c, #F32_bit+FIQ32_mode ; get some extra registers
MOV r8, #0
MOV r9, #0
......@@ -1957,11 +1942,10 @@ ClearPhysRAM ROUT
MOV r14, #0
MSR CPSR_c, #F32_bit+SVC32_mode
;now let us do the clear
LDR r0,=ZeroPage+InitClearRamWs ;we can preserve r4-r11,lr in one of the skipped regions
STMIA r0,{r4-r11,lr}
DebugTX "ClearPhysRAM"
DebugTX "ClearWkspRAM"
; Start off by clearing zero page + scratch space, as these:
; (a) are already mapped in and
......@@ -1991,112 +1975,16 @@ ClearPhysRAM ROUT
STMNEIA r0!, {r8-r11}
BNE %BT30
; Now walk PhysRamTable and clear everything else, except for the stuff
; between InitUsedStart and InitUsedEnd.
;
; To skip these areas properly, we convert their addresses to physical
; page numbers. This is because PhysRamTable isn't guaranteed to be in
; ascending address order.
MSR CPSR_c, #F32_bit+SVC32_mode
LDR r9, =ZeroPage
LDR r5, [r9, #InitUsedStart]
SUB r0, r5, #DRAMOffset_L1PT ; Scratch space + zero page are already cleared, so add them to InitUsedStart..InitUsedEnd
BL PhysAddrToPageNo
; If the DMA region was taken from the first RAM block, we won't be able to look up the page number
; Instead, let's use the first DRAM page for InitUsedStart - as this will correspond to the first page that isn't hidden inside the DMA region
CMP r0, #-1
LDREQ r0, [r9, #DRAMPhysAddrA]
BLEQ PhysAddrToPageNo
MOV r5, r0
LDR r0, [r9, #InitUsedEnd]
BL PhysAddrToPageNo
SUB r6, r0, #1
ADD r9, r9, #PhysRamTable
MOV r4, #0 ; current page no
LDMIA r9!, {r10, r11}
MOV r11, r11, LSR #12 ; get rid of flags
50
; Map in this area, cacheable + bufferable to ensure burst writes are
; performed. We're careful to not partially overwrite any pages which
; are being used, so this shouldn't cause any issues due to being
; cachable + potentially doubly mapped.
MOV r0, #0
MOV r1, r10
MOV r2, #0
BL RISCOS_AccessPhysicalAddressUnchecked
; Inner loop will process one page at a time to keep things simple
MOV r3, r11
MSR CPSR_c, #F32_bit+FIQ32_mode ; switch to our bank o'zeros
MOV r2, #0
60
CMP r4, r5
CMPHS r6, r4
ADD r1, r0, #4096
BHS %FT80
; Clear this page
70
STMIA r0!, {r2,r8-r14}
STMIA r0!, {r2,r8-r14}
TEQ r0, r1
BNE %BT70
80
MOV r0, r1 ; increment log addr
ADD r4, r4, #1 ; increment page no
SUBS r3, r3, #1 ; decrement length
MOVNES r1, r0, LSL #12 ; check for MB limit
BNE %BT60
MSR CPSR_c, #F32_bit+SVC32_mode
; Make page uncacheable so the following is safe
Push "r0-r3"
MOV r0, #L1_B
MOV r1, r10
MOV r2, #0
BL RISCOS_AccessPhysicalAddress
Pull "r0-r3"
; Clean & invalidate the cache before the 1MB window closes
[ CacheCleanerHack
; StrongARM requires special clean code, because we haven't mapped in
; DCacheCleanAddress yet. Cheat and only perform a clean, not full
; clean + invalidate (should be safe as we've only been writing)
ARM_read_ID r2
AND r2, r2, #&F000
CMP r2, #&A000
BNE %FT90
85
SUB r0, r0, #32 ; rewind 1 cache line
ARMA_clean_DCentry r0
MOVS r1, r0, LSL #12 ; start of the MB?
BNE %BT85
B %FT91
90
]
ARMop Cache_CleanInvalidateAll
91
ADD r10, r10, r11, LSL #12 ; r10+(r11-r3) = next MB
MOVS r11, r3 ; next block needed? also resets r11 ready for next pass
SUBNE r10, r10, r3, LSL #12
LDMEQIA r9!, {r10, r11} ; grab next block if necessary
MOVEQS r11, r11, LSR #12 ; anything left to do?
BNE %BT50
MOV a1, #L1_Fault
BL RISCOS_ReleasePhysicalAddress ; reset to default
LDR r0, =ZeroPage+InitClearRamWs
LDMIA r0, {r4-r11,r14} ;restore
CPR_skipped
[ {FALSE} ; NewReset sets this later
LDR r0, =ZeroPage+OsbyteVars + :INDEX: LastBREAK
MOV r1, #&80
STRB r1, [r0] ; flag the fact that RAM cleared
]
MSR CPSR_c, #F32_bit + UND32_mode ; retrieve the MMU control register
LDR r0, =ZeroPage ; soft copy
......@@ -2120,12 +2008,169 @@ CPR_skipped
& -1
MEND
RamSkipTable
MakeSkipTable ZeroPage, InitWsEnd
MakeSkipTable ZeroPage+SkippedTables, SkippedTablesEnd-SkippedTables
EndSkipTables
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ClearFreePoolSection - Routine to clear a section of the free pool
;
; During keyboard scanning we soak up slack time clearing the bulk of RAM
; by picking a section of the free pool, mapping it in, clearing & flushing.
;
; In: r0 = CAM entry to continue from
; Out: r0 = updated
;
ClearFreePoolSection ROUT
Push "r1-r3, lr"
LDR r1, =ZeroPage
LDR r1, [r1, #MaxCamEntry]
LDR r2, =ZeroPage+FreePoolDANode
CMP r0, r1
BHI %FT30
LDR r3, =CAM
ADD r1, r3, r1, LSL #CAM_EntrySizeLog2 ; top entry (inc)
ADD r3, r3, r0, LSL #CAM_EntrySizeLog2 ; starting entry
10
LDR r14, [r3, #CAM_PageFlags]
TST r14, #DynAreaFlags_PMP
BEQ %FT20
LDR r14, [r3, #CAM_PMP]
TEQ r14, r2
BEQ %FT40
20
ADD r3, r3, #CAM_EntrySize ; next
CMP r3, r1
BLS %BT10
30
MOV r0, #-1
Pull "r1-r3, pc"
40
Push "r0-r12"
; This is a PMP entry in the free pool
LDR r14, [r3, #CAM_PMPIndex] ; list index
LDR r9, [r2, #DANode_PMP] ; PMP list base
LDR r3, [r9, r14, LSL #2] ; ppn
BL ppn_to_physical ; => r5 = PA
[ MEMM_Type = "ARM600"
; Map in this section, cacheable + bufferable to ensure burst writes
; are performed (StrongARM will only perform burst writes to CB areas)
MOV a1, #OSAP_None
|
; Map in this section with default NCB cache policy. Making it cacheable
; is liable to slow things down significantly on some platforms (e.g.
; PL310 L2 cache)
LDR a1, =OSAP_None + DynAreaFlags_NotCacheable
]
MOV a2, r5
MOV a3, #0
BL RISCOS_AccessPhysicalAddressUnchecked
MOV r4, #0 ; clear to this value
MOV r6, r4
MOV r7, r4
MOV r8, r4
MOV r12, r4
45
MOV r9, r4
MOV r10, r4
MOV r11, r4
; Fill that page
ADD r2, r0, #4096
50
STMIA r0!, {r4,r6-r12}
STMIA r0!, {r4,r6-r12}
TEQ r0, r2
BNE %BT50
; Step the CAM until there are no more pages in that section
LDR r1, [sp, #1*4]
LDR r2, [sp, #2*4]
LDR r11, [sp, #3*4]
B %FT65
60
LDR r14, [r11, #CAM_PageFlags]
TST r14, #DynAreaFlags_PMP
BEQ %FT65
LDR r14, [r11, #CAM_PMP]
TEQ r14, r2
BEQ %FT70
65
ADD r11, r11, #CAM_EntrySize ; next
CMP r11, r1
BLS %BT60
MOV r14, #-1 ; CAM top, no more
B %FT80
70
MOV r10, r5 ; previous PA
; Next PMP entry in the free pool
LDR r14, [r11, #CAM_PMPIndex] ; list index
LDR r9, [r2, #DANode_PMP] ; PMP list base
LDR r3, [r9, r14, LSL #2] ; ppn
BL ppn_to_physical ; => r5 = PA
MOV r14, r10, LSR #20
TEQ r14, r5, LSR #20 ; same MB as previous?
LDRNE r14, =CAM
SUBNE r14, r11, r14
MOVNE r14, r14, LSR #CAM_EntrySizeLog2 ; no, so compute continuation point
LDREQ r0, =PhysicalAccess
MOVEQ r14, r5, LSL #12
ORREQ r0, r0, r14, LSR #12
STREQ r11, [sp, #3*4]
BEQ %BT45 ; yes, so clear it
80
STR r14, [sp, #0*4] ; return value for continuation
[ MEMM_Type = "ARM600" ; VMSAv6 maps as non-cacheable, so no flush required
; Make page uncacheable so the following is safe
MOV r4, r0
MOV r0, #L1_B
MOV r1, r10
MOV r2, #0
BL RISCOS_AccessPhysicalAddress
MOV r0, r4
; Clean & invalidate the cache before the 1MB window closes
[ CacheCleanerHack
; StrongARM requires special clean code, because we haven't mapped in
; DCacheCleanAddress yet. Cheat and only perform a clean, not full
; clean + invalidate (should be safe as we've only been writing)
ARM_read_ID r2
AND r2, r2, #&F000
CMP r2, #&A000
BNE %FT90
85
SUB r0, r0, #32 ; rewind 1 cache line
ARMA_clean_DCentry r0
MOVS r1, r0, LSL #12 ; start of the MB?
BNE %BT85
B %FT91
90
]
ARMop Cache_CleanInvalidateAll
]
91
MOV a1, #L1_Fault
BL RISCOS_ReleasePhysicalAddress ; reset to default
Pull "r0-r12"
Pull "r1-r3, pc"
InitProcVecs
BKPT &C000 ; Reset
......@@ -2659,7 +2704,8 @@ Reset_IRQ_Handler
ORR a3, a2, #SVC32_mode
MSR CPSR_c, a3
Push "a1-a2,lr"
; If it's not an IIC interrupt, pass it on to the keyboard scan code
; If it's not an IIC interrupt, mute it
LDR v2, =ZeroPage
AddressHAL v2
CallHAL HAL_IRQSource
......@@ -2678,14 +2724,9 @@ Reset_IRQ_Handler
ADD v1, v1, #IICBus_Size
CMP ip, #IICBus_Count
BNE %BT10
LDRB a2, [v2, #InitIRQWs+KbdScanActive]
TEQ a2, #0
CallHAL HAL_KbdScanInterrupt,NE
; Keyboard scan code will have return -1 if it handled the IRQ
; If it didn't handle it, or keyboard scanning is inactive, something
; bad has happened
CMP a1, #-1
CallHAL HAL_IRQDisable,NE ; Stop the rogue device from killing us completely
CallHAL HAL_IRQDisable ; Stop the rogue device from killing us completely
Reset_IRQ_Exit
MyCLREX a1, a2
Pull "a1-a2,lr"
......@@ -2750,6 +2791,7 @@ hextab DCB "0123456789abcdef"
;HALDebugHexTX2
; stmfd r13!, {r0-r3,sb,ip,lr}
; AddressHAL
; mov r0,r0,lsl #16
; b jbdt2
;HALDebugHexTX4
; stmfd r13!, {r0-r3,sb,ip,lr}
......
......@@ -94,29 +94,134 @@ UnplugCMOSTableEnd ; used for backwards indexing
ALIGN
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ModuleInitForKbdScan - Start subset of ROM modules for keyboard scan
;
; in: r0 -> comma seperated list of ROM module names
;
; out: All registers preserved
;
ModuleInit Entry "r0-r12" ; call here on system startup
ModuleInitForKbdScan Entry "r0-r12"
MOV r0, #HeapReason_Init ; first initialise the heap
MOV r1, #RMAAddress
LDR r3, [r1, #:INDEX: hpdend] ; saved for us during init.
SWI XOS_Heap
; first initialise the podule manager - this must be the second module (ie the 1st after UtilityModule)
ASSERT ROMModule_Link = 0
ADRL r6, SysModules_Info+4
LDR r9, =ZeroPage+ROMModuleChain ; pointer to 'previous' node
MOV r8, #0 ; initial head ptr is zero
STR r8, [r9] ; set up null list
LDR r0, [sp, #0*4]
CMP r0, #-1 ; no list?
BNE %FT10
; just init the podule manager - this must be the second module (ie the 1st after UtilityModule)
LDR r1, [r6, #-4]
ADD r1, r6, r1
LDR r14, [r1, #-4]
TEQ r14, #0
MOVNE r0, #ModHandReason_AddArea
SWINE XOS_Module
EXIT
; now for each module in the main ROM needed for KbdScan, create a node for it
10
MOV r3, #-1 ; podule -1 is main ROM
MOV r10, #0 ; chunk number 0 to start
20
LDR r7, [r6, #-4] ; get size of this module
TEQ r7, #0 ; if zero
BEQ %FT50 ; then no more main rom modules
LDR r4, [r6, #Module_TitleStr] ; r4 = offset to module name
ADD r4, r6, r4 ; r4 -> module name
LDR r5, [r6, #Module_HelpStr] ; r5 = help offset
TEQ r5, #0 ; if no help string
ADDEQ r5, r6, #Module_HelpStr ; then use help offset as string (null string)
ADDNE r5, r6, r5 ; otherwise point to help string
CMP r10, #FirstUnpluggableModule
BCC %FT30 ; unconditional since not unpluggable anyway
LDR r11, [sp, #0*4]
BL CompareTitleWithCSV
BNE %FT40 ; if your name's not on the list you can't come in
30
ADR r11, UnplugCMOSTable
SUBS r14, r10, #FirstUnpluggableModule ; subtract number of first module that has an unplug bit
MOVCS r1, r14, LSR #3 ; get byte number
ANDCS r14, r14, #7 ; get bit number
ADDCS r14, r14, #16 ; bit mask stored in bits 16 onwards
RSBCSS r1, r1, #(UnplugCMOSTableEnd-UnplugCMOSTable) ; invert table offset, and check in range
LDRCSB r11, [r11, r1] ; load table value if in range
MOVCS r12, #1
ORRCS r11, r11, r12, LSL r14 ; merge with bit mask
MOVCC r11, #0 ; otherwise zero
BL AddROMModuleNode
BVS %FT50 ; if failed then can't add any more ROMs!
40
MOV r9, r2 ; this node is now previous one
ADD r6, r6, r7 ; go on to next module
ADD r10, r10, #1 ; chunk number +=1
B %BT20
; now start them
50
LDR r12, =ZeroPage+ROMModuleChain
LDR r12, [r12]
60
TEQ r12, #0 ; if no more modules
BEQ %FT90 ; then skip
MOV r11, r12 ; start with current one
BL InitialiseROMModuleAtInit
LDR r12, [r12, #ROMModule_Link]
B %BT60
90
[ DebugROMInit
SWI XOS_WriteS
= "mod init (kbdscan) done",0
SWI XOS_NewLine
]
MOV r1, #RMASizeCMOS
MOV r0, #ReadCMOS