From 5f4a35164c399305b42851e4b30bbb2e62723da7 Mon Sep 17 00:00:00 2001 From: Robert Catherall <rcathera@gitlab.riscosopen.org> Date: Mon, 4 Sep 2000 18:47:59 +0000 Subject: [PATCH] Added 32K EEPROM support. New routine in i2cutils that allows access to protected sections such as MAC address OS_ReadSysInfo 4 now checks both copies MACAddress if MACNVRAM2copies is set Detail: 32K EEPROM has to be configured with IIC address &A6 (i.e wired up on the pcb) ClockNVMemoryFast has been replaced with MaxI2Cspeed so that several different rates can be used depending on the devices on the IIC bus. Admin: Need to implement routine that can use one copy of the MAC address to replace the other in the event of it being corrupted. Version 5.33. Tagged as 'Kernel-5_33' --- VersionASM | 12 ++-- VersionNum | 18 +++--- s/Middle | 164 +++++++++++++++++++++++++++++++++++++++++++------ s/PMF/i2cutils | 63 +++++++++++++------ 4 files changed, 202 insertions(+), 55 deletions(-) diff --git a/VersionASM b/VersionASM index 602c97e3..7e755985 100644 --- a/VersionASM +++ b/VersionASM @@ -8,11 +8,11 @@ GBLS Module_FullVersion GBLS Module_ApplicationDate2 GBLS Module_ApplicationDate4 -Module_MajorVersion SETS "5.32" -Module_Version SETA 532 +Module_MajorVersion SETS "5.33" +Module_Version SETA 533 Module_MinorVersion SETS "" -Module_Date SETS "18 Aug 2000" -Module_ApplicationDate2 SETS "18-Aug-00" -Module_ApplicationDate4 SETS "18-Aug-2000" -Module_FullVersion SETS "5.32" +Module_Date SETS "04 Sep 2000" +Module_ApplicationDate2 SETS "04-Sep-00" +Module_ApplicationDate4 SETS "04-Sep-2000" +Module_FullVersion SETS "5.33" END diff --git a/VersionNum b/VersionNum index a6ef902e..385d7c42 100644 --- a/VersionNum +++ b/VersionNum @@ -1,18 +1,18 @@ -/* (5.32) +/* (5.33) * * This file is automatically maintained by srccommit, do not edit manually. * */ -#define Module_MajorVersion_CMHG 5.32 +#define Module_MajorVersion_CMHG 5.33 #define Module_MinorVersion_CMHG -#define Module_Date_CMHG 18 Aug 2000 +#define Module_Date_CMHG 04 Sep 2000 -#define Module_MajorVersion "5.32" -#define Module_Version 532 +#define Module_MajorVersion "5.33" +#define Module_Version 533 #define Module_MinorVersion "" -#define Module_Date "18 Aug 2000" +#define Module_Date "04 Sep 2000" -#define Module_ApplicationDate2 "18-Aug-00" -#define Module_ApplicationDate4 "18-Aug-2000" +#define Module_ApplicationDate2 "04-Sep-00" +#define Module_ApplicationDate4 "04-Sep-2000" -#define Module_FullVersion "5.32" +#define Module_FullVersion "5.33" diff --git a/s/Middle b/s/Middle index 166b1170..1ae8e459 100644 --- a/s/Middle +++ b/s/Middle @@ -1305,13 +1305,11 @@ 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 ] - [ ClockNVMemoryFast MOV r1, #0 LDRB r1, [r1, #NVRamSpeed] 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 - ] [ StopClocksDuringIdle ORR r2, r2, #&02000000 ] @@ -1441,32 +1439,159 @@ ExitNoEthernetAddress ExitSWIHandler ] - [ STB + [ STB + +NVRAM_TAG_MACAddress + = "MACAddress", 0 +NVRAM_TAG_MACAddressChecksum + = "MACAddressChecksum", 0 +NVRAM_TAG_MACAddress2nd + = "MACAddress2nd", 0 +NVRAM_TAG_MACAddressChecksum2nd + = "MACAddressChecksum2nd", 0 + + ALIGN + GetMachineAddressCMOS ; Out: r0 = lower 4 bytes (or 0) ; r1 = upper 2 bytes (or 0) ; EQ => valid, NE => invalid ; - Entry "r2,r3", 8 ; Preserve these + Entry "r2-r5", 8 ; Preserve these + get 8 bytes workspace + + ADR r0,NVRAM_TAG_MACAddress + ADR r3,NVRAM_TAG_MACAddressChecksum + BL CheckOneCopyOfMachineAddressCMOS ; Get 1st copy of MAC in r0=low 4 bytes, + ; r1=upper 2 bytes of MAC in bytes 0,1 stored checksum in byte 2, calculated checksum in byte 3 + [ MACNVRAM2copies + MOV r4,r0 + MOV r5,r1 + + ADR r0,NVRAM_TAG_MACAddress2nd + ADR r3,NVRAM_TAG_MACAddressChecksum2nd + BL CheckOneCopyOfMachineAddressCMOS ; Get 2nd copy of MAC + + CMP r0,r4 + CMPEQ r1,r5 + BNE %FT41 ; Have different values - i.e one (possibly both) is wrong/broken + ] ;two copies of MAC + + MOV r2,r1,LSR#16 ; move checksum values into low bytes + AND r3,r2,#&ff ; r3=stored checksum + MOV r2,r2,LSR#8 ; r2=calculated checksum + CMP r2,r3 ; do the checksums match + BNE %FT43 ; if not then we have unrecoverable fault, both values identical but checksums broken + ; this would be the case for an unprogrammed CMOS + MOV r2,#&ff + ORR r2,r2,r2,LSL#8 ; mask for removing checksums + AND r1,r1,r2 ; #&0000ffff remove checksums from r1 + EXIT ; return with valid MAC in r0,r1 and flags set to EQ by branch just above + + [ MACNVRAM2copies +;two copies differ +41 + MOV r2,r5,LSR#16 ; move checksum for 1st copy into low bytes + AND r3,r2,#&ff ; r3=stored checksum + MOV r2,r2,LSR#8 ; r2=calculated checksum + CMP r2,r3 ; do the checksums match + BEQ %FT45 ; okay need to repair second set + + MOV r2,r1,LSR#16 ; move checksum for 2nd copy into low bytes + AND r3,r2,#&ff ; r3=stored checksum + MOV r2,r2,LSR#8 ; r2=calculated checksum + CMP r2,r3 ; do the checksums match + BEQ %FT46 ; okay need to repair first set + ] +;we arrive here if we have a situation from which no sensible MAC can be derived +;i) both values are broken +43 + MOV r0,#0 + MOV r1,#0 + EXIT ;return with r0,r1 both zero to indicate no valid address, two possible paths here both have NE flags + [ MACNVRAM2copies +;checksum is valid for first set so repair second set +45 + ADR r3,NVRAM_TAG_MACAddress2nd + ADR r0,NVRAM_TAG_MACAddressChecksum2nd + B %FT47 + +;checksum is valid for second set so repair first set +46 + MOV r4,r0 ;get values of 2nd set into write registers + MOV r5,r1 + ADR r3,NVRAM_TAG_MACAddress + ADR r0,NVRAM_TAG_MACAddressChecksum + +;store MAC (+ check sum) in r4,r5, and checksum in r2 to NVRAM tags given by r0 and r3 +47 + [ 1=2 + ; forgot that NVRAM_Write will fail + ; on locked locations such as .. the MAC addresses... + ; this will be modified shortly to call a new SWI provided + ; by the NVRAM module to turn a tag into an address and + ; then perform the write using routines in the i2cutils + ; section of the kernel. + + MOV r1, sp ;some workspace + STRB r2, [r1,#0] ;store the checksum + MOV r2, #1 + SWI XNVRAM_Write + ;TST r0, #&80000000 ; Check for errors + ;BNE %FT48 ; Oh dear + + BIC r5,r5,#&ffff0000 ;get rid of checksum - we already have a value in r2 extracted earlier + MOV r0,r3 ;NVRAM_TAG_MACAddress + MOV r1,sp ;workspace + + MOV r3,r5 + STRB r3,[r1,#1] + MOV r3,r3,LSR#8 + STRB r3,[r1,#0] + MOV r3,r4 + STRB r3,[r1,#5] + MOV r3,r3,LSR#8 + STRB r3,[r1,#4] + MOV r3,r3,LSR#8 + STRB r3,[r1,#3] + MOV r3,r3,LSR#8 + STRB r3,[r1,#2] + + MOV r2,#6 + SWI XNVRAM_Write + ;TST r0, #&80000000 ; Check for errors + ;BNE %FT48 ; Oh dear + ] +;return with the values from r4,r5 in r0,r1 and flags eq +;48 + MOV r0,r4 + MOV r1,r5 + CMP r1,r1 ;make flags equal - is this required? + EXIT + + ] ; MACNVRAM2copies + +;On entry r0 points to MAC address Tag name +; r3 points to Checksum Tag name +CheckOneCopyOfMachineAddressCMOS + Entry ,8 - ADR r0, NVRAM_TAG_MACAddress ; Read the MAC address MOV r1, sp MOV r2, #6 SWI XNVRAM_Read MOVVS r0, #&ffffffff TST r0, #&80000000 ; Check for errors - BNE %FT10 + BNE MachineAddressNVRAMError - ADR r0, NVRAM_TAG_MACAddressChecksum ; Read the checksum + MOV r0, r3 ADD r1, sp, #6 MOV r2, #1 - SWI NVRAM_Read + SWI XNVRAM_Read MOVVS r0, #&ffffffff TST r0, #&80000000 ; Check for errors -10 + BNE MachineAddressNVRAMError + MOV r0, #0 MOV r1, #0 - BNE %FT20 ; Return zero on error LDRB r3, [sp, #0] ; Get the first byte into checksum MOV r1, r3, ASL #8 ; Store into result @@ -1494,18 +1619,17 @@ GetMachineAddressCMOS LDRB r2, [sp, #6] ; Get the checksum AND r3, r3, #&FF EOR r3, r3, #&FF - TEQ r2, r3 ; Check against the computed value - MOVNE r0, #0 ; Zero the MAC address on failure - MOVNE r1, #0 + ORR r1,r1,r2,LSL#16 ;put stored checksum in byte 2 + ORR r1,r1,r3,LSL#24 ;put calculated checksum in byte 3 +49 + EXIT -20 - EXIT +MachineAddressNVRAMError + MOV r0,#0 + MOV r1,#0 + EXIT -NVRAM_TAG_MACAddress - = "MACAddress", 0 -NVRAM_TAG_MACAddressChecksum - = "MACAddressChecksum", 0 - ] + ] ; OS_ReadSysInfo 5 ; diff --git a/s/PMF/i2cutils b/s/PMF/i2cutils index 6f3152ab..008479f9 100644 --- a/s/PMF/i2cutils +++ b/s/PMF/i2cutils @@ -51,6 +51,19 @@ E2ROMAddress2K_OTP * &60 ; 24C174 device - OTP section 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> + [ MaxI2Cspeed >= 1000 +I2Cticks * 1 + | + [ MaxI2Cspeed >= 400 +I2Cticks * 3 + | +I2Cticks * 10 + ] ] ; ***************************************************************************** @@ -118,7 +131,6 @@ SetC1C0 ROUT MOV R2, #IOC STRB R0, [R2, #IOCControl] - [ ClockNVMemoryFast [ :LNOT: :DEF: TestHarness MOV R0, #0 LDRB R0, [R0, #NVRamSpeed] @@ -127,9 +139,6 @@ SetC1C0 ROUT ] TEQ R0, #0 MOVEQ R0, #10 ; default value if speed not checked yet - | - MOV R0, #10 ; 5µs delay - ] BL DoMicroDelay [ No26bitCode @@ -245,7 +254,7 @@ Start ROUT MOV R1, #1 BL SetC1C0 - [ :LNOT: ClockNVMemoryFast + [ I2Cticks >= 10 ; Hold start condition for BMU MOV R2, #IOC @@ -525,6 +534,17 @@ WriteWithError ROUT MakeErrorBlock CoreNotWriteable +WriteWithoutProtection ; allowing write to "OTP" and protected section + Push "R0-R4, R14" + BL MangleCMOSAddress + Pull "R0-R4, PC", CS ; if invalid, then exit + MOV R2, R0 + MOV R3, R1 + CMP R0, #&10 + MOVLO R4, #&1000000 ; don't change checksum for OTP + BLO %FT10 + B %FT08 ; do change checksum for protected region + Write Push "R0-R4, R14" BL MangleCMOSAddress @@ -544,6 +564,7 @@ Write MOV R2, R0 MOV R3, R1 +08 [ ChecksumCMOS BL ReadStraight ; calculate new checksum : MOV R4, R0 @@ -1615,14 +1636,12 @@ InitCMOSCache ENTRY "r0-r6" ; Need to set the slowest speed so we can probe MOV R2, #0 - [ ClockNVMemoryFast MOV R3, #10 ; Default speed setting (5µs delays) [ :LNOT: :DEF: TestHarness STRB R3, [R2, #NVRamSpeed] | STRB R3, NVSpeed ] - ] ; First determine what hardware we've got fitted, R4 holds the number of ; 256 byte blocks that we've found @@ -1637,6 +1656,7 @@ InitCMOSCache ENTRY "r0-r6" | STRB R4, RTCFlag ] + MOV R3, #10 ; assume 100kHz to start with MOV R5, #4 ; assume 16 byte page size to start with MOV R6, #0 ; assume not protected @@ -1645,9 +1665,7 @@ InitCMOSCache ENTRY "r0-r6" MOV r0, #(E2ROMAddress2K+14) BL DummyAccess MOVVC R4, #8 - [ ClockNVMemoryFast MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - ] BVC %FT5 ; Have we got a 1K E² ? @@ -1672,9 +1690,7 @@ InitCMOSCache ENTRY "r0-r6" BL DummyAccess MOVVC R4, #64 MOVVC R5, #6 ; 64 byte page size - [ ClockNVMemoryFast MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - ] BVC %FT5 ; Have we got a 4K device? @@ -1685,9 +1701,7 @@ InitCMOSCache ENTRY "r0-r6" MOVVC R4, #16 MOVVC R6, #12 ; Only bottom 3K writable MOVVC R5, #5 ; 32 byte page size - [ ClockNVMemoryFast MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - ] BVC %FT5 ; Have we got an 8K device? @@ -1698,11 +1712,20 @@ InitCMOSCache ENTRY "r0-r6" MOVVC R4, #32 MOVVC R6, #24 ; Only bottom 6K writable MOVVC R5, #5 ; 32 byte page size - [ ClockNVMemoryFast MOVVC R3, #3 ; Fast speed setting (1.5µs delays) - ] + BVC %FT5 + +; Have we got a 32K device? - MOVVS R1, #RTCAddress + MOV r1, #E2ROMAddress32K + MOV r0, #E2ROMAddress32K + BL DummyAccess + MOVVC R4, #128 ; 128,120,6,1 + MOVVC R6, #120 ; Only bottom 30K writable + MOVVC R5, #6 ; 64 byte page size + MOVVC R3, #1 ; Hyper-fast speed setting (0.5µs delays - 1MHz part) + + MOVVS R1, #RTCAddress MOVVS R5, #8 ; 256 byte page size for CMOS 5 @@ -1714,17 +1737,17 @@ InitCMOSCache ENTRY "r0-r6" TEQ R6, #0 MOVEQ R6, R4 STRB R6, [R2, #NVRamWriteSize] - [ ClockNVMemoryFast + + CMP R3, #I2Cticks ; clamp speed to maximum bus speed + MOVLO R3, #I2Cticks STRB R3, [R2, #NVRamSpeed] - ] + LDR R3, =CMOSRAMCache | STRB R1, NVBase STRB R4, NVSize STRB R5, NVPageSize - [ ClockNVMemoryFast STRB R3, NVSpeed - ] ADR R3, i2cWorkSpace ] -- GitLab