From 87114d6dbd632747b0f5c92107b028c07fe17eac Mon Sep 17 00:00:00 2001 From: Kevin Bracey <kbracey@gitlab.riscosopen.org> Date: Thu, 8 Apr 1999 13:23:46 +0000 Subject: [PATCH] Parallel port flash upgrade facility added. Version 4.72. Tagged as 'Kernel-4_72' --- VersionASM | 10 +- VersionNum | 13 +- s/FlashROM | 672 +++++++++++++++++++++++++++++++++++++++++++++++++++++ s/GetAll | 10 + s/Morris | 46 +--- 5 files changed, 706 insertions(+), 45 deletions(-) create mode 100644 s/FlashROM diff --git a/VersionASM b/VersionASM index efac76a1..4427f5d5 100644 --- a/VersionASM +++ b/VersionASM @@ -5,8 +5,10 @@ GBLA Module_Version GBLS Module_MinorVersion GBLS Module_Date -Module_MajorVersion SETS "4.71" -Module_Version SETA 471 + GBLS Module_FullVersion +Module_MajorVersion SETS "4.72" +Module_Version SETA 472 Module_MinorVersion SETS "" -Module_Date SETS "25 Feb 1999" - END +Module_Date SETS "08 Apr 1999" +Module_FullVersion SETS "4.72" + END diff --git a/VersionNum b/VersionNum index de807252..d6362c11 100644 --- a/VersionNum +++ b/VersionNum @@ -1,14 +1,15 @@ -/* (4.71) +/* (4.72) * * This file is automatically maintained by srccommit, do not edit manually. * */ -#define Module_MajorVersion_CMHG 4.71 +#define Module_MajorVersion_CMHG 4.72 #define Module_MinorVersion_CMHG -#define Module_Date_CMHG 25 Feb 1999 +#define Module_Date_CMHG 08 Apr 1999 -#define Module_MajorVersion "4.71" -#define Module_Version 471 +#define Module_MajorVersion "4.72" +#define Module_Version 472 #define Module_MinorVersion "" -#define Module_Date "25 Feb 1999" +#define Module_Date "08 Apr 1999" +#define Module_FullVersion "4.72" diff --git a/s/FlashROM b/s/FlashROM new file mode 100644 index 00000000..981bb41f --- /dev/null +++ b/s/FlashROM @@ -0,0 +1,672 @@ +; Copyright 1999 Element 14 Ltd +; +; 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. +; +; This file handles the programming of flash devices in ROM bank 0 with +; a ROM image transferred via the parallel port. This is for development +; purposes only, and is only likely to work on the system for which it was +; designed. + +; Flash Memory Settings + +FR_FlashBase * &00000000 + +FR_DeviceBufferSize * 32 ; 28F640J5 has 32 byte buffer +FR_DeviceBlockSizeBits * 17 ; 28F640J5 has 128KB blocks +FR_DeviceBlocks * 64 ; 64 blocks in a 28F640J5 + +FR_BufferSize * FR_DeviceBufferSize*2 ; 2 devices +FR_BlockSizeBits * FR_DeviceBlockSizeBits+1 ; 2 devices +FR_BlockSize * 1 :SHL: FR_BlockSizeBits ; 256KB +FR_FlashSize * FR_BlockSize*FR_DeviceBlocks ; 16MB + +; Sizes of things in memory + +FR_StackSize * 1024 +FR_RAMCodeSize * 4096 +FR_ScreenSize * 472*1024 + +; Addresses of where we put things in memory + +FR_PageTableBaseAddr * DRAM0PhysRam +FR_StackBase * FR_PageTableBaseAddr+16*1024+FR_StackSize +FR_RAMCodeAddr * FR_StackBase +FR_ScreenBase * (FR_RAMCodeAddr+FR_RAMCodeSize+15):AND::NOT:&F +FR_TransferBuffAddr * FR_ScreenBase + +; Combo chip addresses +FR_ComboCfgBase * &03010000 + &3F0*4 +FR_PPortBase * &03010000 + &278*4 +FR_ECRPortBase * FR_PPortBase + &402*4 + + +; On entry, R11->IOMD +; Will either reprogram the flash, or branch back to 0. +; We're in SVC32 mode with the MMU off, by the way. + + ASSERT IOMD_C_FrontPanelButton <> 0 +ConsiderFlashROM + LDRB R0,[R11,#IOMD_CLINES] + TST R0,#IOMD_C_FrontPanelButton + MOVNE PC,#0 + +FlashROM +; Switch CPU to 32-bit mode + MOV R0,#MMUC_L :OR: MMUC_D :OR: MMUC_P ; Set PROG32 and DATA32 + ARM_write_control R0 + MOV R0,#I32_bit :OR: F32_bit :OR: SVC32_mode + msr AL,CPSR_all,R0 + +; Initialise various CPU control registers + MOV R0,#IOMD_ROMCR_NSTicks_5 :OR: IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit + STRB R0,[R11,#IOMD_ROMCR0] + MOV R0,#IOMD_CLKCTL_CpuclkHalf :OR: IOMD_CLKCTL_MemclkNormal :OR: IOMD_CLKCTL_IOclkNormal + STRB R0,[R11,#IOMD_CLKCTL] + MOV R0,#IOMD_DRAMWID_RASPre_3 :OR: IOMD_DRAMWID_RASCAS_3 :OR: IOMD_DRAMWID_EDO_Enable :OR: IOMD_DRAMWID_DRAM_32bit + STRB R0,[R11,#IOMD_DRAMWID] + MOV R0,#IOMD_IOTCR_Combo_TypeB :OR: IOMD_IOTCR_Network_TypeC + STRB R0,[R11,#IOMD_IOTCR] + MOV R0,#1 ; Card 0 type C, the rest type A + STRB R0,[R11,#IOMD_ECTCR] + MOV R0,#IOMD_ASTCR_WaitStates + STRB R0,[R11,#IOMD_ASTCR] + MOV R0,#IOMD_C_ReadMask :OR: IOMD_C_ROMCardVpp ; Green LED on + STRB R0,[R11,#IOMD_CLINES] + +; Main setup + MOV R10,#VIDC ; Keep R10 pointing to video registers from here on + BL FR_InitVideo + BL FR_FillScreen + BL FR_SetPageTable + BL FR_SetMMU + BL FR_InitParallel ; Sets R9 to parallel base address - keep it this way + +; Copy the rest of code to RAM and jump to it + ADR R0,FR_CopyBlockStart + LDR R1,=FR_RAMCodeAddr + MOV LR,R1 + LDR R2,=FR_RAMCodeEnd - FR_CopyBlockStart +01 LDR R3,[R0],#4 + STR R3,[R1],#4 + SUBS R2,R2,#4 + BNE %BT01 + MOV PC,LR + +FR_InitVideo ROUT +; Set DMA registers + LDR R1,=FR_ScreenBase + ADD R2,R1,#FR_ScreenSize + SUB R2,R2,#16 + STR R1,[R11,#IOMD_VIDSTART] + STR R2,[R11,#IOMD_VIDEND] + STR R1,[R11,#IOMD_VIDINIT] + STR R1,[R11,#IOMD_VIDCUR] + STR R1,[R11,#IOMD_CURSINIT] + STR R1,[R11,#IOMD_CURSCUR] + MOV R1,#0 + STR R1,[R11,#IOMD_VIDINITB] + MOV R1,#IOMD_VIDCR_DRAMMode :OR: IOMD_VIDCR_Enable + STRB R1,[R11,#IOMD_VIDCR] +; Set video registers + ADR R1,FR_InitVidRegs + MOV R2,#(FR_InitVidRegsEnd-FR_InitVidRegs) +02 LDR R3,[R1],#4 + STR R3,[R10] + SUBS R2,R2,#4 + BNE %BT02 +; Set grey palette + MOV R1,#&10000000 + STR R1,[R10] + MOV R1,#0 + MOV R2,#&000001 + ORR R2,R2,#&000100 + ORR R2,R2,#&010000 + MOV R3,#255 +03 STR R1,[R10] + ADD R1,R1,R2 + SUBS R3,R3,#1 + BNE %BT03 + MOV PC,LR + +; Frequency synthesizer register settings +FR_ModR * 8 +FR_ModV * 9 ; 36 MHz +; Video control register settings +FR_FIFO * 3 ; 12 loads +FR_BPP * 3 ; 8bpp +FR_PixelRate * 0 ; CK/1 +FR_ClockSource * 0 ; VCLK +; Horizontal timings +FR_HSync * 72 +FR_HBPch * 86 +FR_HLBdr * 24 +FR_HDisp * 800 +FR_HRBdr * 24 +FR_HFPch * 18 +FR_HDWR * FR_HDisp / 4 +; Vertical timings +FR_VSync * 2 +FR_VBPch * 22 +FR_VTBdr * 0 +FR_VDisp * 600 +FR_VBBdr * 0 +FR_VFPch * 1 + +FR_InitVidRegs ROUT + DCD &E0000000+(FR_FIFO:SHL:8)+(FR_BPP:SHL:5)+(FR_PixelRate:SHL:2)+FR_ClockSource + DCD &D0000000+&C288 + DCD &80000000+FR_HSync+FR_HLBdr+FR_HDisp+FR_HRBdr+FR_HFPch-8 + DCD &81000000+FR_HSync-8 + DCD &82000000+FR_HSync+FR_HBPch-12 + DCD &83000000+FR_HSync+FR_HBPch+FR_HLBdr-18 + DCD &84000000+FR_HSync+FR_HBPch+FR_HLBdr+FR_HDisp-18 + DCD &85000000+FR_HSync+FR_HBPch+FR_HLBdr+FR_HDisp+FR_HRBdr-12 + DCD &90000000+FR_VSync+FR_VBPch+FR_VTBdr+FR_VDisp+FR_VBBdr+FR_VFPch-2 + DCD &91000000+FR_VSync-2 + DCD &92000000+FR_VSync+FR_VBPch-1 + DCD &93000000+FR_VSync+FR_VBPch+FR_VTBdr-1 + DCD &94000000+FR_VSync+FR_VBPch+FR_VTBdr+FR_VDisp-1 + DCD &90000000+FR_VSync+FR_VBPch+FR_VTBdr+FR_VDisp+FR_VBBdr-1 + DCD &40008000 + DCD &C0000000+(1:SHL:12)+3 + DCD &D0000000+&C080+((FR_ModV-1):SHL:8)+(FR_ModR-1) + DCD &D0000000+((FR_ModV-1):SHL:8)+(FR_ModR-1) + DCD &F0000000+(1:SHL:16)+(1:SHL:12)+FR_HDWR + DCD &B1000000 +FR_InitVidRegsEnd + +FR_FillScreen ROUT + LDR R1,=FR_ScreenBase + MOV R2,#((256:SHL:16)/600):AND:&00FF + ORR R2,R2,#((256:SHL:16)/600):AND:&FF00 + MOV R3,R3 + MOV R4,#FR_VDisp +01 MOV R5,#FR_HDisp + MOV R0,R3,LSR #16 + ORR R0,R0,R0,LSL #8 + ORR R0,R0,R0,LSL #16 +02 STR R0,[R1],#4 + SUBS R5,R5,#4 + BNE %BT02 + ADD R3,R3,R2 + SUBS R4,R4,#1 + BNE %BT01 + MOV PC,LR + +;Make a page table that basically gives flat addressing with the C and B bits +;set approriately for the RAM areas. The RAM areas are set with both the C and B +;bits on, and all other areas have both C and B off. The flash area must not +;be made cacheable, or programming won't work. +;On exit +; r0-r4 corrupted +FR_SetPageTable ROUT + MOV R1,#FR_PageTableBaseAddr + MOV R2,#0 ; Address + MOV R4,#L1_U + L1_Section + ORR R4,R4,#AP_Full * L1_APMult +01 BICS R3,R2,#&E0000000 ; Repeats at &00000000, &20000000, &4000000, etc. + BICEQ R4,R4,#L1_C + L1_B ; Clear B and C bits from start of ROM area + CMP R3,#&10000000 + ORREQ R4,R4,#L1_C + L1_B ; Set B and C bits (RAM area cacheable and bufferable) + ORR R0,R3,R4 + STR R0,[R1],#4 + ADDS R2,R2,#1024*1024 + BCC %BT01 + MOV PC,LR + +FR_SetMMU ROUT + MOV R0,#FR_PageTableBaseAddr + ARM_MMU_transbase R0 + MVN R0,#0 ; Full access to all domains + ARM_MMU_domain R0 + MOV R0,#MMUC_L + MMUC_D + MMUC_P + MMUC_W + MMUC_C + MMUC_M + ARM_write_control R0 ; Enable write buffer, cache and MMU + MOV PC,LR + +FR_InitParallel ROUT + LDR R1,=FR_ComboCfgBase +; Enter config mode + MOV R0,#&55 + STRB R0,[R1] + STRB R0,[R1] +; Write CR0 + MOV R0,#0 + STRB R0,[R1] + MOV R0,#&22 + STRB R0,[R1,#4] ; CR0=&22 (FDC, IDE off) +; Write CR1 + MOV R0,#1 + STRB R0,[R1] + MOV R0,#&97 + STRB R0,[R1,#4] ; CR1=&97 (Parallel port on, extended) +; Write CR4 + MOV R0,#4 + STRB R0,[R1] + MOV R0,#&04 ; CR4=&03 (ECP & EPP mode) + STRB R0,[R1,#4] +; Write ECR + MOV R0,#&34 ; PS/2 Parallel Port mode, DMA off, interrupts off + LDR R9,=FR_ECRPortBase + STRB R0,[R9] +; Exit config mode + MOV R0,#&AA + STRB R0,[R1] +; Initialise parallel port + LDR R9,=FR_PPortBase +; Clear nSTROBE bit (puts nACK high) and clear nSLCTIN bit (puts BUSY high) to +; indicate we are busy and not accepting data. + MOV R0,#&20 ; Input, IRQ off, nSLCTIN clear, nSTROBE clear + STRB R0,[R9,#8] +; Keep parallel port base address in R9 from here on + MOV PC,LR + + LTORG + +FR_CopyBlockStart + +; Dont use literals from here on in - the assembler's liable to pull them +; the non-RAM stuff above. + +FR_StackBaseVal & FR_StackBase +FR_TransferBuffVal & FR_TransferBuffAddr + +; Code from here on gets copied to RAM (at FR_RAMCodeAddr) and run from there. + +FR_RAMCodeStart + MOV R0,#IOMD_C_ReadMask :OR: IOMD_C_FrontPanelLED :OR: IOMD_C_ROMCardVpp + STRB R0,[R11,#IOMD_CLINES] ; Red LED on + LDR R13,FR_StackBaseVal +FR_LoopForever + MOV R0,#FR_WaitCmdState-FR_BorderStateTable + BL FR_ShowStateBorder +; Wait for a command header + BL FR_ParallelRead + CMP R0,#'M' + BNE FR_LoopForever + BL FR_ParallelRead + CMP R0,#'P' + BNE FR_LoopForever + BL FR_ParallelRead + CMP R0,#'T' + BNE FR_LoopForever + BL FR_ParallelRead + CMP R0,#'!' + BNE FR_LoopForever + BL FR_ParallelRead + CMP R0,#'P' + BEQ FR_BeginProgram + CMP R0,#'V' + BEQ FR_BeginVerify + B FR_LoopForever + +FR_BeginProgram ROUT + MOV R0,#FR_BeginProgramState-FR_BorderStateTable + BL FR_ShowStateBorder +; Read in parameters + BL FR_ReadOffsetAndCount +; Ready to go - first make the ROM area writable + BL FR_MakeROM0Writable +01 +; Begin erasing the block + MOV R0,R7 + BL FR_StartErase +; Read the block data into the buffer + BL FR_ReadBlockIntoBuffer +; Data read in OK - wait for erase to finish + BL FR_CheckErase +; Now write block + MOV R0,#FR_WriteBlockState-FR_BorderStateTable + BL FR_ShowStateBorder + MOV R0,R7 + LDR R1,FR_TransferBuffVal + BL FR_DoWriteBlock +; Verify the block + BL FR_ResetToReadArray + MOV R0,#FR_VerifyBlockState-FR_BorderStateTable + BL FR_ShowStateBorder + MOV R0,R7 + LDR R1,FR_TransferBuffVal + BL FR_VerifyBlock +; Block done, on to the next + ADD R7,R7,#FR_BlockSize + SUBS R8,R8,#1 + BNE %BT01 +; All finished - make ROM area read-only + BL FR_MakeROM0ReadOnly + B FR_LoopForever + +FR_BeginVerify ROUT + MOV R0,#FR_BeginVerifyState-FR_BorderStateTable + BL FR_ShowStateBorder +; Read in parameters + BL FR_ReadOffsetAndCount +01 +; Read the block data into the buffer + BL FR_ReadBlockIntoBuffer +; Data read in OK - now verify + MOV R0,#FR_VerifyBlockState-FR_BorderStateTable + BL FR_ShowStateBorder + MOV R0,R7 + LDR R1,FR_TransferBuffVal + BL FR_VerifyBlock +; Block done, on to the next + ADD R7,R7,#FR_BlockSize + SUBS R8,R8,#1 + BNE %BT01 +; All done + B FR_LoopForever + +FR_ReadOffsetAndCount ROUT +;Called by the program and verify commands to read their parameters (offset +;and count) from the parallel port. +;On exit +; r7 = Initial offset in Flash ROM area +; r8 = Block count +; r0-r3 corrupted + STMFD R13!,{LR} +; Next incoming word is the block offset to start from + BL FR_ParallelReadWord + MOV R7,R0 +; Check the offset is valid + CMP R7,#FR_FlashSize + BHS FR_OffsetError + MOVS R0,R7,LSL#(32-FR_BlockSizeBits) ; The offset within the block should be 0 + BNE FR_OffsetError +; Next incoming byte is the number of blocks + BL FR_ParallelRead + MOVS R8,R0 + BEQ FR_BlockCountError + ADD R0,R7,R8,LSL #FR_BlockSizeBits + CMP R0,#FR_FlashSize + BHI FR_BlockCountError +; Turn the offset into a real address + ADD R7,R7,#FR_FlashBase + LDMFD R13!,{PC} + +FR_ReadBlockIntoBuffer ROUT +;Read a block of data from the parallel port into the transfer buffer +;Corrupts r0-r6 + STMFD R13!,{LR} + MOV R0,#FR_ReadBlockState-FR_BorderStateTable + BL FR_ShowStateBorder + MOV R6,#FR_BlockSize + LDR R5,FR_TransferBuffVal + MOV R4,#0 ; Checksum +01 BL FR_ParallelReadWord + STR R0,[R5],#4 + ADD R4,R4,R0 + SUBS R6,R6,#4 + BNE %BT01 +; Next word is the checksum + BL FR_ParallelReadWord + CMP R0,R4 + BNE FR_ChecksumError + LDMFD R13!,{PC} + +FR_ChecksumError ROUT + MOV R0,#FR_ChecksumErrorState-FR_BorderStateTable + B FR_Error +FR_OffsetError + MOV R0,#FR_OffsetErrorState-FR_BorderStateTable + B FR_Error +FR_BlockCountError + MOV R0,#FR_BlockCountErrorState-FR_BorderStateTable +FR_Error + BL FR_ShowStateBorder +; Wait for front panel button to be pressed +01 LDRB R0,[R11,#IOMD_CLINES] + TST R0,#IOMD_C_FrontPanelButton + BNE %BT01 +; Start again (note this also resets the stack pointer) + B FR_RAMCodeStart + +FR_ShowStateBorder + STMFD R13!,{R1} + ADR R1,FR_BorderStateTable + LDR R0,[R1,R0] + STR R0,[R10] + LDMFD R13!,{R1} + MOV PC,LR + +FR_BorderStateTable +FR_WaitCmdState DCD &40FF0000 ;Waiting for command - Blue +FR_BeginProgramState DCD &40808080 ;Begin Program command - Grey +FR_BeginVerifyState DCD &40404040 ;Begin Verify command - Dark grey +FR_ReadBlockState DCD &40FFFF00 ;Reading block - Cyan +FR_WriteBlockState DCD &4000FF00 ;Writing block - Green +FR_VerifyBlockState DCD &40FFFFFF ;Verifying block - White +FR_OffsetErrorState DCD &400000FF ;Offset error - Red +FR_BlockCountErrorState DCD &4000FFFF ;Block count error - Yellow +FR_ChecksumErrorState DCD &40FF00FF ;Checksum error - Magenta +FR_EraseErrorState DCD &40808000 ;Erase error - Dark Cyan +FR_VoltageRangeErrorState DCD &40000080 ;Voltage range error - Dark Red +FR_DeviceProtectErrorState DCD &40800000 ;Device protect error - Dark Blue +FR_ProgramErrorState DCD &40008080 ;Program error - Dark Yellow +FR_VerifyErrorState DCD &4000BBFF ;Verify error - Orange + +FR_ParallelRead ROUT +;Read a byte of data from the parallel port +;On entry +; r9 = Parallel port base address +;On exit +; r0 = byte read +; r1 corrupted +;Set nSLCTIN bit (puts BUSY low) and clear nSTROBE bit (puts nACK high), +;to indicate that we are ready to receive data + MOV R0,#&28 ; Input, IRQ off, BUSY low, nACK high + STRB R0,[R9,#8] +;Now wait until nACK bit (nSTROBE) goes low, meaning a byte is ready to be read +01 LDRB R0,[R9,#4] + TST R0,#&40 + BNE %BT01 +;Read the byte + LDRB R0,[R9] +;Set nSTROBE bit (puts nACK low) to indicate we read the byte, and +;clear nSLCTIN bit (puts BUSY high) to indicate we are busy and won't accept +;any more data + MOV R1,#&21 ; Input, IRQ off, BUSY high, nACK low + STRB R1,[R9,#8] +;Make sure nACK bit (nSTROBE) has returned high +02 LDRB R0,[R9,#4] + TST R1,#&40 + BEQ %BT02 +;Finish nAck pulse by clearing nSTROBE bit (puts nACK high). Keep BUSY high + MOV R1,#&20 ; Input, IRQ off, BUSY high, nACK high + STRB R1,[R9,#8] + MOV pc,lr + +FR_ParallelReadWord ROUT +;Read a word of data from the parallel port +;On entry +; r9 = Parallel port base address +;On exit +; r0 = word read +; r1-r3 corrupted + MOV R3,LR + BL FR_ParallelRead + MOV R2,R0 + BL FR_ParallelRead + ORR R2,R2,R0,LSL #8 + BL FR_ParallelRead + ORR R2,R2,R0,LSL #16 + BL FR_ParallelRead + ORR R0,R2,R0,LSL #24 + MOV PC,R3 + +FR_MakeROM0Writable + STMFD R13!,{R0} + LDRB R0,[R11,#IOMD_ROMCR0] + ORR R0,R0,#&80 + STRB R0,[R11,#IOMD_ROMCR0] + LDMFD R13!,{R0} + MOV PC,LR + +FR_MakeROM0ReadOnly + STMFD R13!,{R0} + LDRB R0,[R11,#IOMD_ROMCR0] + BIC R0,R0,#&80 + STRB R0,[R11,#IOMD_ROMCR0] + LDMFD R13!,{R0} + MOV PC,LR + +FR_ResetToReadArray ROUT +;Reset the flash devices to Read Array mode + STMFD R13!,{R0,R1} + MOV R0,#FR_FlashBase + MOV R1,#&FF + ORR R1,R1,R1,LSL #8 + STR R1,[R0] ; Write the Read Array command (&FF) to both devices + LDMFD R13,{R0,R1} + MOV PC,LR + +FR_StartErase ROUT +;Start to erase a block (256KB) of flash memory +;On entry +; r0=Block Address (real memory address) + STMFD R13!,{R1} + MOV R1,#&20 + ORR R1,R1,R1,LSL #8 + STR R1,[R0] ; Write the Block Erase command (&20) to both devices + MOV R1,#&D0 + ORR R1,R1,R1,LSL #8 + STR R1,[R0] ; Write the Confirm command (&D0) to both devices + LDMFD R13!,{R1} + MOV PC,LR + +FR_CheckErase ROUT +;Wait for erase to finish + STMFD R13!,{R0,R1} + MOV R0,#FR_FlashBase +01 LDR R1,[R0] ; Read the status register + TST R1,#&0080 ; Check even SR.7 + TSTNE R1,#&8000 ; Check odd SR.7 + BEQ %BT01 ; Repeat until both set + TST R1,#&0020 ; Check even SR.5 + TSTEQ R1,#&2000 ; Check odd SR.5 + BNE FR_ceEraseError + LDMFD R13!,{R0,R1} + MOV PC,LR +FR_ceEraseError + MOV R1,#&50 + ORR R1,R1,R1,LSL #8 + STR R1,[R0] ; Write Clear Status Register command (&50) to beth devices + BL FR_ResetToReadArray + BL FR_MakeROM0ReadOnly + LDMFD R13!,{R0,R1} + MOV R0,#FR_EraseErrorState-FR_BorderStateTable + B FR_Error + +FR_DoWriteBlock ROUT +;Writes a block (256KB) of data to flash memory +;On entry +; r0=Block Address (real memory address) +; r1=Pointer to data to write +;On exit +; r0,r1 have advanced by the block size (256KB) + STMFD R13!,{R2,R3,LR} + MOV R2,R1 + MOV R1,R0 + MOV R3,#FR_BlockSize +01 BL FR_DoWriteBuffer + SUBS R3,R3,#FR_BufferSize + BNE %BT01 + MOV R0,R1 + MOV R1,R2 + LDMFD R13!,{R2,R3,PC} + +FR_DoWriteBuffer ROUT +;Write a buffer full of data (64 bytes) to flash memory +;On entry +; r0=Block Address +; r1=Start Address +; r2=Pointer to data to write +;On exit +; r0 preserved +; r1,r2 have increased by 64 bytes + STMFD R13!,{R3,R4,LR} + MOV R3,#&E8 + ORR R3,R3,R3,LSL #8 +01 STR R3,[R0] ; Write the Write to Buffer command (&E8) to both devices + LDR R4,[R0] ; Read the XSR + TST R4,#&0080 ; Check even XSR.7 + TSTNE R4,#&8000 ; Check odd XSR.7 + BEQ %BT01 ; Repeat until both set + MOV R3,#(FR_DeviceBufferSize:SHR:1)-1 ; No. of (16-bit) words to write - 1 + ORR R3,R3,R3,LSL #8 + STR R3,[R0] ; Write the (16-bit) word count to both devices + MOV R3,#FR_BufferSize +02 LDR R4,[R2],#4 + STR R4,[R1],#4 ; Write a (16-bit) word of data to each device + SUBS R3,R3,#4 + BNE %BT02 + MOV R3,#&D0 + ORR R3,R3,R3,LSL #8 + STR R3,[R0] ; Write the Confirm command (&D0) to both devices +03 LDR R4,[R0] ; Read the status register + TST R4,#&0080 ; Check even SR.7 + TSTNE R4,#&8000 ; Check odd SR.7 + BEQ %BT03 ; Repeat until both set + TST R4,#&0008 ; Check even SR.3 + TSTEQ R4,#&0800 ; Check odd SR.3 + BNE FR_dwbfVoltageRangeError + TST R4,#&0002 ; Check even SR.1 + TSTEQ R4,#&0200 ; Check odd SR.1 + BNE FR_dwbfDeviceProtectError + TST R4,#&0010 ; Check even SR.4 + TSTEQ R4,#&1000 ; Check odd SR.4 + BNE FR_dwbfProgramError +; Programming completed successfully + LDMFD R13!,{R3,R4,PC} + +FR_dwbfVoltageRangeError + MOV R0,#FR_VoltageRangeErrorState-FR_BorderStateTable + B FR_dwbfErrorExit +FR_dwbfDeviceProtectError + MOV R0,#FR_DeviceProtectErrorState-FR_BorderStateTable + B FR_dwbfErrorExit +FR_dwbfProgramError + MOV R0,#FR_ProgramErrorState-FR_BorderStateTable +FR_dwbfErrorExit + MOV R3,#&50 + ORR R3,R3,R3,LSL #8 + MOV R4,#FR_FlashBase + STR R1,[R4] ; Write Clear Status Register command (&50) to beth devices + BL FR_ResetToReadArray + BL FR_MakeROM0ReadOnly + LDMFD R13!,{R3,R4,LR} + B FR_Error + +FR_VerifyBlock ROUT +;Compare a block (256KB) of data to flash memory +;On entry +; r0=Block Address (real memory address) +; r1=Pointer to block to compare +;On exit +; r0,r1 have advanced by the block size (256KB) + STMFD R13!,{R2-R4} + MOV R2,#FR_BlockSize +01 LDR R3,[R0],#4 + LDR R4,[R1],#4 + CMP R3,R4 + BNE FR_VerifyError + SUBS R2,R2,#4 + BNE %BT01 + LDMFD R13!,{R2-R4} + MOV PC,LR +FR_VerifyError + MOV R0,#FR_VerifyErrorState-FR_BorderStateTable + B FR_Error + +FR_RAMCodeEnd + + END diff --git a/s/GetAll b/s/GetAll index 04d4b5af..2811a852 100644 --- a/s/GetAll +++ b/s/GetAll @@ -217,6 +217,9 @@ IncludeTestSrc SETL {FALSE} :LAND: :LNOT: STB GBLL RO371Timings RO371Timings SETL :LNOT: STB +; For development on Customer M hardware only + GBLL ParallelFlashUpgrade +ParallelFlashUpgrade SETL {FALSE} [ :LNOT: RO371Timings @@ -484,6 +487,12 @@ ProcessorVectors SETL {TRUE} ; Processor vectors indirected t GetUnsqueeze SETS "GET s.Unsqueeze" | GetUnsqueeze SETS "" + ] + GBLS GetFlashROM + [ ParallelFlashUpgrade +GetFlashROM SETS "GET s.FlashROM" + | +GetFlashROM SETS "" ] GBLS GetPublicWS GBLS GetWorkspace @@ -630,6 +639,7 @@ largest_rma_size * (128*1024) ; and the ceiling for rma use GET s.Copro15ops ; some macros GET s.Kernel + $GetFlashROM GET s.NewIRQs GET s.Oscli GET s.SysComms diff --git a/s/Morris b/s/Morris index 94d04b9b..3e8350b6 100644 --- a/s/Morris +++ b/s/Morris @@ -20,7 +20,6 @@ MorrisHeaderCodeSize * (24*4) ;Code occupies less than this, we pad to this boundary so POST code ;has a nicely defined place for its romsize and code entry points - [ 1 = 1 ; VECTOR AREA: LDR pc, .+ResetIndirection @@ -44,43 +43,20 @@ MorrisHeaderCodeSize * (24*4) ;Code occupies less than this, we pad to this bo ; produced in 16-in-32 form by extracting hex values from a listing... DCD &0000B632, &0000E3A0 ; 20: MOV R11, #IO+IOMDREGS - point at IOMD - DCD &00000000, &0000E3A0 ; 24: MOV R0, #&0 - ROMCR:32b,slow,218.75us,no burst - DCD &00000080, &0000E5CB ; 28: STRB R0,[R11,#ROMCR0] - switch mode - DCD &0000F000, &0000E3A0 ; 2C: MOV PC, #0 - jump to 0 (this instr pre-fetched) + DCD &00000000, &0000E3A0 ; 28: MOV R0, #&0 - ROMCR:32b,slow,218.75us,no burst + DCD &00000080, &0000E5CB ; 30: STRB R0,[R11,#ROMCR0] - switch mode + [ :LNOT: ParallelFlashUpgrade + DCD &0000F000, &0000E3A0 ; 38: MOV PC, #0 - jump to 0 (this instr pre-fetched) | -; -; Kludged to cope with Morris Bugs -; - - ! 0,"<><><><><><><> This kernel version will not softload on a Risc PC <><><><><><><>" - - DCD &E3A0F010 - DCD &FFFFE3A0 - - DCD &E59FF034 - DCD &E59FF034 - - DCD &E59FF034 - DCD &E59FF034 - - DCD &E59FF034 - DCD &E59FF034 - - DCD &E3A0B632 - DCD &E3A0E3A0 ; 20: MOV R11, #IO+IOMDREGS - point at IOMD - - DCD &E3A00000 - DCD &E3A0E3A0 ; 24: MOV R0, #&0 - ROMCR:32b,slow,218.75us,no burst - - DCD &E5CB0080 - DCD &E3A0E5CB ; 28: STRB R0,[R11,#ROMCR0] - switch mode - - DCD &E59FF0F4 - DCD &E5CBE59F ; 2C: MOV PC, #0 - jump to 0 (this instr pre-fetched) +; At this point, we know that we're in an ARM 7500-based box with 32-bit ROMs that's +; just been powered up. These are the conditions under which we may wish to reprogram +; ourselves. +CFR_Offset * (ConsiderFlashROM - ROM - ((.-ROM)/2) - 8)/4 + DCD CFR_Offset :AND: &FFFF ; 38: B ConsiderFlashROM (this instr pre-fetched) + DCD &0000EA00 + (CFR_Offset:SHR:16) ] -; vector absolute targets for use from physical vector instructions - +; vector absolute targets for use from physical vector instructions UNDEF_VEC DCD UndInstInReset-ROM SWI_VEC DCD SWIInReset -ROM -- GitLab