Commit 14a44ef3 authored by Ben Avison's avatar Ben Avison
Browse files

Mostly device stuff.

Detail:
  * Implemented OS_Hardware 2, 3 and 4 as described in Docs.HAL.NewAPI.
  * Added new OS->HAL and HAL->OS routines to register HAL devices with the
    OS during hard resets.
  * Updated Docs.HAL.NewAPI to correct inconsistencies, fill in missing
    definitions, and allow for interrupt sharing.
  * Now uses OS_LeaveOS to trigger callbacks after ROM module init.
Admin:
  Untested. Requires new HAL.

Version 5.35, 4.79.2.49. Tagged as 'Kernel-5_35-4_79_2_49'
parent 4bfadee7
......@@ -46,12 +46,12 @@ struct device
const char *description;
void *address;
uint32_t reserved[3];
int (*Activate)(struct peripheral *);
void (*Deactivate)(struct peripheral *)
void (*Reset)(struct peripheral *);
int (*Sleep)(struct peripheral *, state);
int (*Claim)(struct peripheral *, int intno, myfunc, handle);
void (*Release)(struct peripheral *, int intno, myfunc, handle);
bool (*Activate)(struct device *);
void (*Deactivate)(struct device *);
void (*Reset)(struct device *);
int32_t (*Sleep)(struct device *, int32_t state);
int32_t devicenumber;
bool (*TestIRQ)(struct device *);
uint32_t reserved[2];
};
......@@ -60,8 +60,8 @@ struct device
struct serial
{
struct device dev;
int (*ReadByte)(struct serial *);
void (*WriteByte)(struct serial *, int c);
uint8_t (*ReadByte)(struct serial *);
void (*WriteByte)(struct serial *, uint8_t c);
// private data
}
......@@ -71,16 +71,23 @@ device pointer.
Type
----
The type word describes what the device is. It is grouped into sub-words as follows:
The type word describes what the device is.
Bits 31-24: Top level type (eg video, sound, system peripheral, comms port)
Bits 23-16: Second level type (eg VDU display, 16-bit PCM sound output,
interrupt controller, UART).
Bits 15-0: Product code - a unique identifier for this particular device.
Bits 15-8: Top level type (eg video, sound, system peripheral, comms port)
Defined values are: 1 = video
2 = sound
3 = system peripheral
4 = comms port
Bits 7-0: Second level type (eg VDU display, 16-bit PCM sound output,
interrupt controller, UART). Allocated independently within each top
level type.
A device driver will normally search for devices with a specific value in bits 31-16,
and not care about bits 15-0. Bits 31-16, together with the version number, indicate
which device specific calls are available.
This half-word, together with the version number, indicate which device specific calls
are available.
ID
--
16-bit product code - a unique identifier for this particular device.
Location
--------
......@@ -128,7 +135,7 @@ depends on the exact device in question.
Activate
--------
A device driver must call the Activate entry point before using a device. A
success/failure indication is returned: 0 indicates successful activation, -1 indicates
success/failure indication is returned: 1 indicates successful activation, 0 indicates
unsuccessful. Devices may ignore activate/deactivate calls, count them, or
may alternatively provide full locking to allow only one activation. Typically this
would be called by in a driver's module initialisation routine. Alternatively, it might
......@@ -145,11 +152,25 @@ The Kernel will call the Reset entry point of every device on the system
before performing a software reset (eg OS_Reset or Ctrl-Break), after it has
issued Service_PreReset. All devices must enter a quiescent state.
Claim
Sleep
-----
Claim is a front-end to OS_ClaimDeviceVector. The device should set up interrupt
parameters appropriately for the interrupt in question, and call OS_ClaimDeviceVector.
This call reads or sets a device's power-down state. If the second parameter is -1,
then the current state is returned; otherwise the second parameter must be a value in
the range 0-255 giving sleepiness (0 = full power, 255 = off) and the old sleepiness
is returned. Note that the value returned does not have to match the last value
programmed: for example, if a device cannot power down, it will always return 0.
DeviceNumber
------------
If this is -1, then the device has no associated interrupt. Otherwise, bits 0-30 give
the device number and bit 31 flags that the device vector is shared, ie this is the R0
that should be passed to OS_ClaimDeviceVector. If bit 31 is set then the TestIRQ
routine must be used to determine whether the vector should be claimed or passed on.
TestIRQ
-------
Returns 0 if the device is not interrupting, or 1 if the device is interrupting.
When DeviceNumber is -1, this must be a null pointer.
......@@ -164,9 +185,13 @@ On entry: R0 -> device descriptor
R8 = 2
On exit: All registers preserved
void OS_AddDevice(device *d);
void OS_AddDevice(uint32_t flags, struct device *d);
void HAL_InitDevices(uint32_t flags);
Declare a new device to the system. OS_AddDevice must not be called until
HAL_InitDevices is called.
Declare a new device to the system.
Devices are removed by calling OS_Hardware 3. There is no HAL->OS equivalent.
......@@ -176,13 +201,32 @@ On entry: R0 -> device descriptor
R8 = 3
On exit: All registers preserved
The Kernel tracks all present devices, issuing service calls as devices come and go, and
providing a call to enumerate devices of a particular type.
SWI OS_Hardware 4 (SWI &7A)
---------------------------
On entry: R0 = type
On entry: R0 = type to match
R1 = 0 to start an enumeration, else preserved from last call
R8 = 4
On exit:
On exit: R1 = -1 if there are no (more) devices of this type
R2 -> device descriptor (undefined if R1 = -1)
Other registers preserved
Service_Device (Service Call &??)
----------------------------------
On entry: R0 bits 0-7 = sub-reason code, bits 8-31 flags (undefined, ignore)
R1 = reason code (&??)
R2 -> device
On exit: Depends on sub-reason code
Sub-reason code 0: Device added
On exit: All registers must be preserved
Sub-reason code 1: Device being removed
On exit: R1 = 0 => we object to device being removed
R0 -> error block
other registers must be preserved
else all registers must be preserved
......@@ -14,3 +14,4 @@
|
Dir <Obey$Dir>
amu_machine clean
stripdepnd
......@@ -7,19 +7,17 @@
GBLS Module_MinorVersion
GBLS Module_Date
GBLS Module_FullVersion
GBLS Module_ApplicationDate2
GBLS Module_ApplicationDate4
GBLS Module_ApplicationDate
GBLS Module_HelpVersion
GBLS Module_ComponentName
GBLS Module_ComponentPath
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.48"
Module_Date SETS "07 Oct 2002"
Module_ApplicationDate2 SETS "07-Oct-02"
Module_ApplicationDate4 SETS "07-Oct-2002"
Module_MinorVersion SETS "4.79.2.49"
Module_Date SETS "16 Oct 2002"
Module_ApplicationDate SETS "16-Oct-02"
Module_ComponentName SETS "Kernel"
Module_ComponentPath SETS "RiscOS/Sources/Kernel"
Module_FullVersion SETS "5.35 (4.79.2.48)"
Module_HelpVersion SETS "5.35 (07 Oct 2002) 4.79.2.48"
Module_FullVersion SETS "5.35 (4.79.2.49)"
Module_HelpVersion SETS "5.35 (16 Oct 2002) 4.79.2.49"
END
......@@ -5,20 +5,19 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.48
#define Module_Date_CMHG 07 Oct 2002
#define Module_MinorVersion_CMHG 4.79.2.49
#define Module_Date_CMHG 16 Oct 2002
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.48"
#define Module_Date "07 Oct 2002"
#define Module_MinorVersion "4.79.2.49"
#define Module_Date "16 Oct 2002"
#define Module_ApplicationDate2 "07-Oct-02"
#define Module_ApplicationDate4 "07-Oct-2002"
#define Module_ApplicationDate "16-Oct-02"
#define Module_ComponentName "Kernel"
#define Module_ComponentPath "RiscOS/Sources/Kernel"
#define Module_FullVersion "5.35 (4.79.2.48)"
#define Module_HelpVersion "5.35 (07 Oct 2002) 4.79.2.48"
#define Module_FullVersion "5.35 (4.79.2.49)"
#define Module_HelpVersion "5.35 (16 Oct 2002) 4.79.2.49"
#define Module_LibraryVersionInfo "5:35"
......@@ -140,6 +140,29 @@ EntryNo_HAL_ATAControllerInfo # 1
EntryNo_HAL_ATASetModes # 1
EntryNo_HAL_ATACableID # 1
EntryNo_HAL_InitDevices # 1
; Quick bodge until devices are working...
EntryNo_HAL_DMA_Activate # 1
EntryNo_HAL_DMA_Deactivate # 1
EntryNo_HAL_DMA_Reset # 1
EntryNo_HAL_DMA_Sleep # 1
EntryNo_HAL_DMA_TestIRQ # 1
EntryNo_HAL_DMA_DMA_EnumeratePhysical # 1
EntryNo_HAL_DMA_DMA_EnumerateLogical # 1
EntryNo_HAL_DMA_DMA_Allocate # 1
EntryNo_HAL_DMA_DMA_Deallocate # 1
EntryNo_HAL_DMA_DMA_Features # 1
EntryNo_HAL_DMA_DMA_SetOptions # 1
EntryNo_HAL_DMA_DMA_SetCurrentTransfer # 1
EntryNo_HAL_DMA_DMA_SetNextTransfer # 1
EntryNo_HAL_DMA_DMA_TransferState # 1
EntryNo_HAL_DMA_DMA_SetCurrentTransfer2 # 1
EntryNo_HAL_DMA_DMA_SetNextTransfer2 # 1
EntryNo_HAL_DMA_DMA_TransferState2 # 1
EntryNo_HAL_DMA_DMA_IRQClear # 1
EntryNo_HAL_DMA_DMA_Status # 1
; Various flags and constants
; NVMemory
......
......@@ -1276,6 +1276,10 @@ 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 ARM control register
[ HAL
DeviceCount # 4 ; size of our table of devices in the system heap
DeviceTable # 4 ; pointer to table
]
AplWorkSize * AppSpaceDANode + DANode_Size
......
......@@ -19,6 +19,9 @@ OS_InitARM # 1
OS_AddRAM # 1
OS_Start # 1
OS_MapInIO # 1
OS_AddDevice # 1
HighestOSEntry * :INDEX: @ - 1
; The layout of the OS header
^ 0
......
......@@ -40,6 +40,7 @@ ShowWS SETL {TRUE} ; Make KernelWS be verbose
GET Hdr:PublicWS
GET Hdr:KernelWS
GET Hdr:HALEntries
GET Hdr:HALDevice
GET Hdr:OSEntries
GET Hdr:Services
GET Hdr:FSNumbers
......
......@@ -1806,6 +1806,12 @@ RISCOS_MapInIO ROUT
EXIT
; void RISCOS_AddDevice(unsigned int flags, struct device *d)
RISCOS_AddDevice
ADDS a1, a2, #0 ; also clears V
B HardwareDeviceAdd_Common
SetUpHALEntryTable ROUT
LDR a1, =ZeroPage
LDR a2, [a1, #HAL_Descriptor]
......@@ -1830,8 +1836,14 @@ NullHALEntry
HardwareSWI
AND ip, v5, #&FF
CMP ip, #1
BHI HardwareBadReason
BLO HardwareCall
BEQ HardwareLookup
CMP ip, #3
BLO HardwareDeviceAdd
BEQ HardwareDeviceRemove
CMP ip, #5
BLO HardwareDeviceEnumerate
BHS HardwareBadReason
HardwareCall
Push "v1-v4,sb,lr"
......@@ -1867,6 +1879,110 @@ HardwareLookup
MOV a2, sb
ExitSWIHandler
HardwareDeviceAdd
Push "lr"
BL HardwareDeviceAdd_Common
Pull "lr"
B SLVK_TestV
HardwareDeviceRemove
Push "lr"
BL HardwareDeviceRemove_Common
Pull "lr"
B SLVK_TestV
HardwareDeviceAdd_Common
Entry "r1-r3"
BL HardwareDeviceRemove_Common ; first try to remove any device already at the same address
EXIT VS
MOV lr, #0
LDR r1, [lr, #DeviceCount]
LDR r2, [lr, #DeviceTable]
TEQ r2, #0
BEQ %FT80
LDR lr, [r2, #-4] ; word before heap block is length
TEQ r1, lr, LSR #2 ; block already full?
BEQ %FT81
10 ADD lr, r2, r1, LSL #2
11 LDR r1, [lr, #-4]! ; copy existing devices up, so new ones get enumerated first
STR r1, [lr, #4]
CMP lr, r2
BHI %BT11
STR r0, [r2]
MOV r2, r0
MOV r1, #Service_Device
MOV r0, #0
BL Issue_Service
ADDS r0, r2, #0 ; exit with V clear
EXIT
80 ; Claim a system heap block for the device table
MOV r3, #16
BL ClaimSysHeapNode
EXIT VS
MOV r1, #0
STR r2, [r1, #DeviceTable]
B %BT10
81 ; Extend the system heap block
MOV r0, #HeapReason_ExtendBlock
MOV r3, #16
BL DoSysHeapOpWithExtension
EXIT VS
MOV lr, #0
LDR r1, [lr, #DeviceCount]
STR r2, [lr, #DeviceTable]
B %BT10
HardwareDeviceRemove_Common
Entry "r1-r4"
MOV lr, #0
LDR r3, [lr, #DeviceCount]
LDR r4, [lr, #DeviceTable]
TEQ r3, #0
EXIT EQ ; no devices registered
01 LDR r2, [r4], #4
TEQ r2, r0
SUBNES r3, r3, #1
BNE %BT01
TEQ r2, r0
EXIT NE ; this device not registered
MOV r0, #1
MOV r1, #Service_Device
BL Issue_Service
CMP r1, #0 ; if service call claimed
CMPEQ r1, #1:SHL:31 ; then set V
EXIT VS ; and exit
MOV r0, r2
SUBS r3, r3, #1
02 LDRNE r2, [r4], #4 ; copy down remaining devices
STRNE r2, [r4, #-8]
SUBS r3, r3, #1
BNE %BT02
EXIT
HardwareDeviceEnumerate
Push "r3-r4,lr"
MOV lr, #0
LDR r2, [lr, #DeviceCount]
LDR r3, [lr, #DeviceTable]
SUBS r4, r2, r1
MOVLS r1, #-1
BLS %FT90 ; if r1 is out of range then exit
ADD r3, r3, r1, LSL #2
10 ADD r1, r1, #1
LDR r2, [r3], #4
LDR lr, [r2, #HALDevice_Type + 2]
MOV lr, lr, LSR #16
TEQ lr, r0
SUBNES r4, r4, #1
BNE %BT10
TEQ lr, r0
MOVNE r1, #-1
90
Pull "r3-r4,lr"
ExitSWIHandler
HardwareBadReason
ADR r0, ErrorBlock_HardwareBadReason
[ International
......
......@@ -356,10 +356,11 @@ RISCOS_Header
DCD (RISCOS_Entries_End - RISCOS_Entries) / 4
RISCOS_Entries
DCD RISCOS_InitARM - RISCOS_Entries
DCD RISCOS_AddRAM - RISCOS_Entries
DCD RISCOS_Start - RISCOS_Entries
DCD RISCOS_MapInIO - RISCOS_Entries
DCD RISCOS_InitARM - RISCOS_Entries
DCD RISCOS_AddRAM - RISCOS_Entries
DCD RISCOS_Start - RISCOS_Entries
DCD RISCOS_MapInIO - RISCOS_Entries
DCD RISCOS_AddDevice - RISCOS_Entries
RISCOS_Entries_End
|
......
......@@ -1804,7 +1804,13 @@ ResetPart1Done ; R0 is reset type
BEQ SkipHardResetPart2
; HardResetPart2
[ :LNOT: HAL
[ HAL
AddressHAL
MOV R0, #0
STR R0, [R0, #DeviceCount]
STR R0, [R0, #DeviceTable]
CallHAL HAL_InitDevices ; get HAL to register any devices it has
|
BL L1L2PTenhancements ; little tricks on cacheability etc for performance
]
BL InitVariables
......@@ -1842,22 +1848,14 @@ ResetPart1Done ; R0 is reset type
BL Issue_Service
; New code added here by TMD 01-Apr-92
; Go into user mode, issue a dummy SWI, then go back into SVC mode
; Changed to use OS_LeaveOS 16-Oct-02
[ DebugROMInit
SWI XOS_WriteS
= "callbacks",0
SWI XOS_NewLine
]
WritePSRc 0, R14 ; enter USR mode (IRQs, FIQs enabled)
NOP ; wait for it to take effect
SWI XOS_WriteI+0 ; I hope it doesn't generate an error
; otherwise the callback will get deferred!
[ DebugROMInit
SWI XOS_WriteS
= "EnterOS!",0
SWI XOS_NewLine
]
SWI XOS_LeaveOS
SWI XOS_EnterOS ; switch back to SVC mode (IRQs, FIQs enabled)
[ :LNOT: HAL :LAND: RO371Timings
BL finalmemoryspeed
......
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