Commit 3cd8d7bb authored by Kevin Bracey's avatar Kevin Bracey
Browse files

More HAL work. IOMD HAL work in progress. Lots of my own little build scripts. Don't touch this.

Version 5.35, 4.79.2.2. Tagged as 'Kernel-5_35-4_79_2_2'
parent 49836a59
0 STATE (X) 0->X (8)
1 nWAIT 1->9
2 BRST 2->X (2)
3 nFIQ 3->X (13)
4 nIRQ 4->X (12)
5 nc (MAS[0]) 5->6
6 nMREQ 1 6->1
7 SEQ (X) 7->0
8 nRW 8->3
9 nBW (MAS[1]) 9->7
10 LOCK 10->X (10)
11 nTRANS (X) 11->5
12 nOPC (X) 12->4
13 nc 13->11 (DMA low)
14 ABE
15 DBE
Master clock: (MCLK down)
0 SEQ 0->7
1 nMREQ 1->6
2 nEXEC
Slave clock: (MCLK up)
3 nRW 16->8
4 nOPC 17->12
5 nTRANS 18->11
6 MAS[0] 19->5
7 MAS[1] 20->9
8 DBGACK
9 nWAIT 22->1
10 ABORT
11 DMA
12 BIGEND
13 CS0
14 CS1
15 CS2
16 CS3
17 CS4
18 CS5
19 CS6
20 CS7
0
0->X
\ No newline at end of file
......@@ -242,6 +242,9 @@ void RISCOS_Start(unsigned int flags, int *riscos_header, int *hal_entry_table,
flags
bit 0: power on reset
bit 1: CMOS reset inhibited (eg protection link on Risc PC)
bit 2: perform a CMOS reset (if bit 1 clear and bit 0 set - eg front panel
button held down on an NC)
On entry:
SVC32 mode
......
Initialisation
==============
HAL_Init
HAL_Init(unsigned int *riscos_header)
Will be called after the MMU is turned on, before any other entries points.
The HAL workspace will be filled with zeroes.
Interrupts
......@@ -29,11 +32,239 @@ HAL_GetHighestIRQ
Timers
======
The HAL must supply at least one timer capable of generating periodic interrupts.
Each timer should generate a separate logical interrupt.
The HAL must supply at least one timer capable of generating periodic
interrupts. Each timer should generate a separate logical interrupt, and the
interrupt must be latched. The timers must either be variable rate (period is
a multiple of a basic granularity), or be fixed rate (period = 1*granularity).
Optionally, the timer should be capable of reporting the time until the
next interrupt, in units of the granularity.
int HAL_Timers(void)
Returns number of timers. Timers are numbered from 0 upwards. Timer 0
must exist.
int HAL_TimerDevice(int timer)
Returns device number of timer n
unsigned int HAL_TimerGranularity(int timer)
Returns basic granularity of timer n in ticks per second.
unsigned int HAL_TimerMaxPeriod(int timer)
Returns maximum period of the timer, in units of Granularity. Will be 1
for a fixed rate timer.
void HAL_TimerSetPeriod(int timer, unsigned int period)
Sets period of timer n. If period > 0, the timer will generate interrupts every
(period / granularity) seconds. If period = 0, the timer may be stopped.
This may not be possible on some hardware, so the corresponding interrupt
should be masked in addition to calling this function with period 0.
If period > maxperiod, behaviour is undefined.
unsigned int HAL_TimerPeriod(int timer)
Reads period of timer n. This should be the actual period in use by the
hardware, so if for example period 0 was requested and impossible, the
actual current period should be reported.
unsigned int HAL_TimerReadCountdown(int timer)
Returns the time until the next interrupt in units of granularity, rounded down.
If not available, 0 is returned.
Counter
=======
The HAL must supply a counter that varies rapidly, appropriate for use for
sub-millisecond timing. On many systems, this counter will form part of
timer 0 - as such it is not required to operate when timer 0 is not running.
On other systems, the periodic timers may have no readable latch, and a
separate unit will be required.
The counter should count down from (period-1) to 0 continuously.
unsigned int HAL_CounterRate(void)
Returns the rate of the counter in ticks per second. Typically will
equal HAL_TimerGranularity(0).
unsigned int HAL_CounterPeriod(void)
Returns the period of the counter, in ticks. Typically will equal
HAL_TimerPeriod(0).
unsigned int HAL_CounterRead(void)
Reads the current counter value. Typically will equal
HAL_TimerReadCountdown(0).
unsigned void HAL_CounterDelay(unsigned int microseconds)
Delay for at least the specified number of microseconds.
Non-volatile memory
===================
The HAL should provide at least 240 bytes of non-volatile memory. If no
non-volatile memory is available, the HAL may provide fake NVRAM contents
suitable for RISC OS - however, it is preferable that the HAL just state that
NVRAM is not available, and RISC OS will act as though a CMOS reset has been
performed every reset.
NVRAM is typically implemented as an IIC device, so the calls are permitted
to be slow, and to enable interrupts. The HAL is not expected to cache
contents.
If the HAL has no particular knowledge of NVMemory, then it may
just say that "NVMemory is on IIC", and the OS will probe for CMOS/EEPROM
devices on the IIC bus.
unsigned int HAL_NVMemoryType(void)
Returns a flags word describing the NVMemory
bits 0-7: 0 => no NVMemory available
1 => NVMemory may be available on the IIC bus
2 => NVMemory is available on the IIC bus, and the
device characteristics are known
3 => the HAL provides NVMemory access calls.
bit 8: NVMemory has a protected region at the end
bit 9: Protected region is software deprotectable
bit 10: Memory locations 0-15 are readable
bit 11: Memory locations 0-15 are writeable
If bits 0-7 are 0 or 1 no other NVMemory calls need be available,
and bits 8-31 should be zero.
If bits 0-7 are 2, Size, ProtectedSize, Protection and IICAddress calls must
be available.
If bits 0-7 are 3, all calls except IICAddress must be available.
unsigned int HAL_NVMemorySize(void)
Returns the number of bytes of non-volatile memory available. Bytes 0-15
should be included in the count, so for example a Philips PCF8583
CMOS/RTC device (as used in the Archimedes and Risc PC) would be described
as a 256-byte device, with locations 0-15 not readable. More complex
arrangements would have to be abstracted out by the HAL providing its own
NVMemory access calls.
This is to suit the current RISC OS Kernel, which does not use bytes 0-15.
unsigned int HAL_NVMemoryProtectedSize(void)
Returns the number of bytes of NVMemory that are protected. These should
be at the top of the address space. The OS will not attempt to write
to those locations without first requesting deprotection (if available).
Returns 0 if bit 8 of the flags is clear.
void HAL_NVMemoryProtection(bool)
Enables (if true) or disables if (false) the protection of the software
protectable region. Does nothing if bits 8 and 9 not both set.
unsigned int HAL_NVMemoryIICAddress(void)
Returns a word describing the addressing scheme of the NVRAM.
bits 0-7: IIC address
int HAL_NVMemoryRead(unsigned int addr, void *buffer, unsigned int n)
Reads n bytes of memory from address addr onwards into the buffer supplied.
Returns the number of bytes successfully read. Under all normal circumstances
the return value will be n - if it is not, a hardware failure is implied.
Behaviour is undefined if the address range specified is outside the NVMemory,
or inside bytes 0-15, if declared unavailable.
int HAL_NVMemoryWrite(unsigned int addr, void *buffer, unsigned int n)
Write n bytes of memory into address addr onwards from the buffer supplied.
Returns the number of bytes successfully written. Under all normal circumstances
the return value will be n - if it is not, a hardware failure is implied.
Behaviour is undefined if the address range specified is outside the NVMemory.
Writes inside the a protected region should be ignored.
I²C bus
=======
Many hardware designs have an I²C bus. Often, it is used only to place non-
volatile memory on, but in other systems TV tuners, TV modulators,
microcontrollers, and arbitrary expansion cards may be fitted.
Low-level and high level APIs are defined. An arbitrary number of buses are
supported, and each can be controlled by either the low or high level API.
The OS should normally only use one fixed API on each bus - mixing APIs may
not have good results.
The low-level API requires the OS to control the two lines of the bus
directly. The high-level API currently covers version 2.1 of the I²C
protocol, and allows high-level transactions to be performed.
It is expected that a HAL will always provide the low-level API on each
bus, where possible in hardware. Using this, the OS can provide Fast mode
single or multi-master operation. The HAL may wish to provide the high-level API
where a dedicated I²C port with hardware assistance is available; this will
further permit High-speed and slave operation.
As it is possible that some HAL APIs (eg NVMemory), although abstracted at
this API layer, are still actually an I²C device, a matching set of high-level
I²C calls are provided in the OS. These give the HAL access to the OS I²C engine,
which will make low-level HAL calls. This saves the HAL from implementing the
full I²C protocol. To illustrate this diagramatically:
+----------+ NVMem_Read +------------+ NVMemoryRead +------------+
| | ---------> | | ------------> | |
| App | | OS | IICTransmit | HAL |
| | | | <------------ | |
| | | | IICSetLines | |
| | | | ------------> | |
+----------+ +------------+ +------------+
int HAL_IICBuses(void)
Returns the number of IIC buses on the system.
unsigned int HAL_IICType(int bus)
Returns a flag word describing the specified IIC bus.
bit 0: Bus supplies the low-level API
bit 1: Bus supplies the high-level API
bit 2: High-level API supports multi-master operation
bit 3: High-level API supports slave operation
bit 16: Bus supports Fast (400kbps) operation
bit 17: Bus supports High-speed (3.4Mbps) operation
bits 20-31: Version number of I²C supported by high-level API, * 100.
Low level API
-------------
The low-level calls should be instantaneous. Interrupt status may not be altered.
The following structure is used:
typedef struct { int SDA, SCL } IICLines;
Note the "__value_in_regs" keyword, which signifies that the binary ABI expects
SDA and SCL to be returned in registers a1 and a2.
__value_in_regs IICLines HAL_IICSetLines(int bus, IICLines lines)
Sets the SDA and SCL lines on the specified bus. A 0 value represents
logic LOW, 1 logic HIGH. The function then reads back and returns
the values present on the bus, to permit arbitration.
__value_in_regs IICLines HAL_IICReadLines(int bus);
Reads the state of the IIC lines on the specified bus, without changing
their state.
High level API
--------------
To be defined.
HAL_Timer
HAL_TimerEnable
HAL_TimerRead
HAL_TimerSetRate
HAL_TimerDisable
G F D B 9 7 5 3 1 Gnd?
G J E C A 8 6 4 2 0
Aux
X
X
G 1 3 5 7 9 B D F x
0 2 4 6 8 A C E J x
FIQ
aux
14 pfiq
12 preq
15 pirq
13 rclk
Cont
3 Fiq
14 abe
9 nbw
15 dBE
1 wait
4 irq
8 nrw
2 brst
10 lock
clk mclk
0 state? (lk1)
7 seq? lk2
12 nopc? lk3
11 ntrans lk4
6 mreq
5 n/c
13 n/c
CLK to AUX link connects MCLK to AUX clock
......@@ -62,6 +62,8 @@ EXPORTS = ${EXP_HDR}.EnvNumbers \
${EXP_HDR}.RISCOS \
${EXP_HDR}.Variables \
${EXP_HDR}.VduExt \
${EXP_HDR}.HALEntries \
${EXP_HDR}.OSEntries \
${C_EXP_HDR}.RISCOS
#
......@@ -117,7 +119,7 @@ ${AIFDBG}: ${OBJECTS}
${LD} -aif -bin -d -o ${AIFDBG} ${OBJECTS}
${GPADBG}: ${AIFDBG}
ToGPA ${AIFDBG} ${GPADBG}
ToGPA -s ${AIFDBG} ${GPADBG}
s.TMOSHelp: ${TOKENS} HelpStrs
${TOKENISE} ${TOKENS} HelpStrs $@
......@@ -145,6 +147,12 @@ ${EXP_HDR}.VduExt: hdr.VduExt
${EXP_HDR}.Variables: hdr.Variables
${CP} hdr.Variables $@ ${CPFLAGS}
${EXP_HDR}.HALEntries: hdr.HALEntries
${CP} hdr.HALEntries $@ ${CPFLAGS}
${EXP_HDR}.OSEntries: hdr.OSEntries
${CP} hdr.OSEntries $@ ${CPFLAGS}
${C_EXP_HDR}.RISCOS: hdr.RISCOS
${MKDIR} ${C_EXP_HDR}
perl Build:Hdr2H hdr.RISCOS $@
......
......@@ -8,11 +8,13 @@
GBLS Module_FullVersion
GBLS Module_ApplicationDate2
GBLS Module_ApplicationDate4
GBLS Module_HelpVersion
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.1"
Module_Date SETS "15 Sep 2000"
Module_ApplicationDate2 SETS "15-Sep-00"
Module_ApplicationDate4 SETS "15-Sep-2000"
Module_FullVersion SETS "5.35 (4.79.2.1)"
Module_MinorVersion SETS "4.79.2.2"
Module_Date SETS "02 Oct 2000"
Module_ApplicationDate2 SETS "02-Oct-00"
Module_ApplicationDate4 SETS "02-Oct-2000"
Module_FullVersion SETS "5.35 (4.79.2.2)"
Module_HelpVersion SETS "5.35 (02 Oct 2000) 4.79.2.2"
END
......@@ -4,15 +4,16 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.1
#define Module_Date_CMHG 15 Sep 2000
#define Module_MinorVersion_CMHG 4.79.2.2
#define Module_Date_CMHG 02 Oct 2000
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.1"
#define Module_Date "15 Sep 2000"
#define Module_MinorVersion "4.79.2.2"
#define Module_Date "02 Oct 2000"
#define Module_ApplicationDate2 "15-Sep-00"
#define Module_ApplicationDate4 "15-Sep-2000"
#define Module_ApplicationDate2 "02-Oct-00"
#define Module_ApplicationDate4 "02-Oct-2000"
#define Module_FullVersion "5.35 (4.79.2.1)"
#define Module_FullVersion "5.35 (4.79.2.2)"
#define Module_HelpVersion "5.35 (02 Oct 2000) (4.79.2.2)"
; Copyright 2000 Pace Micro Technology plc
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; The layout of the HAL descriptor
^ 0
HALDesc_Flags # 4
HALDesc_Start # 4
HALDesc_Size # 4
HALDesc_Entries # 4
HALDesc_NumEntries # 4
HALDesc_Workspace # 4
HALDesc_size # 4
; Entries to the HAL from the OS
^ 0
EntryNo_HAL_Init # 1
EntryNo_HAL_Timers # 1
EntryNo_HAL_TimerDevice # 1
EntryNo_HAL_TimerGranularity # 1
EntryNo_HAL_TimerMaxPeriod # 1
EntryNo_HAL_TimerSetPeriod # 1
EntryNo_HAL_TimerPeriod # 1
EntryNo_HAL_TimerReadCountdown # 1
EntryNo_HAL_CounterRate # 1
EntryNo_HAL_CounterPeriod # 1
EntryNo_HAL_CounterRead # 1
EntryNo_HAL_CounterDelay # 1
EntryNo_HAL_NVMemoryType # 1
EntryNo_HAL_NVMemorySize # 1
EntryNo_HAL_NVMemoryProtectedSize # 1
EntryNo_HAL_NVMemoryProtection # 1
EntryNo_HAL_NVMemoryIICAddress # 1
EntryNo_HAL_NVMemoryRead # 1
EntryNo_HAL_NVMemoryWrite # 1
EntryNo_HAL_IICBuses # 1
EntryNo_HAL_IICType # 1
EntryNo_HAL_IICSetLines # 1
EntryNo_HAL_IICReadLines # 1
; Various flags and constants
; IIC
IICFlag_LowLevel * 1:SHL:0
IICFlag_HighLevel * 1:SHL:1
IICFlag_Fast * 1:SHL:16
END
......@@ -233,6 +233,9 @@ ZeroPage * &00000000
[ HAL
; Sort out 26/32 bit versions
SVCStackSize * 32*1024
IRQStackSize * 8*1024
ABTStackSize * 8*1024
UNDStackSize * 8*1024
RMAAddress * &80000000 ; temporary - run time allocate
ScreenEndAdr * &A0000000 ; temporary - run time allocate
......@@ -240,10 +243,12 @@ ScreenMaxSize * 480*1024
RMAMaxSize * -1
IO * &F0000000
IO * &FA000000 ; works downwards
HALWorkspace * &FA000000
IRQStackAddress * &FA100000
SVCStackAddress * &FA200000
ABTStackAddress * &FA300000
UNDStackAddress * &FA400000
PhysicalAccess * &FAE00000
CursorChunkAddress * &FAFF0000
L2PT * &FB000000
......@@ -252,6 +257,10 @@ SysHeapChunkAddress * &FB404000
SysHeapAddress * SysHeapChunkAddress
SysHeapMaxSize * &FB800000 - SysHeapAddress
CAM * &FB800000
IRQSTK * IRQStackAddress + IRQStackSize
ABTSTK * ABTStackAddress + ABTStackSize
UNDSTK * UNDStackAddress + UNDStackSize
|
AplWorkMaxSize * &01C00000 ; 28M
RMAAddress * &02100000
......@@ -921,16 +930,22 @@ VDWSSize # 0
; *****************************************************************************
; Real workspace definition
; locations used during reset only
^ ZeroPage+&20
InitKbdHandler # 4
InitKbdWs # 16
InitUsedStart # 4
InitUsedEnd # 4
InitClearRamWs # 5*4
; locations used during reset only. Not cleared by ClearPhysRAM, but
; cleared later (just before DEFHAN).
^ ZeroPage+&80 ; steer clear of FIQ code
InitKbdHandler # 4 ; pointer to IRQ handler (LDR PC'ed from IRQ HW vector)
InitKbdWs # 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 ; can't remember
InitHALFlags # 4 ; flags passed into OS_Start
InitClearRamWs # 10*4
AlignSpace 32 ; because we clear 32 at a time
InitWsEnd # 0
ASSERT InitKbdHandler >= EndFiq - MOSROMVecs
; Basic kernel space - defined locations for external modules
^ ZeroPage+&100
......@@ -1079,9 +1094,11 @@ LCD_Inverted # 1 ; Added to support LCD palette inversion. 0=norm
]
[ HAL
AlignSpace
HAL_EntryTable # 4
HAL_Descriptor # 4
HAL_Workspace # 4
HAL_WsSize # 4
ICache_Info # 0
ICache_Info # 4
ICache_NSets # 4
ICache_Size # 4
ICache_LineLen # 1
......@@ -1097,28 +1114,21 @@ DCache_LineLen # 1
DCache_Associativity # 1
]
IOSystemType # 1 ; 0 => old I/O subsystem, 1 => IOEB+82C710 system, 2..255 => ?
[ StrongARM
ProcessorType # 1 ; Processor type (handles 600 series onwards)
ProcessorFlags # 1 ; Processor flags (IMB, Arch4 etc)
AlignSpace
ProcessorFlags # 4 ; Processor flags (IMB, Arch4 etc)
! 0, "ProcessorType at ":CC::STR:(ProcessorType)
! 0, "ProcessorFlags at ":CC::STR:(ProcessorFlags)
]
IOSystemType # 1 ; 0 => old I/O subsystem, 1 => IOEB+82C710 system, 2..255 => ?
AlignSpace 32 ; skipped bit must end on 32-byte boundary (due to speedup)
SkippedTablesEnd # 0
AppSpaceDANode # DANode_NodeSize ; Dummy area node for application space (not on list)
FreePoolDANode # DANode_NodeSize ; Area node for free pool
SysHeapDANode # DANode_NodeSize ; Area node for system heap
CDASemaphore # 4 ; Semaphore for OS_ChangeDynamicArea - non-zero => routine threaded
MMUControlSoftCopy # 4 ; Soft copy of ARM600/700 control register
AplWorkSize * AppSpaceDANode + DANode_Size
ProcVec_Start # 0 ; Start of processor vector table
ProcVec_Branch0 # 4 ; Branch through zero
ProcVec_UndInst # 4 ; Undefined instruction vector
......@@ -1132,6 +1142,8 @@ ProcVec_End # 0
ProcVecPreVeneersSize * 4*4 ; Space for preveneers for loading handler addresses from 0 page.
ProcVecPreVeneers # ProcVecPreVeneersSize
! 0, "Free space before DebuggerSpace = ":CC::STR:(&300-@)
ASSERT @ <= &300
# (&300-@)
Export_DebuggerSpace # 16*8 ; Debugger module needs some zero page
......@@ -1151,6 +1163,14 @@ NVRamWriteSize # 1 ; Size of writable region (256byte units
AlignSpace
AppSpaceDANode # DANode_NodeSize ; Dummy area node for application space (not on list)
FreePoolDANode # DANode_NodeSize ; Area node for free pool
SysHeapDANode # DANode_NodeSize ; Area node for system heap
CDASemaphore # 4 ; Semaphore for OS_ChangeDynamicArea - non-zero => routine threaded
MMUControlSoftCopy # 4 ; Soft copy of ARM600/700 control register
AplWorkSize * AppSpaceDANode + DANode_Size
EnvString # 256
! 0, "Free space after EnvString = ":CC::STR:(&500-@)
......@@ -1175,7 +1195,7 @@ MaxCamEntry # 4 ; maximum index into the cam map, ie
RAMLIMIT # 4
# 4 ; dummy slot where AplWorkSize used to be
IOAllocPtr # 4
HiServ_ws # 4
HiServ # 4
......@@ -1653,10 +1673,12 @@ DefaultIRQ1V |#| DefIRQ1Vspace
[ @-7*4 :AND: 15 <> 0
|#| (@-7*4):AND:15
]
[ :LNOT: HAL32
IRQSTK # 0 ; Overflow will give abort
[ AssemblingArthur
! 0, "IRQ stack size ":CC::STR:(IRQSTK-CursorChunkAddress)
]
]
ASSERT @ > ( CursorChunkAddress + &1000 ) ; Check minimum stack
......
; Copyright 2000 Pace Micro Technology plc
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; Entries to the OS from the HAL
^ 0
OS_InitARM # 1
OS_AddRAM # 1
OS_Start # 1
OS_MapInIO # 1
; The layout of the OS header
^ 0
OSHdr_Magic # 4
OSHdr_Flags # 4
OSHdr_ImageSize # 4
OSHdr_Entries # 4
OSHdr_NumEntries # 4
OSHdr_size # 0
; Parameters/flag for various calls
OSStartFlag_POR * 1:SHL:0 ; Power-On Reset
OSStartFlag_NoCMOSReset * 1:SHL:1 ; CMOS reset inhibited (protection link etc)
OSStartFlag_CMOSReset * 1:SHL:2 ; CMOS reset (if POR and not inhibited)
END
......@@ -107,12 +107,14 @@ FixedAreasL2Size * 96*1024 ; amount of L2 to cover fixed are
UndStackSoftCamChunk * &01E00000
UndStackSize * 8*1024
CamEntriesForVicky * UndStackSoftCamChunk + UndStackSize
[ :LNOT: HAL
UNDSTK * CamEntriesForVicky ; points to end of stack
[ No26bitCode
AbtStack * &02000000
AbtStackSize * 8*1024
ABTSTK * AbtStack + AbtStackSize
]
]
PhysSpace * &80000000 ; Map of MEMC/IOMD physical space (64M/512M in size)
......@@ -135,6 +137,7 @@ arm600stuff_startofstuff
;fully (user and supervisor)
;
ARM_default_MMU_CR_table
[ :LNOT: CacheOff
;
;ARM 6 SBLDPWCAM
DCD 2_0000001111101
......@@ -161,6 +164,7 @@ ARM_default_MMU_CR_table
DCD 2_1001001111101
]
;
]
ARM_cacheoff_MMU_CR_table
......@@ -728,7 +732,7 @@ ClearPhysRAM ROUT
;now let us do the clear
[ ClearPhysRAMspeedup
MOV r0,#48 ;we can preserve r7-r9,r13 at logical address 48..63
MOV r0,#ZeroPage+InitClearRamWs ;we can preserve r7-r9,r13 at logical address 52..67
STMIA r0,{r7-r9,r13}
MOV r7, #0
MOV r8, #0
......@@ -774,11 +778,18 @@ ClearPhysRAM ROUT
BNE %BT10
[ ClearPhysRAMspeedup
MOV r12,#48
LDMIA r12,{r7-r9,r13} ;restore
MOV r12,#32 ;clear our speed up workspace
STMIA r12!,{r0-r3}
STMIA r12!,{r0-r3}
MOV r0, #ZeroPage+InitClearRamWs
LDMIA r0, {r7-r9,r13} ;restore
MOV r0, #ZeroPage+InitUsedStart ;clear our speed up workspace
ASSERT InitUsedStart < InitUsedEnd
ASSERT InitUsedEnd < InitClearRamWs
GBLA finalclear
finalclear SETA InitUsedStart
WHILE finalclear < InitWsEnd
STMIA r0!,{r1-r3}
finalclear SETA finalclear + 12
WEND
]
;StrongARM - now let us remove bufferable status of logical representation of physical space (perhaps we could
......
......@@ -1185,9 +1185,11 @@ FixedAreasTable ; table of fixed areas (
& &03000000, 16*1024*1024 ; I/O + ROM
]
& PhysSpace, 512*1024*1024 ; PhysSpace
[ :LNOT: HAL
[ No26bitCode
& AbtStack, AbtStackSize
]
]
[ ShadowROM
& &FF800000, &007FFFFF ; Shadow ROM (length has been bodged to avoid wrap problems)
]
......
......@@ -44,6 +44,8 @@
; now the conditional flags for the version we want
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GBLL CacheOff
CacheOff SETL {TRUE}
; ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; essential global variables
......@@ -533,6 +535,8 @@ MaxSwi * OS_NVMemory+1
GET Hdr:Heap
GET Hdr:PublicWS
GET Hdr:KernelWS
GET Hdr:HALEntries
GET Hdr:OSEntries
GET Hdr:Services
GET Hdr:FSNumbers
GET Hdr:HighFSI
......@@ -582,6 +586,7 @@ MaxSwi * OS_NVMemory+1
GET s.ChangeDyn
$GetHAL
GET s.Arthur2
GET s.LibKern
GET s.Utility
GET s.MoreComms
GET s.Convrsions
......
......@@ -12,27 +12,19 @@
; See the License for the specific language governing permissions and
; limitations under the License.
;
GBLL CacheOff
CacheOff SETL {TRUE}
; Sets $reg and sb up ready for CallHAL. $zero, if supplied, points to zero page (saves an instruction)
; Set sb up ready for CallHAL.
MACRO
AddressHAL $reg, $zero
[ "$zero" = ""
MOV $reg, #ZeroPage
LDR $reg, [$reg, #HAL_Entries]
|
LDR $reg, [$zero, #HAL_Entries]
]
LDR sb, =HAL_Workspace
AddressHAL
LDR sb, =ZeroPage
LDR sb, [sb, #HAL_Workspace]
MEND
; Calls the HAL. $rout is the routine, $hal is the register set up by AddressHAL.
; Calls the HAL. $rout is the routine. sb must have been set up by AddressHAL
MACRO
CallHAL $rout, $hal
LDR ip, [$hal, #$rout * 4]
CallHAL $rout
MOV lr, pc
ADD pc, $hal, ip
LDR pc, [sb, #-(EntryNo_$rout+1) * 4]
MEND
a1 RN 0
......@@ -49,24 +41,6 @@ sb RN 9
v7 RN 10
v8 RN 11
; Layouts of HAL and image headers
^ 0
HALDesc_Flags # 4
HALDesc_Start # 4
HALDesc_Size # 4
HALDesc_EntryTable # 4
HALDesc_Entries # 4
HALDesc_WorkspaceSize # 4
^ 0
ImgDesc_MagicWord # 4
ImgDesc_Flags # 4
ImgDesc_Address # 4
ImgDesc_Size # 4
ImgDesc_EntryTable # 4
ImgDesc_Entries # 4
; Fixed page allocation is as follows
......@@ -75,7 +49,6 @@ DRAMOffset_FirstFixed # 0
DRAMOffset_ScratchSpace # 16*1024
DRAMOffset_PageZero # 16*1024
DRAMOffset_L1PT # 16*1024 ; L1PT must be 16K-aligned
DRAMOffset_CAM # 0
DRAMOffset_LastFixed # 0
ARMv3 * 0
......@@ -401,7 +374,7 @@ RISCOS_Start
BNE %BT60
ADD v1, a3, #DRAMOffset_PageZero - DRAMOffset_L1PT
ADD v2, a3, #DRAMOffset_CAM - DRAMOffset_L1PT
ADD v2, a3, #DRAMOffset_LastFixed - DRAMOffset_L1PT
STR a2, [v1, #RAMLIMIT] ; remember the RAM size
MOV lr, a2, LSR #12
SUB lr, lr, #1
......@@ -421,32 +394,24 @@ RISCOS_Start
; v2 -> next address to allocate in v1 (may point at end of v1)
; v3 -> L1PT (or 0 if MMU on - not yet)
; Allocate the CAM
MOV a3, lr
LDR a2, =(AP_None * L2_APMult) + L2_C + L2_B
LDR a1, =CAM
BL Init_MapInRAM
; Allocate workspace for the HAL
LDR lr, [sp, #2*4] ; recover pushed HAL header
ADD a4, v3, #DRAMOffset_PageZero - DRAMOffset_L1PT
LDR a3, [sp, #8] ; recover pushed HAL header
LDR a1, =HALWorkspace
LDR a2, =(AP_None * L2_APMult) + L2_C + L2_B
LDR lr, [lr, #HALDesc_WorkspaceSize]
LDR lr, [a3, #HALDesc_Workspace] ; their workspace
LDR ip, [a3, #HALDesc_NumEntries] ; plus 1 word per entry
ADD lr, lr, ip, LSL #2
MOV a3, lr, LSR #12 ; round workspace up to whole
MOV a3, a3, LSL #12 ; number of pages
CMP a3, lr
ADDNE a3, a3, #&1000
STR a3, [a1, #HAL_WsSize]
LDR a1, =HALWorkspace
STR a3, [a4, #HAL_WsSize] ; Make a note of allocated space
ADD ip, a1, ip, LSL #2 ; Their workspace starts
STR ip, [a4, #HAL_Workspace] ; after our table of entries
BL Init_MapInRAM
ASSERT ZeroPage = 0
LDR a1, =HALWorkspace
MOV a2, #0
LDR a3, [a2, #HAL_WsSize]
BL memset
; Bootstrap time. We want to get the MMU on ASAP. We also don't want to have to
; clear up too much mess later. So what we'll do is map in the three fixed areas
; (L1PT, scratch space and page zero), the CAM, ourselves, and the HAL,
......@@ -489,7 +454,7 @@ RISCOS_Start
ADD v6, v6, v7 ; (v6,v8)=(start,end) of HAL
ADD v8, v6, lr
LDR v7, [v5, #ImgDesc_Size]
LDR v7, [v5, #OSHdr_ImageSize]
ADD v7, v5, v7 ; (v5,v7)=(start,end) of RISC OS
TEQ v8, v5 ; check contiguity (as in a ROM image)
......@@ -512,8 +477,8 @@ RISCOS_Start
B %FT75
70
; HAL is separate. Map it in at the start of IO space
LDR a2, =IO
; HAL is separate. (We should cope with larger images)
LDR a2, =ROM
MOV a1, v6
SUB ip, a2, a1 ; change physical address passed in
LDR a3, [sp, #8] ; into logical address
......@@ -537,6 +502,7 @@ RISCOS_Start
; We've now allocated all the pages we're going to before the MMU comes on.
; Note the end address (for RAM clear)
ADD a1, v3, #DRAMOffset_PageZero - DRAMOffset_L1PT
STR v1, [a1, #InitUsedBlock]
STR v2, [a1, #InitUsedEnd]
; Fill in some initial processor vectors. These will be used during ARM
......@@ -664,6 +630,11 @@ MMUon_nol1ptoverlap
SUB v1, v1, lr
ADD v1, v1, a1 ; turn v1 from LogAddr to PhysAddr
; Store the logical address of the HAL descriptor
LDR a1, =ZeroPage
LDR a2, [sp, #8]
STR a2, [a1, #HAL_Descriptor]
MOV v3, #0 ; "MMU is on" signal
BL ARM_Analyse
......@@ -671,14 +642,108 @@ MMUon_nol1ptoverlap
MOV a1, #L1_Fault
BL RISCOS_ReleasePhysicalAddress
BL ConstructCAMfromPageTables
ASSERT ZeroPage = 0
LDR a1, =HALWorkspace
MOV a2, #0
LDR a3, [a2, #HAL_WsSize]
BL memset
LDR a1, =IO
MOV a2, #ZeroPage
STR a1, [a2, #IOAllocPtr]
BL SetUpHALEntryTable
; Initialise the HAL
LDR a1, =RISCOS_Header
AddressHAL
CallHAL HAL_Init
; Start timer zero, at 100 ticks per second
MOV a1, #0
CallHAL HAL_TimerGranularity
MOV a2, a1
MOV a1, #100
BL __rt_udiv
MOV a2, a1
MOV a1, #0
CallHAL HAL_TimerSetPeriod
; Remember some stuff that's about to get zapped
LDR v8, =ZeroPage
LDR v5, [v8, #RAMLIMIT]
LDR v7, [v8, #MaxCamEntry]
; Clear the memory.
BL ClearPhysRAM
BKPT 2
; Put it back
STR v5, [v8, #RAMLIMIT]
STR v7, [v8, #MaxCamEntry]
; Allocate the CAM
LDR a3, [v8, #SoftCamMapSize]
LDR a2, =(AP_None * L2_APMult) + L2_C + L2_B
LDR a1, =CAM
BL Init_MapInRAM
; Allocate the supervisor stack
LDR a1, =SVCStackAddress
LDR a2, =(AP_Read * L2_APMult) + L2_C + L2_B
LDR a3, =SVCStackSize
BL Init_MapInRAM
[ HAL32
; Allocate the interrupt stack
LDR a1, =IRQStackAddress
LDR a2, =(AP_None * L2_APMult) + L2_C + L2_B
LDR a3, =IRQStackSize
BL Init_MapInRAM
]
; Allocate the abort stack
LDR a1, =ABTStackAddress
LDR a2, =(AP_None * L2_APMult) + L2_C + L2_B
LDR a3, =ABTStackSize
BL Init_MapInRAM
; Allocate the undefined stack
LDR a1, =UNDStackAddress
LDR a2, =(AP_None * L2_APMult) + L2_C + L2_B
LDR a3, =UNDStackSize
BL Init_MapInRAM
; Allocate the system heap
LDR a1, =SysHeapAddress
LDR a2, =(AP_Full * L2_APMult) + L2_C + L2_B
LDR a3, =32*1024
BL Init_MapInRAM
; Allocate the cursor/system/sound block
LDR a1, =CursorChunkAddress
LDR a2, =(AP_None * L2_APMult) + L2_C + L2_B
LDR a3, =32*1024
BL Init_MapInRAM
MSR CPSR_c, #F32_bit+I32_bit+IRQ32_mode
LDR sp, =IRQSTK
MSR CPSR_c, #F32_bit+I32_bit+ABT32_mode
LDR sp, =ABTSTK
MSR CPSR_c, #F32_bit+I32_bit+UND32_mode
LDR sp, =UNDSTK
MSR CPSR_c, #F32_bit+I32_bit+SVC2632
LDR sp, =SVCSTK
BL ConstructCAMfromPageTables
MOV a1, #4096
STR a1, [v8, #Page_Size]
B Continue_after_HALInit
LTORG
......@@ -800,19 +865,17 @@ ConstructCAMfromPageTables
; On exit:
; a1 -> next free page
; v1, v2 updated
; ip corrupt (a2-a4 preserved)
;
; No out of memory check...
Init_ClaimPhysicalPage
Push "lr"
MOV a1, v2
LDMIA v1, {ip, lr}
ADD ip, ip, lr ; ip = end of this bank
CMP v2, ip ; advance v2 to next bank if
LDMIA v1, {a2, a3}
ADD a2, a2, a3 ; ip = end of this bank
CMP v2, a2 ; advance v2 to next bank if
LDRHS a1, [v1, #8]! ; this bank is fully used
ADD v2, a1, #4096
Pull "pc"
MOV pc, lr
; Allocate and map in some RAM.
;
......@@ -1055,17 +1118,16 @@ AllocateL2PT
ORR a3, a1, #L1_Page + L1_U
]
AND lr, v8, #3
ORR v5, a3, lr, LSL #10
STR a3, [v6, v8, LSL #2]
ORR a3, a3, lr, LSL #10
STR a3, [v6, v8, LSL #2] ; fill in the L1PT
TEQ v3, #0 ; MMU on?
MOVEQ a1, a1 ; then point at logical address
MOVNE a1, v4 ; else point at physical address
MOV a2, #0
MOV a3, #4*1024
BL memset ; zero out 4K of L2PT
TEQ v3, #0 ; MMU off?
MOVNE a1, v4 ; if so, zero out the L2PT
MOVNE a2, #0 ; (if it's on then it will already
MOVNE a3, #4*1024 ; be clear from ClearPhysRAM, and
BLNE memset ; it's not mapped in yet anyway)
SUB a1, v4, #4*1024 ; Map in the L2PT page itself
MOV a1, v4 ; Map in the L2PT page itself
LDR a2, =L2PT ; (will recurse...)
ADD a2, a2, v8, LSL #10
BIC a2, a2, #&C00
......@@ -1159,6 +1221,10 @@ FindARMloop
ADD a2, v6, #DCache_Info
BL EvaluateCache
AND a1, v2, #CT_ctype_mask
MOV a1, a1, LSR #CT_ctype_pos
STRB a1, [v6, #Cache_Type]
MOV v5, #0
; Test abort timing (base restored or base updated)
......@@ -1188,12 +1254,9 @@ FindARMloop
LDR a1, [a1] ; If this aborts a1 will be left unchanged
TEQ a1, #0
ORREQ v5, v5, #CPUFlag_VectorReadException
35 STR v5, [v6, #ProcessorFlags]
35
30 Pull "v1,v2,v6,pc"
30 Pull "v1,v2,v5,v6,pc"
; This routine works out the values LINELEN, ASSOCIATIVITY, NSETS and CACHE_SIZE defined in section
......@@ -1329,7 +1392,7 @@ ClearPhysRAM ROUT
;now let us do the clear
MOV r0,#ZeroPage+InitClearRamWs ;we can preserve r7-r9,r13 at logical address 52..67
STMIA r0,{r7-r9,r13,lr}
STMIA r0,{r4-r11,r13,lr}
MOV r8, #0
MOV r9, #0
MOV r13,#0
......@@ -1353,7 +1416,7 @@ ClearPhysRAM ROUT
CMP r0, r11
BHS %FT18
BKPT 0
;BKPT 0
LDR r1, [r8, #InitUsedEnd]
TEQ r0, r10 ; if at start of block, easy
......@@ -1422,16 +1485,16 @@ ClearPhysRAM ROUT
BNE %BT10
50 MOV r1, #0
MOV r4, #ZeroPage+InitClearRamWs
LDMIA r4, {r7-r9,r13,r14} ;restore
MOV r0, #ZeroPage+InitClearRamWs
LDMIA r0, {r4-r11,r13,r14} ;restore
MOV r4, #ZeroPage+InitUsedStart ;clear our speed up workspace
MOV r0, #ZeroPage+InitUsedStart ;clear our speed up workspace
ASSERT InitUsedStart < InitUsedEnd
ASSERT InitUsedEnd < InitClearRamWs
GBLA finalclear
finalclear SETA InitUsedStart
WHILE finalclear < InitWsEnd
STMIA r4!,{r1-r3,r12}
STMIA r0!,{r1-r3,r12}
finalclear SETA finalclear + 16
WEND
......@@ -1482,48 +1545,6 @@ RamSkipTable
EndSkipTables
ROUT
memset
TEQ a3, #0 ; return immediately if zero bytes
MOVEQ pc, lr
TST a1, #3 ; check for unaligned start
BNE %FT80
05 SUBS a3, a3, #32 ; if at least 32, do 32 at a time
BLO %FT50
Push "v1-v5"
AND a2, a2, #&FF
ORR a2, a2, a2, LSL #8
ORR a2, a2, a2, LSL #16
MOV a4, a2
MOV v1, a2
MOV v2, a2
MOV v3, a2
MOV v4, a2
MOV v5, a2
MOV ip, a2
10 STMIA a1!, {a2,a4,v1,v2,v3,v4,v5,ip}
SUBS a3, a3, #32
BHS %BT10
Pull "v1-v5"
50 ADDS a3, a3, #32-4 ; if at least 4, do 4 at a time
BMI %FT70
60 STR a2, [a1], #4
SUBS a3, a3, #4
BPL %BT60
70 ADDS a3, a3, #4
MOVEQ pc, lr
80 STRB a2, [a1], #1 ; byte at a time until finished or
SUBS a3, a3, #1 ; aligned (if at end, will finish)
MOVEQ pc, lr
TST a1, #3
BNE %BT80
B %BT05
InitProcVecs
BKPT &C000 ; Reset
BKPT &C004 ; Undefined Instruction
......@@ -1537,5 +1558,60 @@ InitProcVec_FIQ
DCD 0
InitProcVecsEnd
RISCOS_MapInIO
Entry "v1-v4"
MOV a4, a3
AND a3, a1, #L2_C
ORR a3, a3, #AP_None * L2_APMult
MOV a1, a2
Push "a1,a3,a4"
BL FindIOVirtualAddress
MOV a2, a1
MOV v4, a1
Pull "a1,a3,a4"
MOV ip, #ZeroPage
LDR v1, [ip, #InitUsedBlock]
LDR v2, [ip, #InitUsedEnd]
MOV v3, #0
BL Init_MapIn
MOV a1, v4
EXIT
; a1 = Physical address
; a3 = flags
; a4 = size
FindIOVirtualAddress
MOV a2, a4, LSR #12
TEQ a4, a2, LSL #12
ADDNE a2, a2, #1
MOV a4, a2, LSL #12 ; a4 = size rounded up
ORR a2, a1, a4
MOVS ip, a2, LSL #12 ; EQ if megabyte aligned
MOV ip, #ZeroPage
LDR a3, [ip, #IOAllocPtr]
MOVEQ a3, a3, LSR #20
MOVEQ a3, a3, LSL #20
SUB a1, a3, a4
STR a1, [ip, #IOAllocPtr]
MOV pc, lr
SetUpHALEntryTable ROUT
LDR a1, =ZeroPage
LDR a2, [a1, #HAL_Descriptor]
LDR a3, [a1, #HAL_Workspace]
LDR a4, [a2, #HALDesc_Entries]
LDR ip, [a2, #HALDesc_NumEntries]
ADD a4, a2, a4 ; a4 -> entry table
MOV a2, a4 ; a2 -> entry table (increments)
10 LDR a1, [a2], #4
SUBS ip, ip, #1 ; decrement counter
ADD a1, a4, a1 ; convert offset to absolute
STR a1, [a3, #-4]! ; store backwards below HAL workspace
BHI %BT10
MOV pc, lr
END
......@@ -259,9 +259,8 @@ DoTestThings SETS ""
; RISC OS image header
RISCOS_Header
= "ROIm"
= "OSIm"
DCD 0
DCD ROM
DCD 1*1024*1024 - 64*1024
DCD RISCOS_Entries - RISCOS_Header
DCD (RISCOS_Entries_End - RISCOS_Entries) / 4
......@@ -270,6 +269,7 @@ RISCOS_Entries
DCD RISCOS_InitARM - RISCOS_Entries
DCD RISCOS_AddRAM - RISCOS_Entries
DCD RISCOS_Start - RISCOS_Entries
DCD RISCOS_MapInIO - RISCOS_Entries
RISCOS_Entries_End
|
......@@ -285,14 +285,14 @@ DoMorrisROMHeader SETS " GET s.Morris"
[ IncludeTestSrc
DoTestThings SETS " GET TestSrc.Begin"
]
$DoTestThings
[ IncludeTestSrc
DoMorrisROMHeader SETS ""
]
]
$DoTestThings
$DoMorrisROMHeader
]
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
......@@ -353,6 +353,8 @@ MOSROMVecs
SUBS pc, r14, #4
EndFiq
ASSERT InitKbdHandler >= EndFiq - MOSROMVecs
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; This is the table of default processor vectors which is copied to 0 page.
......
; Copyright 2000 Pace Micro Technology plc
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
;
; Kernel utility library
; void *memset(void *s, int c, size_t n) -------------------------------------------------
ROUT
memset
TEQ a3, #0 ; return immediately if zero bytes
MOVEQ pc, lr
ADD a1, a1, a3
TST a1, #3 ; check for unaligned end
BNE %FT80
05 SUBS a3, a3, #32 ; if at least 32, do 32 at a time
BLO %FT50
Push "v1-v5"
AND a2, a2, #&FF
ORR a2, a2, a2, LSL #8
ORR a2, a2, a2, LSL #16
MOV a4, a2
MOV v1, a2
MOV v2, a2
MOV v3, a2
MOV v4, a2
MOV v5, a2
MOV ip, a2
10 STMDB a1!, {a2,a4,v1,v2,v3,v4,v5,ip}
SUBS a3, a3, #32
BHS %BT10
Pull "v1-v5"
50 ADDS a3, a3, #32-4 ; if at least 4, do 4 at a time
BMI %FT70
60 STR a2, [a1, #-4]!
SUBS a3, a3, #4
BPL %BT60
70 ADDS a3, a3, #4
MOVEQ pc, lr
80 STRB a2, [a1, #-1]! ; byte at a time until finished or
SUBS a3, a3, #1 ; aligned (if at end, will finish)
MOVEQ pc, lr
TST a1, #3
BNE %BT80
B %BT05
; unsigned __rt_udiv(unsigned divisor, unsigned dividend) --------------------------------
ROUT
|__rt_udiv|
; Unsigned divide of a2 by a1: returns quotient in a1, remainder in a2
; Destroys a3 and ip only
MOV a3, #0
RSBS ip, a1, a2, LSR #3
BCC u_sh2
RSBS ip, a1, a2, LSR #8
BCC u_sh7
MOV a1, a1, LSL #8
ORR a3, a3, #&FF000000
RSBS ip, a1, a2, LSR #4
BCC u_sh3
RSBS ip, a1, a2, LSR #8
BCC u_sh7
MOV a1, a1, LSL #8
ORR a3, a3, #&00FF0000
RSBS ip, a1, a2, LSR #8
MOVCS a1, a1, LSL #8
ORRCS a3, a3, #&0000FF00
RSBS ip, a1, a2, LSR #4
BCC u_sh3
RSBS ip, a1, #0
BCS dividebyzero
u_loop MOVCS a1, a1, LSR #8
u_sh7 RSBS ip, a1, a2, LSR #7
SUBCS a2, a2, a1, LSL #7
ADC a3, a3, a3
u_sh6 RSBS ip, a1, a2, LSR #6
SUBCS a2, a2, a1, LSL #6
ADC a3, a3, a3
u_sh5 RSBS ip, a1, a2, LSR #5
SUBCS a2, a2, a1, LSL #5
ADC a3, a3, a3
u_sh4 RSBS ip, a1, a2, LSR #4
SUBCS a2, a2, a1, LSL #4
ADC a3, a3, a3
u_sh3 RSBS ip, a1, a2, LSR #3
SUBCS a2, a2, a1, LSL #3
ADC a3, a3, a3
u_sh2 RSBS ip, a1, a2, LSR #2
SUBCS a2, a2, a1, LSL #2
ADC a3, a3, a3
u_sh1 RSBS ip, a1, a2, LSR #1
SUBCS a2, a2, a1, LSL #1
ADC a3, a3, a3
u_sh0 RSBS ip, a1, a2
SUBCS a2, a2, a1
ADCS a3, a3, a3
BCS u_loop
MOV a1, a3
MOV pc, lr
dividebyzero
B dividebyzero
END
......@@ -142,8 +142,8 @@ NotScreen
; r10 = page size
; r11 = ap + CB
LDR r4, =FreePoolDANode
MOV r6, r11 ; r6 = ap + CB
MOV r4, #FreePoolDANode
LDR r7, [r4, #DANode_Base]
LDR r8, [r4, #DANode_Size]
ADD r7, r7, r8 ; r7 -> end of free pool +1
......@@ -533,6 +533,8 @@ vectorpoke_notSA_1
BL Processor_Type ; Determines the processor type & stores it in page 0.
]
Continue_after_HALInit
;StrongARM: OK, there is quite a bit of code poking below, to various addresses. We'll
; defer IMB consideration till the poking's done, then do a full IMB (full
; data cache clean). This avoids various little IMB's and removes chance of leaving
......@@ -577,7 +579,6 @@ vectorpoke_notSA_1
MSR CPSR_c, r0
]
; Ensure any CMOS operation aborted
MOV R1,#16 ; Two bytes in case RTC transmitting
......@@ -680,26 +681,38 @@ afterpokingaround_notSA
; Initialise CAO ptr to none.
MOV R0, #0
MOV R1, #32*1024*1024 ; nothing will be here!!
LDR R1, =DuffEntry ; nothing will be here!!
STR R1, [R0, #Curr_Active_Object]
KeyWait * 200000 ; 1/5 sec wait (in microseconds)
[ HAL
us * 1
|
us * 2
]
[ KeyWait <> 0
; Check for keyboard there every 1/5 sec. but give up after 2 secs.
MOV r2, #IOC
MOV r3, #10 ; Check for keyboard 10 times (2 secs max).
MOV r4, #InitKbdWs
[ HAL
AddressHAL
]
kbdwait
LDRB r5, [r4, #KB_There_Flag]
[ EmulatorSupport
ARM_on_emulator r0
MOVEQ r0, #2
LDRNE r0, =KeyWait*2 ; Wait 1/5 second (give keys down a chance to come in).
MOVEQ r0, #us
LDRNE r0, =KeyWait*us ; Wait 1/5 second (give keys down a chance to come in).
|
LDR r0, =KeyWait*2 ; Wait 1/5 second (give keys down a chance to come in).
LDR r0, =KeyWait*us ; Wait 1/5 second (give keys down a chance to come in).
]
[ HAL
CallHAL HAL_CounterDelay
|
BL DoMicroDelay
]
TEQ r5, #0 ; If keyboard was there 1/5 second ago then
BNE kbdthere ; continue reset
SUBS r3, r3, #1 ; else wait a maximum of 2 seconds.
......@@ -788,12 +801,22 @@ checkboot
; IF power-on bit set in IOC AND R/T/Del/Copy pressed THEN reset CMOS RAM
; note that memory cleared if POR, so key info has had plenty of time!
[ HAL
MOV R0, #InitHALFlags
LDR R1, [R0]
TST R1, #OSStartFlag_POR
BEQ no_cmos_reset
TST R1, #OSStartFlag_NoCMOSReset
BNE no_cmos_reset
TST R1, #OSStartFlag_CMOSReset
BNE cmos_reset
|
MOV R0, #IOC
LDRB R1, [R0, #IOCIRQSTAA]
ANDS R1, R1, #por_bit
BEQ no_cmos_reset
[ CheckProtectionLink
[ CheckProtectionLink :LAND: :LNOT: HAL
LDR r0, =IOMD_MonitorType
; on Issue A's the protection bit is only weakly pulled up,
......@@ -817,6 +840,8 @@ checkboot
]
]
] ; HAL
MOV R0, #InitKbdWs
LDR R7, [R0, #R_Down_Flag]
CMP R7, #0
......@@ -835,7 +860,11 @@ checkboot
; the sync, that would probably be a better algorithm.
; **************************************************************************
[ HAL
! 0, "Sort out SetBorder for CMOS reset"
|
SetBorder R0, R1, 15, 0, 0 ; flash the border as warning!
]
MOVS R3, R7, LSR #16 ; full reset or just system?
MOVNE R3, #-1 ; Del or Copy does all RAM
......@@ -843,8 +872,8 @@ checkboot
[ ChecksumCMOS
BL ValChecksum ; unless the CMOS ram's corrupt ..
MOVNE R3, #-1 ; .. then blast it anyway.
[ STB
cmos_reset
[ STB
ADD sp, sp, #4 ; junk CannotReset flag from stack
]
MOVNE R0, #0 ; even the econet station number
......@@ -925,6 +954,10 @@ not_full_reset
MOVEQ R1, #MonitorTypeAuto :OR: Sync_Separate ; if T or Copy
BL Write
[ HAL
! 0, "Sort out 16-bit sound + PS/2 mouse CMOS reset selection"
|
[ MorrisSupport
MOV R8, #IOMD_Base
LDRB r0, [r8, #IOMD_ID0]
......@@ -945,7 +978,7 @@ not_full_reset
B Config16BitSound
]
dont_program_mousetype
]
] ; MorrisSupport
[ Select16BitSound
LDR r0, =IOMD_MonitorType
......@@ -975,6 +1008,7 @@ Config16BitSound
ConfigSoundDone
]
] ; HAL
ADR R8, DefaultCMOSTable
50
......@@ -1707,6 +1741,8 @@ CopyDefaultIRQ1V
LDR R1, RealIRQHandler
STR R1, [R0, #&18]
[ StrongARM
;for StrongARM, we need to do an IMB type thing for modifying code in vector area, and
;for copying irq handler code
......@@ -1737,11 +1773,18 @@ furtherpoke_notSA
MSR CPSR_c, r2
]
MOV R1, #&100
STR R1, [R0, #RCLimit]
STR R0, [R0, #ReturnCode]
STR R0, [R0, #TickNodeChain]
; clear the keyboard workspace (tidy!)
MOV R0, #InitKbdHandler
MOV R1, #0
MOV R2, #InitWsEnd - InitKbdHandler
BL memset
;now put in error handler and escape handler
BL DEFHAN
BL DEFHN2
......
......@@ -104,19 +104,20 @@ BCDToHex ROUT
;
; SetC1C0 - Set clock and data lines to values in R1 and R0 respectively
;
; out: All registers preserved, including PSR
; out: ATPCS
;
SetC1C0 ROUT
[ No26bitCode
Push "R0-R3,R14"
MRS R3, CPSR
Push "R9,R14"
[ HAL
AddressHAL
MOV R2, R1
MOV R1, R0
MOV R0, #1
CallHAL HAL_IICSetLines
|
Push "R0-R2,R14"
]
ADD R0, R0, R1, LSL #1 ; R0 := C0 + C1*2
[ AssemblingArthur :LOR: Module
MOV R2, #0 ; prepare to index soft copy
LDRB R1, [R2, #IOCControlSoftCopy] ; read soft copy
BIC R1, R1, #&03 ; clear clock and data
......@@ -124,12 +125,10 @@ SetC1C0 ROUT
ORR R0, R0, #&C0 ; make sure two test bits are
; always set to 1 !
STRB R0, [R2, #IOCControlSoftCopy] ; store back to soft copy
|
ORR R0, R0, #&FC ; set other bits to 1
]
MOV R2, #IOC
STRB R0, [R2, #IOCControl]
]
[ E2ROMSupport
[ :LNOT: :DEF: TestHarness
......@@ -145,11 +144,28 @@ SetC1C0 ROUT
]
BL DoMicroDelay
[ No26bitCode
MSR CPSR_f, R3
Pull "R0-R3,PC"
Pull "R9,PC"
; *****************************************************************************
;
; ReadC1C0 - Read clock and data lines to R1 and R0 respectively
;
; out: R0, R1 updated - otherwise ATPCS
;
ReadC1C0 ROUT
[ HAL
Push "sb,lr"
AddressHAL
CallHAL HAL_IICReadLines
Pull "sb,pc"
|
Pull "R0-R2,PC",,^
MOV a3, #IOC
LDRB a3, [a3, #IOCControl]
MOV a2, a1, LSR #1
AND a1, a1, #1
AND a2, a2, #1
MOV pc, lr
]
; *****************************************************************************
......@@ -164,8 +180,15 @@ SetC1C0 ROUT
;
DoMicroDelay ROUT
Push R14
[ HAL
Push "a3,a4,sb,ip,lr"
AddressHAL
MOVS a1, a1, LSR #1
ADC a1, a1, #0
CallHAL HAL_CounterDelay
Pull "a3,a4,sb,ip,pc"
|
Push R14
STRB R0, [R2, #Timer0LR] ; copy counter into output latch
LDRB R1, [R2, #Timer0CL] ; R1 := low output latch
10
......@@ -178,6 +201,7 @@ DoMicroDelay ROUT
BNE %BT10 ; loop if not finished
Pull PC
]
LTORG
......@@ -192,17 +216,18 @@ DoMicroDelay ROUT
ClockData ROUT
[ No26bitCode
Push "R1,R2,R14"
MRS R2,CPSR
Push "R0-R3,R4,R5,R12,R14"
MRS R4,CPSR
|
Push "R1, R14"
Push "R0-R3,R5,R12,R14"
]
MOV R5, R0
MOV R1, #0 ; Clock lo
BL SetC1C0
[ No26bitCode
ORR R1,R2,#I32_bit
ORR R1,R4,#I32_bit
MSR CPSR_c,R1
|
; Disable interrupts to ensure clock hi with data hi is only transient
......@@ -212,19 +237,21 @@ ClockData ROUT
ORR R1,R1,#I_bit
TEQP PC,R1
]
MOV R0, R5
MOV R1, #1 ; Clock hi
BL SetC1C0
; Delay here must be >= 4.0 microsecs
MOV R0, R5
MOV R1, #0 ; Clock lo
BL SetC1C0
[ No26bitCode
MSR CPSR_cf,R2 ; Restore interrupts
Pull "R1,R2,PC"
MSR CPSR_cf,R4 ; Restore interrupts
Pull "R0-R3,R4,R5,R12,PC"
|
Pull "R1, PC",,^
Pull "R0-R3,R5,R12,PC",,^
]
ClockData0 ROUT ; Clock a zero bit
......@@ -242,10 +269,10 @@ ClockData0 ROUT ; Clock a zero bit
Start ROUT
[ No26bitCode
Push "R0-R3,R14"
MRS R3, CPSR
Push "R0-R3,R4,R12,R14"
MRS R4, CPSR
|
Push "R0-R2,R14"
Push "R0-R3,R12,R14"
]
MOV R0, #1 ; clock HI, data HI
......@@ -273,10 +300,10 @@ Start ROUT
BL SetC1C0
[ No26bitCode
MSR CPSR_f, R3
Pull "R0-R3,PC"
MSR CPSR_f, R4
Pull "R0-R3,R4,R12,PC"
|
Pull "R0-R2,PC"
Pull "R0-R3,R12,PC"
]
; *****************************************************************************
......@@ -289,7 +316,7 @@ Start ROUT
;
Acknowledge ROUT
Push "R0-R2,R14"
Push "R0-R3,R12,R14"
MOV R0, #1 ; clock LO, data HI
MOV R1, #0
......@@ -310,8 +337,8 @@ Acknowledge ROUT
; Delay here must be >= 4.0 microsecs (0.6 for fast device)
MOV R2, #IOC
LDRB R2, [R2, #IOCControl] ; get the data from IOC
BL ReadC1C0
MOV R2, R0
MOV R0, #0
MOV R1, #0 ; clock lo
......@@ -328,7 +355,7 @@ Acknowledge ROUT
ORRNE R2, R2, #V_bit ; set V if no acknowledge
MSR CPSR_f, R2
Pull "R0-R2,PC"
Pull "R0-R3,R12,PC"
; *****************************************************************************
;
......@@ -339,10 +366,10 @@ Acknowledge ROUT
Stop ROUT
[ No26bitCode
Push "R0-R2,R14"
MRS R2, CPSR
Push "R0-R3,R4,R12,R14"
MRS R4, CPSR
|
Push "R0,R1,R14"
Push "R0-R3,R12,R14"
]
MOV R0, #0 ; clock HI, data LO
......@@ -357,9 +384,9 @@ Stop ROUT
[ No26bitCode
MSR CPSR_f, R2
Pull "R0-R2,PC"
Pull "R0-R3,R4,R12,PC"
|
Pull "R0,R1,PC",,^
Pull "R0-R3,R12,PC",,^
]
; *****************************************************************************
......@@ -442,13 +469,12 @@ StartTXPollAck ROUT
RXByte ROUT
[ No26bitCode
Push "R1-R5, R14"
Push "R1-R6,R12,R14"
MRS R5, CPSR
|
Push "R1-R4, R14"
Push "R1-R4, R6, R12, R14"
]
MOV R3, #0 ; byte:=0
MOV R2, #IOC
MOV R6, #0 ; byte:=0
MOV R4, #7
MOV R0, #1 ; clock LO, data HI
......@@ -468,9 +494,8 @@ RXByte ROUT
MOV R1, #1
BL SetC1C0
LDRB R1, [R2, #IOCControl] ; get the data from IOC
AND R1, R1, #1
ADD R3, R1, R3, LSL #1 ; byte:=byte*2+(IOC?0)AND1
BL ReadC1C0
ADD R6, R0, R6, LSL #1 ; byte:=byte*2+ SDA
MOV R0, #1 ; return clock LO
MOV R1, #0
......@@ -483,12 +508,12 @@ RXByte ROUT
SUBS R4, R4, #1
BCS %BT10
MOV R0, R3 ; return the result in R0
MOV R0, R6 ; return the result in R0
[ No26bitCode
MSR CPSR_f, R5
Pull "R1-R5, PC"
Pull "R1-R6, R12, PC"
|
Pull "R1-R4, PC",,^
Pull "R1-R4, R6, R12, PC",,^
]
; *****************************************************************************
......
......@@ -43,9 +43,9 @@ UtilityMod
]
Util_SWITab
= "ARM"
= "IMB"
= "IMBRange"
= "ARM",0
= "IMB",0
= "IMBRange",0
= 0
ALIGN
......
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