Commit a89c776b authored by Dan Ellis's avatar Dan Ellis
Browse files

Added HAL NVRAM support

Detail:
  Added the HAL NVRAM entries.
  Modified i2cutils to use the HAL entries for NVRAM and behave sensibly if the HAL reports that there is no NVRAM, in which case there must be a forced reset_cmos call so that the cache gets set up sensibly.
Admin:
  Tested under the RPC emulator and appears to be working correctly, although some calls to IIC are still being made in the no nvram case.

Version 5.35, 4.79.2.8. Tagged as 'Kernel-5_35-4_79_2_8'
parent 05b4e6c2
......@@ -171,7 +171,9 @@ void HAL_NVMemoryProtection(bool)
unsigned int HAL_NVMemoryIICAddress(void)
Returns a word describing the addressing scheme of the NVRAM.
bits 0-7: IIC address
bits 0-7: IIC address
This will always be on bus zero.
int HAL_NVMemoryRead(unsigned int addr, void *buffer, unsigned int n)
......
......@@ -11,10 +11,10 @@
GBLS Module_HelpVersion
Module_MajorVersion SETS "5.35"
Module_Version SETA 535
Module_MinorVersion SETS "4.79.2.7"
Module_MinorVersion SETS "4.79.2.8"
Module_Date SETS "05 Oct 2000"
Module_ApplicationDate2 SETS "05-Oct-00"
Module_ApplicationDate4 SETS "05-Oct-2000"
Module_FullVersion SETS "5.35 (4.79.2.7)"
Module_HelpVersion SETS "5.35 (05 Oct 2000) 4.79.2.7"
Module_FullVersion SETS "5.35 (4.79.2.8)"
Module_HelpVersion SETS "5.35 (05 Oct 2000) 4.79.2.8"
END
......@@ -4,16 +4,16 @@
*
*/
#define Module_MajorVersion_CMHG 5.35
#define Module_MinorVersion_CMHG 4.79.2.7
#define Module_MinorVersion_CMHG 4.79.2.8
#define Module_Date_CMHG 05 Oct 2000
#define Module_MajorVersion "5.35"
#define Module_Version 535
#define Module_MinorVersion "4.79.2.7"
#define Module_MinorVersion "4.79.2.8"
#define Module_Date "05 Oct 2000"
#define Module_ApplicationDate2 "05-Oct-00"
#define Module_ApplicationDate4 "05-Oct-2000"
#define Module_FullVersion "5.35 (4.79.2.7)"
#define Module_HelpVersion "5.35 (05 Oct 2000) (4.79.2.7)"
#define Module_FullVersion "5.35 (4.79.2.8)"
#define Module_HelpVersion "5.35 (05 Oct 2000) (4.79.2.8)"
......@@ -74,10 +74,23 @@ EntryNo_HAL_Video_VetMode # 1
EntryNo_HAL_MachineID # 1
; Various flags and constants
; NVMemory
NVMemoryFlag_None * 0
NVMemoryFlag_MaybeIIC * 1
NVMemoryFlag_IIC * 2
NVMemoryFlag_HAL * 3
NVMemoryFlag_Provision * 7 ; mask for provision
NVMemoryFlag_ProtectAtEnd * 1:SHL:8 ; Protected region at end
NVMemoryFlag_Deprotectable * 1:SHL:9
NVMemoryFlag_LowRead * 1:SHL:10 ; locations 0-15 are readable
NVMemoryFlag_LowWrite * 1:SHL:11 ; locations 0-15 are writeable
; IIC
IICFlag_LowLevel * 1:SHL:0
IICFlag_HighLevel * 1:SHL:1
IICFlag_Fast * 1:SHL:16
IICFlag_HighSpeed * 1:SHL:17
END
......@@ -1173,18 +1173,14 @@ ProcVecPreVeneers # ProcVecPreVeneersSize
# (&300-@)
Export_DebuggerSpace # 16*8 ; Debugger module needs some zero page
[ E2ROMSupport
NVRamSize # 1 ; Size of NVRam (E2ROM & CMOS) fitted in 256byte units
RTCFitted # 1 ; flag =1 iff RTC is fitted
]
; NVRAM support
[ E2ROMSupport
NVRamSize # 1 ; Size of NVRam (E2ROM & CMOS) fitted in 256byte units
RTCFitted # 1 ; flag =1 iff RTC is fitted
NVRamBase # 1 ; Base of NVRam
NVRamSpeed # 1 ; Clock hold time in 0.5s units
NVRamPageSize # 1 ; Page size for writing (log2)
NVRamWriteSize # 1 ; Size of writable region (256byte units)
]
AlignSpace
......
......@@ -31,8 +31,8 @@ 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)
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)
OSStartFlag_NoCMOS * 1:SHL:3 ; There's no real NVRAM, only cache
END
......@@ -1237,7 +1237,7 @@ FindARMloop
LDR a1, [sp], #4
TEQ a1, a2
ORREQ v5, v5, #CPUFlag_StorePCplus8
[ 0=1
; Check whether 26-bit mode is available
MSR CPSR_c, #F32_bit+I32_bit+SVC26_mode
MRS a1, CPSR
......@@ -1252,9 +1252,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]
30 Pull "v1,v2,v5,v6,pc"
Pull "v1,v2,v5,v6,pc"
; This routine works out the values LINELEN, ASSOCIATIVITY, NSETS and CACHE_SIZE defined in section
......
......@@ -1305,12 +1305,9 @@ IOST_BATMAN * 64 ;Stork keyboard/battery controller seems to be present
ORRNE r2, r2, #&00000100 ;NE, Morris based machine with IOMDL
ORRNE r2, r2, #&00010000 ;NE, and VIDC2L
]
[ E2ROMSupport
MOV r1, #0
LDRB r1, [r1, #NVRamSpeed]
|
MOV r1,#I2Cticks ; defined in PMF.i2cutils
]
SUB r1, r1, #1 ; catch zero = slow (just in case)
CMP r1, #3-1 ; speed is 3 for 400kHz, 10 for 100kHz.
ORRLS r2, r2, #&01000000 ; indicate fast speed
......
......@@ -590,6 +590,10 @@ Continue_after_HALInit
[ CacheCMOSRAM
BL InitCMOSCache ; initialise cache of CMOS RAM
TEQ R0, #0 ; returns zero on failure
LDREQ R1, [R0, #InitHALFlags]
ORREQ R1, R1, #OSStartFlag_NoCMOS
STREQ R1, [R0, #InitHALFlags]
]
; Now copy the initialised data
......@@ -804,6 +808,8 @@ checkboot
[ HAL
MOV R0, #InitHALFlags
LDR R1, [R0]
TST R1, #OSStartFlag_NoCMOS ; If no CMOS, reset for sensible cache
BEQ cmos_reset
TST R1, #OSStartFlag_POR
BEQ no_cmos_reset
TST R1, #OSStartFlag_NoCMOSReset
......
......@@ -44,7 +44,6 @@ PollMax * 150 ; Number of times to poll for an Ack (increase if you clock faste
; Device addresses
RTCAddress * &a0 ; traditional RTC / 240 byte CMOS
[ E2ROMSupport
E2ROMAddress * &a8 ; 24C08 device - 512 byte or 1K
E2ROMAddress2K * &e0 ; 24C174 device - 2K
E2ROMAddress2K_OTP * &60 ; 24C174 device - OTP section
......@@ -52,7 +51,6 @@ E2ROMAddress4K * &a4 ; 24C32 device - 4K (top 1K protectable)
E2ROMAddress8K * &a2 ; 24C64 device - 8K (top 2K protectable)
E2ROMAddress16K * &a8 ; 24C128 device - 16K
E2ROMAddress32K * &a6 ; 24CS256 device - 32K (top 2K possibly OTP)
]
; Choose a lower limit on the number of ticks per clock phase based on the
; MaxI2Cspeed variable defined in Hdr:Machine.<Machine>
......@@ -66,6 +64,7 @@ I2Cticks * 10
]
]
; *****************************************************************************
;
; HexToBCD - Convert byte in hex to BCD
......@@ -113,7 +112,7 @@ SetC1C0 ROUT
AddressHAL
MOV R2, R1
MOV R1, R0
MOV R0, #1
MOV R0, #0
CallHAL HAL_IICSetLines
|
ADD R0, R0, R1, LSL #1 ; R0 := C0 + C1*2
......@@ -131,12 +130,8 @@ SetC1C0 ROUT
]
[ E2ROMSupport
[ :LNOT: :DEF: TestHarness
MOV R0, #0
LDRB R0, [R0, #NVRamSpeed]
|
LDRB R0, NVSpeed
]
TEQ R0, #0
MOVEQ R0, #10 ; default value if speed not checked yet
|
......@@ -285,13 +280,14 @@ Start ROUT
MOV R1, #1
BL SetC1C0
[ I2Cticks >= 10
; Hold start condition for BMU
LDR R0, =ZeroPage
LDRB R0, [R0, #NVRamSpeed]
MOV R2, #IOC
MOV R0, #10
BL DoMicroDelay
]
CMP R0, #10
MOVGE R2, #IOC
MOVGE R0, #10
BLGE DoMicroDelay
; Delay here must be >= 4.0 microsecs (0.6 for fast device)
......@@ -607,17 +603,40 @@ Write
ORREQ R4, R4, #&1000000 ; if checksum is being written
]
10
[ CacheCMOSRAM
CMP r2, #&100 ; check small cache limit
BCS %FT15
[ :LNOT: :DEF: TestHarness
LDR R1, =CMOSRAMCache ; update cache, but always write to
|
ADR R1, i2cWorkSpace
]
STRB R3, [R1, R2] ; real hardware as well
15
]
[ HAL
Push "R12,sb"
AddressHAL
MOV R12, R2
CallHAL HAL_NVMemoryType
AND R0, R0, #NVMemoryFlag_Provision
TEQ R0, #NVMemoryFlag_None
; If there's no NVmemory, all we have is the internal cache.
Pull "R12,sb", EQ
Pull "R0-R4,PC", EQ
TEQ R0, #NVMemoryFlag_HAL
BNE %FT20 ; Go and do IIC stuff.
; Make the HAL call - we have to write the data into a buffer.
Push "R3"
MOV R0, R12
MOV R1, sp
MOV R2, #1
CallHAL HAL_NVMemoryWrite
Pull "R3"
Pull "R12,sb"
Pull "R0-R4,PC"
20
]
[ E2ROMSupport
MOV R0, R2
BL GetI2CAddress ; convert to device address + offset
......@@ -664,15 +683,10 @@ Write
WriteBlock ROUT
Push "R0-R4,R14"
[ E2ROMSupport
[ :LNOT: :DEF: TestHarness
MOV R14, #0
LDRB R4, [R14, #NVRamWriteSize]
LDRB R14, [R14, #NVRamSize]
MOV R4, R4, LSL #8
|
LDRB R14, NVSize
MOV R4, R14
]
MOV R14, R14, LSL #8
|
MOV R14, #240
......@@ -793,12 +807,8 @@ WriteSubBlock ROUT
MOVHI R3, R14
[ E2ROMSupport
; R3 = logical end of possible transaction (exclusive). Now check we don't cross page boundaries.
[ :LNOT: :DEF: TestHarness
MOV R14, #0
LDRB R14, [R14, #NVRamPageSize]
|
LDRB R14, NVPageSize
]
MOV R5, #1
MOV R14, R5, LSL R14 ; R14 = (1<<pagesize)
......@@ -812,15 +822,10 @@ WriteSubBlock ROUT
MOVLO R3, R5 ; adjust R3 to not cross page boundary
]
[ CacheCMOSRAM
CMP R0, #&100 ; check it's a cacheable segment
BHS %FT15
[ :LNOT: :DEF: TestHarness
LDR R14, =CMOSRAMCache
|
ADR R14, i2cWorkSpace
]
Push "R3, R4"
ADD R3, R3, R4 ; R3 = physical end address
ADD R4, R4, R0 ; R4 = physical address
......@@ -834,10 +839,40 @@ WriteSubBlock ROUT
BLO %BT12
MOV R1, R5 ; restore R1, and continue to update real memory
Pull "R3, R4"
]
15
Push "R0-R2"
ADD R0, R0, R4 ; R0 = physical address
[ HAL
Push "R12, sb"
MOV R5, R0 ; save address
AddressHAL
CallHAL HAL_NVMemoryType
AND R0, R0, #NVMemoryFlag_Provision
TEQ R0, #NVMemoryFlag_None
; If there's no NVmemory, tough - we just return.
Pull "R12,sb", EQ
Pull "R0-R2", EQ
MOVEQ R2, #0 ; nothing written
Pull "R3,R5-R6,PC", EQ
TEQ R0, #NVMemoryFlag_HAL
MOV R0, R5 ; restore address
BNE %FT17 ; do IIC things.
; Make the HAL call
CallHAL HAL_NVMemoryWrite ; returns bytes wrtten in R0
MOV R2, R0
ADD R0, R0, R2 ; update return R0
ADD R4, R4, R2
Pull "R12,sb"
Pull "R0-R2"
Pull "R3,R5-R6,PC"
17
Pull "sb"
]
[ E2ROMSupport
BL GetI2CAddress ; convert to device address and offset
|
......@@ -909,7 +944,6 @@ Read
MOVCS R0, #0 ; pretend illegal addresses contain 0
Pull "R1,R2,PC", CS
10
[ CacheCMOSRAM
TEQ R0, #&40 ; is it Econet station number
BEQ %FT15 ; if so then don't use cache
CMP R0, #&10 ; don't cache the clock
......@@ -923,16 +957,40 @@ Read
BLO %FT15
]
13 CMP R0, #&100 ; check small cache limit
[ :LNOT: :DEF: TestHarness
LDRCC R2, =CMOSRAMCache ; if in range
|
ADRCC R2, i2cWorkSpace
]
LDRCCB R0, [R2, R0] ; read from cache
Pull "R1,R2,PC", CC ; and exit
15
; else drop thru into real CMOS reading code
[ HAL
Push "R4, sb"
MOV R4, R0 ; save address
AddressHAL
CallHAL HAL_NVMemoryType
AND R0, R0, #NVMemoryFlag_Provision
TEQ R0, #NVMemoryFlag_None
; If there's no NVmemory, pretend addresses contain 0
Pull "R4, sb", EQ
MOVEQ R0, #0
Pull "R1,R2,PC", EQ
TEQ R0, #NVMemoryFlag_HAL
MOV R0, R4 ; restore address
BNE %FT20
; Make the HAL call - we have to provide a buffer.
SUB sp, sp, #4 ; make some space on the stack
MOV R1, sp
MOV R2, #1
CallHAL HAL_NVMemoryRead
LDRB R0, [sp], #4 ; read back from stack and restore
Pull "R4, sb"
Pull "R1,R2,PC"
20
]
[ E2ROMSupport
......@@ -985,12 +1043,8 @@ Read
ReadBlock ROUT
Push "R0-R3,R14"
[ E2ROMSupport
[ :LNOT: :DEF: TestHarness
MOV R14, #0
LDRB R14, [R14, #NVRamSize]
|
LDRB R14, NVSize
]
MOV R14, R14, LSL #8
|
MOV R14, #240
......@@ -1063,17 +1117,12 @@ ReadSubBlock ROUT
CMP R3, R14
MOVHI R3, R14
; R3 = logical end of this transaction (exclusive)
[ CacheCMOSRAM
TEQ R0, #0 ; check it's a cacheable segment
BEQ %FT15
CMP R0, #&100
BHS %FT15
[ :LNOT: :DEF: TestHarness
LDR R14, =CMOSRAMCache
|
ADR R14, i2cWorkSpace
]
ADD R3, R3, R4 ; R3 = physical end address
ADD R4, R4, R0 ; R4 = physical address
ADD R3, R3, R14 ; R3 = cache end address
......@@ -1087,10 +1136,41 @@ ReadSubBlock ROUT
STRB R14, [R1], #1
BLO %BT12
Pull "R3-R5,PC" ; V will be clear
]
15
Push "R0-R2"
ADD R0, R0, R4 ; R0 = physical address
[ HAL
Push "sb"
MOV R5, R0 ; save address
AddressHAL
Push "R1-R3,R12"
CallHAL HAL_NVMemoryType
Pull "R1-R3,R12"
AND R0, R0, #NVMemoryFlag_Provision
TEQ R0, #NVMemoryFlag_None
; If there's no NVmemory, tough - we just return.
MOVEQ R2, #0 ; nothing read
Pull "sb", EQ
Pull "R3-R5,PC", EQ
TEQ R0, #NVMemoryFlag_HAL
MOV R0, R5 ; restore address
BNE %FT17 ; do IIC things.
; Make the HAL call
Push "R12"
CallHAL HAL_NVMemoryRead ; returns bytes read in R0
Pull "R12"
MOV R2, R0
ADD R0, R0, R1 ; update return R0
Pull "sb"
Pull "R3-R5,PC"
17
Pull "sb"
]
[ E2ROMSupport
BL GetI2CAddress ; convert to device address and offset
|
......@@ -1207,17 +1287,12 @@ ChecksumSubBlock ROUT
MOVHI R3, R14
; R3 = logical end of this transaction (exclusive)
[ CacheCMOSRAM
TEQ R0, #0 ; check it's a cacheable segment
BEQ %FT15
CMP R0, #&100
BHS %FT15
[ :LNOT: :DEF: TestHarness
LDR R14, =CMOSRAMCache
|
ADR R14, i2cWorkSpace
]
ADD R3, R3, R4 ; R3 = physical end address
ADD R4, R4, R0 ; R4 = physical address
ADD R3, R3, R14 ; R3 = cache end address
......@@ -1231,7 +1306,6 @@ ChecksumSubBlock ROUT
ADD R1, R1, R14
BLO %BT12
Pull "R3-R5,PC"
]
15
Push "R0-R2"
ADD R0, R0, R4 ; R0 = physical address
......@@ -1296,30 +1370,18 @@ ChecksumSubBlock ROUT
[ E2ROMSupport
GetI2CAddress ROUT
Push "R14"
[ :LNOT: :DEF: TestHarness
MOV R14, #0 ; get no 256 byte blocks and calculate end address
LDRB R14, [R14, #NVRamSize]
|
LDRB R14, NVSize
]
MOV R14, R14, LSL #8
CMP R0, R14
Pull "PC",CS ; indicate invalid
; address is < end address -> is valid
[ :LNOT: :DEF: TestHarness
MOV R1, #0
LDRB R1, [R1, #RTCFitted]
|
LDRB R1, RTCFlag
]
TEQ R1, #0
MOVNE R1, #RTCAddress
[ :LNOT: :DEF: TestHarness
LDREQB R1, [R1, #NVRamBase]
|
LDREQB R1, NVBase
]
CMP R14, #2*1024 ; is the device bigger than 2K? If so, new addressing scheme
ORRHI R1, R1, #&100 ; set magic bit => 2 byte address
......@@ -1353,12 +1415,8 @@ GetI2CAddress ROUT
MangleCMOSAddress ROUT
[ E2ROMSupport
Push "R14"
[ :LNOT: :DEF: TestHarness
MOV R14, #0 ; read no 256 byte blocks and calculate end address
LDRB R14, [R14, #NVRamSize]
|
LDRB R14, NVSize
]
MOV R14, R14, LSL #8
CMP R0, R14 ; if >= end address then
Pull "R14"
......@@ -1410,12 +1468,8 @@ ValChecksum Entry "R1-R2"
MOV R0, #0
MOV R1, #CMOSxseed
[ E2ROMSupport
[ :LNOT: :DEF: TestHarness
MOV R2, #0 ; read number of 256 byte blocks and calculate end address
LDRB R2, [R2, #NVRamSize]
|
LDRB R2, NVSize
]
MOV R2, R2, LSL #8
|
MOV R2, #240
......@@ -1452,12 +1506,8 @@ MakeChecksum ROUT
MOV R0, #0
MOV R1, #CMOSxseed
[ E2ROMSupport
[ :LNOT: :DEF: TestHarness
MOV R2, #0
LDRB R2, [R2, #NVRamSize]
|
LDRB R2, NVSize
]
MOV R2, R2, LSL #8
|
MOV R2, #240
......@@ -1491,21 +1541,16 @@ SetTime ROUT
Push "R4, R14" ; save registers
[ E2ROMSupport
[ :LNOT: :DEF: TestHarness
MOV R14, #0
LDRB R14, [R14, #RTCFitted]
|
LDRB R14, RTCFlag
]
TEQ R14, #0
BNE %FT20
; no RTC - just set soft copy
[ :LNOT: :DEF: TestHarness
BL RegToRealTime
]
Pull "R4, PC"
]
20
......@@ -1570,9 +1615,8 @@ SetTime ROUT
40
MOV R0, R4 ; put hours back in R0
[ :LNOT: :DEF: TestHarness
BL RTCToRealTime
]
Pull "R4, PC"
; *****************************************************************************
......@@ -1656,35 +1700,73 @@ ReadTime ROUT
; *****************************************************************************
;
; InitCMOSCache - Initialise cache of CMOS RAM
; in: -
;
; out: R0 = 0 for failure
[ CacheCMOSRAM
InitCMOSCache Entry "r0-r6"
InitCMOSCache Entry "r1-r6, sb"
[ E2ROMSupport
; Need to set the slowest speed so we can probe
MOV R2, #0
LDR R4, =ZeroPage
MOV R3, #10 ; Default speed setting (5s delays)
[ :LNOT: :DEF: TestHarness
STRB R3, [R2, #NVRamSpeed]
|
STRB R3, NVSpeed
]
STRB R3, [R4, #NVRamSpeed]
; First determine what hardware we've got fitted, R4 holds the number of
; 256 byte blocks that we've found
[ HAL
AddressHAL
CallHAL HAL_NVMemoryType