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