; > TestSrc.Begin TTL RISC OS 2+ Power-On Self-Test ; ; Startup code for RISC OS ROM Self-Test. ; ; Performs ROM test patterns, determines test strategy and enters ; external or internal test code. ; ; A minimal set of opcodes should be used (ideally, only B, LDR and ADDS) ; so that a processor test may be validly included in the internal test ; sequence. ; ;------------------------------------------------------------------------ ; History ; ; Date Name Rel Comment ; ---- ---- --- ------- ; 23-Feb-93 ArtG 2.00 Experimental ARM 600 / Jordan mods ; 20-Oct-93 ARTG 2.02 Changed to new conditional assembly scheme ; 18-Nov-94 RCM 2.05 Morris changes ; 15-May-96 BAR 2.06 Update for ARM7500FE variant, new IOMD ID ; Code. Used initially in the NC product; ; needs different prescalers and ROM speed ; settings, switched on IOMD ID code. ; 30-May-96 BAR 2.07 Add code to flash NC's led's. Ignore morse ; code and just use the simplified flash ; sequence. ; 14-Jun-96 BAR 2.08 Add get call for initmodule file. ; 17-Jun-96 BAR 2.09 Change speed settings for the second bank of ; ROM space. ; 24-Jun-96 BAR 2.10 Updated second check on IOMD ID, instead of ; checking for ARM7500 IOMD ID code to skip ; the Virq test, now checks for the original ; (RiscPC) IOMD ID code and skips Virq test if ; not equal. Thus ARM7500 and ARM7500FE ; devices don't execute the test. ; Updated version number. ; Added call to sir_IOMD_Regs -show iomd registers ; 08-Jul-96 BAR 2.11 Ensure r0 is cleared before checking IOMD vsn no. ; Change ROM Burst speed from93.75nS to 125nS. ; 09-Jul-96 Make IOMD ID code more efficent. Change ; variables used for ROMCR Values and remove ; 'NormalSpeed' ROMs compiler switching code - ; no longer supporting PSwindell. ; Change non-7500FE ROM Burst speed from 3 ticks ; to 4 ticks ; 25-Jul-96 BAR 2.12 Add code to handle EEPROM as well as CMOS ; RAM. Code supplied by J.Harris. ; 29-Jul-96 BAR 2.13 Update LED stuff to wait properly. ; 29-Jul-96 BAR 2.14 Update exit codes IOMD et all. ; More work on the LED code. ; 30-Jul-96 BAR 2.15 Humm, get the LED's to work ! ; 16-Aug-96 JRH 2.16 Add check for OS image in 2nd ROM bank. ; Don't program the 2nd ROM bank speed (ROMCR1), ; unless CanLiveInROMCard is True, in which case ; check whether we're running from the 2nd bank. ; Made display of IOMD regs conditional on new ; ShowIOMDRegs flag, which is set to TRUE ; 05-Sep-96 BAR 2.17 Updated to NOT show the progress colours on ; the screen unless a POST box is added when ; they will be shown. This is in accordance ; with fault report ANC-00159. The final red ; fail screen will be maintained as this ; enfoces the fact the the POSt has failed and ; that the ser needs to attend to the unit. ; The compile switch DontShowProgressColours ; can be set to FALSE, then the progress ; colours will always be shown. ; 07-Oct-96 JRH 2.18 Changed ExtIO to fix support for speaking to ; the test box when running from the 2nd ROM bank, ; conditioned on CanLiveOnROMCard. ; 22-Oct-96 JRH 2.19 Added an Align64 at the end of the file because ; OS_Find was sometimes failing. Don't know why. ; Fixed bug introduced in 2.18 which turned burst ; off on ROMCR0. ; 08 Nov 96 BAR 2.20 Add kluge to skip ram (long) test ; altogether, 'cos it appears to be crashing. ; amg: Renaissance merge. 7500FE unconditional, other changes now conditioned ; on STB being {TRUE}. Extra declarations left unconditional. ; 10 Mar 97 BAR 2.21 Add code to check 1K of NVRAM - if reqd. ; 13 Mar 97 BAR 2.22 Change conditional assemble flags for ; including new LED flashing routines. Now ; checks for Left & Right LED flags. ; Always use the VGA VIDC Definition Table if ; the flag ChrontelSupport is TRUE. ; 18 Mar 97 BAR 2.23 Added C_DEFAULT (Black) Change use of ; C_WARMSTART to C_DEFAULT. ; 12 Jun 97 BAR 2.24 Ensure LED is set to RED before flashing ; them - gets the sequence right. If flashed ; ensure that BOTH are turned back on. ; 19 Jun 97 BAR 2.25 Remove un-necessary mov r13,r14's ; When completed flashing LED's restore the ; faultcode flag from fiq_regs. ; 04 Apr 00 KJB 2.30 Converted to run in 32-bit mode always. ; ShowIOMDRegs set to FALSE (request from ; Tom Clay) ; ;------------------------------------------------------------------------ ; ; TS_STATUS should be one of : ; ; 'R' RISC OS POST ; 'S' Standalone version (with a2 memory test instead of RISCOS) ; 'T' Test build - development only ; TS_STATUS * "R" ; Medusa POST version 2.0x ; TS_RELEASE * 23 TS_CHANGES * 0 GBLL POSTenabled POSTenabled SETL {TRUE} ; don't permit POST for ordinary startup GBLL AlwaysShortPOST AlwaysShortPOST SETL {TRUE} :LAND: STB ; always do a short POST GBLL ShowIOMDRegs ShowIOMDRegs SETL (IO_Type = "IOMD") :LAND: {FALSE} :LAND: STB ; show IOMD regs GBLL DontShowProgressColours DontShowProgressColours SETL {TRUE} :LAND: STB ; Do not show the progress colour screens. ; Progress Colours will always be shown when using POST Box. ; Set to true for NC - Fault Report ANC-00159. GBLL DontDoCMOSTest DontDoCMOSTest SETL {TRUE} :LAND: STB ts_Rom_bits * 21 ; Widest ROM address ts_Rom_length * 1 :SHL: ts_Rom_bits ; Longest ROM ts_highaddr_bit * 1 :SHL: 25 ; ARM address width ts_Alias_bits * (1 :SHL: 23) ; I/F output bits ts_recover_time * (1 :SHL: 8) ; inter-twiddle delay ts_pause_time * 200 ; Display pause time ts_S5_base * &3350000 ; IO register base address ts_IOEB_ID * (ts_S5_base + &50) ; IOE_B ASIC identification ts_IOEB_ident * &5 ; the value found there ts_PCaddress * &3010000 ; PC IO world base address ts_ReadyByte_00 * &90 ; signal 'Here I am' to ExtIO ts_BBRAM * &A0 ; IIC address of clock/ram chip [ STB ts_BBE2 * &A8 ; IIC address of E2ROM chip ts_BB2KE2 * &E0 ; IIC address of 2K E2ROM chip ] ts_RamChunk * &2000 ; gap between data line tests ts_MaxRamTest * 4*1024*1024 ; Max. DRAM tested on normal reset ts_VIDCPhys * &3400000 ; Real location of VIDC ; ; Border colours used for self-test indicators ; [ VIDC_Type = "VIDC1a" C_ARMOK * &40000000+&70C ; testing ROM C_RAMTEST * &40000000+&C70 ; testing RAM C_FAULT * &40000000+&00F ; failed tests C_PASSED * &40000000+&7C0 ; all passed C_WARMSTART * &40000000+&777 ; not tested C_DEFAULT * &40000000+&000 ; default (Black) ] [ VIDC_Type = "VIDC20" C_2NDBANK * &40000000+&C00070 ; jumping to image in 2nd ROM bank (Dark blue) C_ARMOK * &40000000+&7000C0 ; testing ROM (Magenta) C_RAMTEST * &40000000+&C07000 ; testing RAM (Blue) C_FAULT * &40000000+&0000F0 ; failed tests(Red) C_PASSED * &40000000+&70C000 ; all passed (Green) C_WARMSTART * &40000000+&707070 ; not tested (Mid grey) C_DEFAULT * &40000000+&000000 ; default (Black) ] ; ; ; Responses to external commands ; ; ErrorCmd * &00FF ; ; Control bitmasks used to indicate results of test to RISCOS ; R_SOFT * 0 ; not a power-on reset R_HARD * 1 ; Self-test run due to POR R_EXTERN * 2 ; external tests performed R_TESTED * 4 ; Self-test run due to test link R_MEMORY * 8 ; Memory has been tested R_ARM3 * &10 ; ARM 3 fitted R_MEMSKIP * &20 ; long memory test disabled R_IOEB * &40 ; PC-style IO controller (A5000) R_IOMD * &40 ; PC-style IO controller (RiscPC, ARM7500) R_VRAM * &80 ; VRAM present R_STATUS * &1ff ; bits that aren't a fault R_CHKFAILBIT * &100 ; CMOS contents failed checksum R_ROMFAILBIT * &200 ; ROM failed checksum R_CAMFAILBIT * &400 ; CAM failed R_PROFAILBIT * &800 ; MEMC protection failed R_IOCFAILBIT * &1000 ; IOC register test failed R_INTFAILBIT * &2000 ; Cannot clear interrupts R_VIDFAILBIT * &4000 ; VIDC flyback failure R_SNDFAILBIT * &8000 ; Sound DMA failure R_CMSFAILBIT * &10000 ; CMOS unreadable R_LINFAILBIT * &20000 ; Page zero RAM failure R_MEMFAILBIT * &40000 ; Main RAM test failure R_CACFAILBIT * &80000 ; ARM 3 Cache test failure ; [ MorrisSupport Kludge * 96 | Kludge * 0 ] SUBT Exception vectors ; ; These vectors are available for use while the Rom is mapped into ; low memory addresses. The Reset vector will be copied to low RAM ; as part of a software reset sequence : therefore it must perform ; a fixed operation to ensure compatibility with future versions ; of RISC-OS. ; Reset ts_start $DoMorrisROMHeader [ :LNOT: MorrisSupport [ ResetIndirected LDR pc,.+ResetIndirection ; load pc from vector at &118 | B ts_RomPatt + PhysROM ; Jump to normal ROM space ] ] 01 & ts_Rom_length ; gets patched by ROM builder 02 & (ts_ROM_cvectors - ROM) ; pointer to code vector table 03 & (ts_ROM_dvectors - ROM) ; pointer to data vector table 04 & (ts_ROM_bvectors - ROM) ; pointer to branch table B Reset ; not currently used B Reset B Reset ts_ROMSIZE * %BT01 - ts_start ts_CVECTORS * %BT02 - ts_start ts_DVECTORS * %BT03 - ts_start ts_BVECTORS * %BT04 - ts_start ! 0, "ts_Rom_length held at ":CC::STR:(%BT01 - ROM) ; ; Selftest version ID ; 00 ASSERT %B00 <= (ts_start + &2c + Kludge) % ((ts_start + &2c + Kludge) - %B00) ts_ID & ((TS_STATUS :SHL: 24) + (TS_RELEASE :SHL: 16) + TS_CHANGES) ts_ID_text ts_himsg = "SELFTEST" ; **DISPLAY_TEXT** = &89 ; Cursor position = TS_STATUS = ("0" + (TS_RELEASE / 10)) = "." = ("0" + (TS_RELEASE :MOD: 10)) = ("0" + (TS_CHANGES :MOD: 10)) = 0 ALIGN ; ; These vector tables permit access by the external (or downloaded) test ; software to data and code in the POST modules. ; Find the start of these tables through the 2nd and 3rd vectors at ; the start of the ROM. ; ts_ROM_dvectors 01 & ts_ID ; Selftest identification number 02 & (ts_ID_text - ROM) ; Selftest identification text ts_ROM_cvectors & ts_RomPatt & ts_User_startup & ts_Self_test_startup & ts_Dealer_startup & ts_Forced_startup & ts_GetCommand & ts_Softstart & ts_Hardstart ; ; ROM branch vectors - intended primarily so downloaded programs ; may use standard subroutines. This table should be in a fixed place. ; 00 ASSERT %B00 <= (ts_start + 128 + Kludge) % ((ts_start + 128 + Kludge) - %B00) ts_ROM_bvectors B ts_RomPatt B ts_GetCommand B ts_SendByte B ts_SendWord B ts_GetByte B ts_GetWord B ts_SendText B ts_MoreText B ts_SendLCDCmd ; ; Pad out until the location of the ResetIndirection vector ; ASSERT .-ROM <= ResetIndirection % ResetIndirection-(.-ROM) & ts_RomPatt-ROM+PhysROM ; ; ROM test code ; ; Note : the register order in ADDS ...pc.. is often critical. ; If we want to adjust pc, use ADDS pc,rn,pc so that the PSR is ; rewritten with it's original value. ; If we want to do some pc-relative arithmetic, use ADDS rn,pc,rn ; so that the bits from PSR are NOT used in the address calculation. ; SUBT Macros MACRO MODE $mode_bits MSR CPSR_c,#I32_bit :OR: F32_bit :OR: $mode_bits MEND MACRO MOV_fiq $dest,$src MODE FIQ32_mode MOV $dest,$src MODE SVC32_mode MEND MACRO FAULT $code MODE FIQ32_mode ORR r12_fiq,r12_fiq,$code MODE SVC32_mode MEND ; ; Define an area of storage with the required set of data bus patterns ; These are used both for testing the complete width of the data bus ; during ROM pattern testing, and will provide a tidy set of patterns ; if the reset is held, while the ARM increments addresses. ; SUBT ROM Address and Data Patterns DataPatterns GBLA dmask dmask SETA &80000000 DCD &FFFFFFFF ; first two : all set DCD &0 ; all clear GBLA OldOpt ; don't list all the walking OldOpt SETA {OPT} ; patterns OPT OptNoList WHILE dmask > 0 ; then for each bit DCD &$dmask ; set it DCD :NOT: &$dmask ; and clear it dmask SETA dmask :SHR: 1 WEND OPT OldOpt DEnd OPT OptList ; ; ; Read the ROM at a series of addresses ; such that : a) all the address lines are exercised individually ; b) all the data lines are exercised individually ; ; Data and address lines are exercised as walking-0 and walking-1. ; The test is performed as a series of LDR operations to avoid using ; a larger instruction set. ; ts_RomPatt ROUT ; Patterns which will exercise most of the data bus. ; All are arbitrary instructions with NV execution DCD &F0000000 ; walking 1 OldOpt SETA {OPT} ; patterns OPT OptNoList dmask SETA &08000000 WHILE dmask > 0 DCD dmask :OR: &F0000000 dmask SETA dmask :SHR: 1 WEND DCD &FFFFFFFF ; walking 0 dmask SETA &08000000 WHILE dmask > 0 DCD (:NOT: dmask) :OR: &F0000000 dmask SETA dmask :SHR: 1 WEND OPT OldOpt ; Now some proper code : ; Initialise address pointer and make MemC safe LDR r0,%01 ADD pc,r0,pc 01 & 0 ; useful constant [ IO_Type = "IOC-A1" ;;!! unsafe if we execute ROM at zero LDR r1,%02 ADD pc,r0,pc 02 ;;!! This remaps MEMC's ROM & &E000C :OR: MEMCADR ;;!! addressing if it hasn't STR r1,[r1] ;;!! already happened. ] LDR r5,%03 ; Load r5 with a constant which ADD pc,r0,pc ; may be added to ROM plus a 03 ; walking-zero bitmask to create & ts_Rom_length - 3 ; a valid word address in ROM. LDR r2,%04 ; Offset from ROM start to here ADD pc,r0,pc 04 & ROM - pcfromstart ADD r2,pc,r2 ; pointer to start of ROM ADD r3,r2,r0 ; pointer to start of ROM pcfromstart ADD r4,r2,r0 ; pointer to start of ROM ; assembly-time loop - only 32 iterations required OldOpt SETA {OPT} GBLA doffset doffset SETA DataPatterns WHILE doffset < DEnd LDR r0,doffset ; walking 1 data pattern LDR r1,doffset+4 ; walking 0 data pattern LDR r6,[r2] ; walking 1 address pattern LDR r6,[r3] ; walking 0 address pattern [ (doffset - DataPatterns) > ((32 - ts_Rom_bits) * 8) [ (doffset - DataPatterns) < (31 * 8) ADD r2,r4,r0 ; r2 = ROM + walking 1 pattern ADD r3,r4,r1 ; r3 = ROM + walking 0 pattern ADD r3,r3,r5 ; adjust to a valid address ] ] OPT OptNoList doffset SETA doffset + 8 WEND ASSERT (. - doffset < 4095) ; in range without barrel shift ? OPT OldOpt [ EmulatorSupport ARM_on_emulator r0 ; we skip the rest of POST if BEQ CONT ; on the emulator ] ; ; External interface drivers - ; provides entry points to send byte- and word- and string-sized objects ; and to receive byte- and word-sized objects ; ; Continue into GetCommand, which determines adapter type (or no adapter) ; and jumps to an ExtCmd handler, ts_User_startup, ts_Forced_startup or ; ts_Dealer_startup as appropriate. ; B ts_GetCommand ; (This instruction redundant 'cos ts_GetCommand ; is the first thing defined in TestSrc.ExtIO) GET TestSrc.ExtIO ; ; External command handlers - respond to commands given through the ; external test interface. ; GET TestSrc.ExtCmd SUBT Selftest ; ; There is no attached test interface. Is this a power-on reset ? ; Addressing IOC will make MEMC1a remap the ROM to high memory if ; it hasn't already done it, so be careful to ensure that the ; ARM is addressing normally-addressed ROM when this code runs. ; ts_User_startup ROUT LDR r0,%01 ADD pc,r0,pc 01 & 0 ; ; IOMD will only access the ROM until a write to IOMD has been made - ; make this write also switch on refresh so the DRAM has a chance to ; get running before the memory test starts. ; [ MEMC_Type = "IOMD" LDR r1,%02 ADD pc,r0,pc 02 & (IOMD_Base+IOMD_VREFCR) LDR r2,%03 ADD pc,r0,pc 03 & IOMD_VREFCR_REF_16 STR r2, [r1,#0] ] [ POSTenabled LDR r1,%12 ; load address of IOC IRQ register ADD pc,r0,pc 12 & IOC+IOCIRQSTAA LDR r1, [r1,#0] ; Get IRQSTAA register (hence POR bit) LDR r2, %13 ADD pc,r0,pc ; Constant to shift por to bit 31 13 & por_bit :SHL: 1 14 ADD r1,r1,r1 ADDS r2,r2,r2 BCC %14 ; loop until por_bit is at bit 31 ADDS r1,r1,r1 ; then shift it into carry BCC ts_Self_test_end ; POR bit clear - do soft reset. ; it's a power-on reset, so assume we can't be in 32-bit mode for ARM 6/7 MOV_fiq r12_fiq, #R_HARD B ts_Self_test_startup | B CONT ; if user POST disabled ] ; ; Perform self - tests ; ; Any distinction between test operation for Power-up, Display-only ; and Forced tests needs to be made between these three entry points. ; ; This is where tests start if a dumb test link is fitted ; (a diode from A21 to *ROMCS, disabling the ROMs when A21 is high) ts_Forced_startup ROUT MOV_fiq r12_fiq, #R_TESTED B ts_Self_test_startup ; This is where the tests start if an external display adapter is fitted ts_Dealer_startup ROUT MOV_fiq r12_fiq, #R_EXTERN LDR r4,%FT02 ; make a pointer to signon string 01 ADD r4,pc,r4 ADD pc,r0,pc 02 & (ts_himsg - %BT01 - 8) ADD r14,pc,r0 ; make a return address for this 'call' ASSERT (.+4 = ts_Self_test_startup) ; PC must point there already ! B ts_SendText ts_Self_test_startup ROUT ; This is where the power-on test starts (every user gets this) ; ; Processor test would go here .... if there was one. ; [ MorrisSupport ; ; On startup Morris defaults to dividing all its clocks by two and ; accessing ROM at the slowest possible access speed. So check for ; Morris and set to sensible values. ; ; check for te veriosn of IOMD, only need to determin between variants in ; the ARM7500 and ARM7500FE - condional code assembly excludes non-ARM7500 ; devices. MOV r2, #IOMD_Base ; r2 points to the IOMD base address defiend in HDR:IO.IOMDL LDRB r1,[r2,#IOMD_ID1] ; load r1 with IOMD ID high byte LDRB r0,[r2,#IOMD_ID0] ; load r0 with IOMD ID low byte ORR r0,r0,r1,LSL#8 ; Or r0 and r1, shifted left 8, put in r0 LDR r1,=ts_IOMD_ID2 ; get Ref IOMD ID code #2 CMPS r0,r1 ; check for IOMD ID Code #2 BEQ %FT05 ; If equal, got to 05 LDRNE r1,=ts_IOMD_ID3 ; If not ID1, get ID code #3 CMPNES r0,r1 ; If not ID1, check for IOMD ID Code #3 BNE %FT10 ; Not equal; not an ARM7500 or an ARM7500FE - skip [ RO371Timings 05 MOV r0, #0 ;Calling from POST BL TimeCPU ;just sets things according to assumed bus speeds for each IOMD id, in this case | ; else if not RO371Timings ; Here because its an ARM7500 'FE' variant ; Program the CPU, Memory and IO clock prescalers ; Set the prescalers to :- ; CPUCLK divide by 2 unless FECPUSpeedNormal set ; MEMCLK divide by 1 ; IOCLK divide by 1 ; [ FECPUSpeedNormal MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal | MOV r0, #IOMD_CLKCTL_CpuclkHalf + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal ] STRB r0, [r2, #IOMD_CLKCTL] ; initialise all the prescalers. ; ; Set ROM speed, take care to preserve 16-bit mode bit... ; ; According to BSiddle on the 15-May-96, Omega will use burst mode roms: use 93nS burst, 156nS initial. ; According to TDbson on the 09-Jul-96, Omega will handle ROMS up to 120nS and 70nS. ; Thus the ROM speed should be initilised to :- ; Half Speed or H bit, clear, which is ON ! : Half the delays, thus DOUBLE all clock ticks. ; Non-Sequental delay : 10 Ticks : Half speed on, so select 5 ticks (5*2) ; Burst delay : 8 Ticks : Half speed on, so select 4 ticks (4*2) ; Remember the Memory clock on Omega is faster than on previous porducts. ; The fast flash devices used for Omega testing should be able to cope even ; though they aren't burst devices. LDRB r0, [r2, #IOMD_ROMCR0] ; Get contents of ROMCR0 in to r0 AND r0, r0, #&40 ; clear all but the 16-bit mode flag [ ROMSpeedNormal ORR r0, r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks | ORR r0, r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks ] STRB r0, [r2, #IOMD_ROMCR0] ; Prog. the reg.s [ CanLiveOnROMCard TST pc, #ts_RC_2ndbank ; Not running out of 2nd ROM bank? ; Don't know what's in the 2nd bank -> program it to a slow default [ ExtROMis16bit [ ROMSpeedNormal MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff | MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff ] | [ ROMSpeedNormal MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff | MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff ] ] STRB r0, [r2, #IOMD_ROMCR1] ; Otherwise program it the same ] B %FT10 ; 05 ; Here because its an ARM7500 variant - NON 'FE' device. ; Program the CPU, Memory and IO clock prescalers ; Set the prescalers to :- ; CPUCLK divide by 1 ; MEMCLK divide by 1 ; IOCLK divide by 1 ; MOV r0, #IOMD_CLKCTL_CpuclkNormal + IOMD_CLKCTL_MemclkNormal + IOMD_CLKCTL_IOclkNormal STRB r0, [r2, #IOMD_CLKCTL] ; initialise all prescalers to div1 ; ; Set ROM speed, take care to preserve 16-bit mode bit... ; ; According to RJKing on 6/5/94, Kryten will use burst mode roms: use 93nS burst, 156nS initial. ; According to BSiddle on 09-Jul-96 - Omega will need to set the burst speed to 4 ticks from 3 ticks. ; Thus the ROM speed should be initilised to :- ; Half Speed or H bit, Set, which is OFF ! : Don't half the delays. ; Non-Sequental delay : 5 Ticks : Half speed off, so select 5 ticks ; Burst delay : 4 Ticks : Half speed off, so select 4 ticks ; The fast EPROMS used for Kryten testing should be able to cope even though ; they aren't burst devices LDRB r0, [r2, #IOMD_ROMCR0] ; Get contents of ROMCR0 in to r0 AND r0, r0, #&40 ; clear all but the 16-bit mode flag [ ROMSpeedNormal ORR r0, r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks | ORR r0, r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_NSTicks_$ROMSpeedNSTicks :OR: IOMD_ROMCR_BTicks_$ROMSpeedBurstTicks ] STRB r0, [r2, #IOMD_ROMCR0] ; Prog. the reg.s [ CanLiveOnROMCard TST pc, #ts_RC_2ndbank ; Not running out of 2nd ROM bank? ; Don't know what's in the 2nd bank -> program it to a slow default [ ExtROMis16bit [ ROMSpeedNormal MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff | MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_16bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff ] | [ ROMSpeedNormal MOVEQ r0, #IOMD_ROMCR_Normal :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff | MOVEQ r0, #IOMD_ROMCR_HalfSpeed :OR: IOMD_ROMCR_32bit :OR: IOMD_ROMCR_NSTicks_7 :OR: IOMD_ROMCR_BurstOff ] ] STRB r0, [r2, #IOMD_ROMCR1] ; Otherwise program it the same ] ] ;RO371Timings conditional ; 10 ] ; ; From this point on we assume we can safely use all the processor ; ; Initialise VIDC ; ts_InitVIDC [ IO_Type = "IOMD" ; If POSTbox fitted, ROM may still be mapped everywhere ; Using IOMD MOV r2,#IOMD_Base MOV r0, #IOMD_VREFCR_REF_16 ; switch on DRAM refresh STR r0, [r2, #IOMD_VREFCR] MOV r1,#ts_VIDCPhys [ ChrontelSupport ; We have a Chrontel chip ... thus always set for VGA. ADRL r2,TestVVIDCTAB | ; NOT ChrontelSupport ; We don't have a Chrontel chip ; ... thus check MonitorType and select table as reqd. ADRL r2,TestVIDCTAB LDR r0,=IOMD_MonitorType LDR r0,[r0] ANDS r0,r0,#IOMD_MonitorIDMask ADDEQ r2,r2,#(TestVVIDCTAB-TestVIDCTAB) ] ; Endif - ChrontelSupport | ; not IOMD MOV r1,#ts_VIDCPhys ADRL r2,TestVIDCTAB ] ; Endif - IO_Type = "IOMD" 10 LDR r0, [r2],#4 CMP r0, #-1 STRNE r0, [r1] BNE %BT10 ; ; Test for presence of OS image in 2nd ROM bank and jump to it ; GBLS DoROMCardThings [ ROMCardSupport :LOR: CanLiveOnROMCard DoROMCardThings SETS "GET TestSrc.ROMCard" | DoROMCardThings SETS "" ] $DoROMCardThings ; ; Set purple screen ; [ DontShowProgressColours MOV_fiq r0,r12_fiq ; restore the faultcode bits ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, ; NE : Adaptor fitted, show progress. ; EQ : No Adaptor fitted, don't show progress BEQ ts_RomTest ; EQ : Don't show colours ] MOV r1, #ts_VIDCPhys [ :LNOT: StrongARM_POST ;skip POST for StrongARM or ARM8 ARM_read_ID r0 AND r0,r0,#&F000 CMP r0,#&A000 ;if we are a StrongARM... CMPNE r0,#&8000 ;or an ARM8... LDREQ r0,=C_WARMSTART ;the colour that indicates no POST performed STREQ r0,[r1] BEQ ts_Hardstart ;RISC OS - right now! ] [ ARM810support :LAND: (:LNOT: ARM810_POST) ;just too horrible to fix POST for ARM 8 at the moment ARM_read_ID r0 AND r0,r0,#&F000 CMP r0,#&8000 ;if we are an ARM 8 LDREQ r0,=C_WARMSTART ;the colour that indicates no POST performed STREQ r0,[r1] BEQ ts_Hardstart ;RISC OS - right now! ] LDR r0, =C_ARMOK ; set initial screen colour STR r0, [r1] B ts_RomTest LTORG ROUT ; ; Calculate ROM checksum : display status and calculated checksum. ; 1 = "ROM :",0 2 = "ROM bad",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 3 = "ROM size",&8A,&ff,&ff,&ff,&ff,&ff,&ff,0 ALIGN ts_RomTest ADR r4,%BT1 BL ts_SendText BL ts_ROM_checksum BEQ %20 ADR r4,%BT2 ; Failed message FAULT #R_ROMFAILBIT ; set ROM bit in r12_fiq MOV r8,r0 ; calculated checksum BL ts_SendText BL ts_ROM_alias ; Checksum failed :- ADR r4,%BT3 ; hunt for first alias MOV r8,r0, LSL #8 BL ts_SendText ; and report it. 20 [ IO_Type = "IOC-A1" ; Don't use RISC OS MemSize ; until much later - it sets up ; the ARM600 MMU as well. B ts_MEMCset ; ; Do MEMC setup and memory size determination (the first time). ; LTORG ROUT 1 = "M Size :",0 2 = "M Size",&89,&ff,&ff,&ff,&ff,".",&ff,&ff,0 ALIGN ts_MEMCset MOV r12,#0 ADR r4,%BT1 BL ts_SendText LDR r1,=(&E000C :OR: MEMCADR) ; MemSize expects 32k page STR r1,[r1] BL MemSize ; ; MemSize returns with r0 = page size (now in bytes, *NOT* in MEMC control patterns), ; r1 = memory size (in bytes) ; r2 = MEMC control value ; ; Translate these into a number that looks like : ; ; mmmm.pp ; ; where mmmm is memory size in hex Kbytes, pp is page size in hex Kbytes. ; MODE FIQ32_mode ; Save memory size and MOV r11_fiq,r2 ; MEMC setup value for MOV r10_fiq,r1 ; later use MODE SVC32_mode MOV r8, r0, LSR #2 ; MemSize now returns actual page size in r0 ADD r8,r8,r1,LSL #6 ADR r4,%BT2 BL ts_SendText ] ; ; Test data, address and byte strobe lines. ; On MEMC systems, this calls MemSize and tests the memory that finds. ; On IOMD systems, memory sizing is performed along with the data line ; tests, and that result is used for address line testing. ; B ts_LineTest GBLS tsGetMem1 tsGetMem1 SETS "GET TestSrc.Mem1" :CC: MEMC_Type $tsGetMem1 ; ; Test IOC. ; This shuld require vector space to work (for testing interrupts), ; but the current version just reports the status register contents. ; ; Display is ccaabbff ; ; where cc is the control register ; aa is IRQ status register A ; bb is IRQ status register B ; ff is FIQ status register ; B ts_IOCTest LTORG ROUT [ IO_Type = "IOMD" 1 = "IOMD :",0 2 = "IOMD-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 3 = "IOMD-V" 4 = &88,&ff,&ff,&ff,&ff," V.",&ff,0 | 1 = "IOC :",0 2 = "IOC-F",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 3 = "IOC" 4 = &88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 ] ALIGN ts_IOCTest ADR r4,%BT1 BL ts_SendText BL ts_IOCreg ; check register integrity BEQ %FT8 ADR r4,%BT2 BL ts_SendText ; report if failure FAULT #R_IOCFAILBIT 8 ADR r4,%BT1 BL ts_SendText BL ts_IOCstat ; IOCstat, get IOC/IOMD Vsn number. ; Note : func leaves falgs un altered, thus ; result of last comparison is passed back ; as the result. ; r8 has the id&vsn number : &IIIIVV00 BEQ %FT10 ; fail message only printed if ADR r4,%BT3 ; ID code unrecognised BL ts_SendText FAULT #R_IOCFAILBIT ; .. and set error bit if IOMD code is wrong B %FT11 10 ADR r4,%BT4 ; print the status value BL ts_MoreText FAULT #R_IOMD ; set that bit in the result word ; to indicate an IOMD was found. 11 [ IO_Type = "IOMD" ; IO world is IOMD : Show IOMD Regs, skip IOEB test [ ShowIOMDRegs BL sir_ShowIOMDRegs ] B ts_CMOStest | ; IO world is IOEB: Do the IOEB test, skip Show IOMD Regs. B ts_IOEBtest ] LTORG ROUT ; ; Check for presence of IOEB ASIC ; [ IO_Type = "IOEB" 1 = "IOEB :",0 2 = "IOEB",&88,"exists",0 ALIGN ts_IOEBtest ADR r4,%BT1 BL ts_SendText LDR r0,=ts_IOEB_ID ; read an ID register in the IOEB ASIC LDRB r0, [r0] AND r0, r0, #&f CMPS r0, #ts_IOEB_ident ; if it looks right ( == 5) .. BNE %10 FAULT #R_IOEB ; set that bit in the result word ADR r4, %BT2 BL ts_SendText 10 B ts_CMOStest ] ; IOEB IO world ROUT ; ; Read CMOS ; Check the checksum, read the memory test flag. ; ts_CMOStest [ DontDoCMOSTest B ts_IOinit | ADR r4,%FT1 BL ts_SendText [ ChecksumCMOS :LAND: STB LDR r0,=(ts_BBRAM + &4000) MOV r1,#&C0 ; Get first RAM area MOV r2,#CMOSxseed BL ts_CMOSread BNE %FT10 MOV r2, r0 LDR r0,=(ts_BBRAM + &1000) ; Accumulate the second RAM area MOV r1,#&2F BL ts_CMOSread BNE %FT10 RSB r2, r0, #0 ; Subtract from the checksum byte LDR r0,=(ts_BBRAM + &3F00) MOV r1,#1 BL ts_CMOSread BNE %FT10 MOV r8, r0, LSL #24 ANDS r0, r0, #&FF ; A zero result ? MOV r1, #R_CHKFAILBIT ADR r4,%FT3 ; Report checksum failure BNE %FT21 ; failed .. report error ] ; end ChecksumCMOS [ :LNOT: AlwaysShortPOST ; Always do a short post on STBs LDR r0,=(ts_BBRAM + &FC00) ; Read Misc1CMOS byte MOV r1,#1 MOV r2,#0 BL ts_CMOSread BNE %FT10 ANDS r0,r0,#&80 ; Test the memory-test-disable bit BEQ %FT25 ] FAULT #R_MEMSKIP ; If set, skip the memory test B %FT25 10 ; CMOS failed -> try E2 [ E2ROMSupport :LAND: STB [ ChecksumCMOS ; Accumulate the first RAM area LDR r0,=(ts_BBE2 + &4000) ; r0 = base addr + start location MOV r1,#&C0 ; r1 = length of data to read MOV r2,#CMOSxseed ; r2 = checksum seed or previous value BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT20 ; branch if NE - failed to ready at all. ; Accumulate the second RAM area MOV r2, r0 ; r2 = r0 = new checksum value. LDR r0,=(ts_BBE2 + &1000) ; r0 = base addr + start location MOV r1,#&2F ; r1 = length of data to read BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT22 ; branch if NE - failed to ready at all. RSB r2, r0, #0 ; Subtract from the checksum byte ; Check to see if we need to Accumulate the THIRD area. MOV r1,#?CMOSRAMCache ; r1 = size of the CMOS RAM TEQ r1,#240 ; Is r1 = 240 bytes ? BEQ %FT15 ; It is equal, go to checksum checking code ; Accumulate the third RAM area MOV r2,r0 ; r2 = r0 = new checksum value. LDR r0,=(ts_BBE2 + &10000) ; r0 = base addr + start location MOV r1,#&300 ; r1 = length of data to read BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT22 ; branch if NE - failed to ready at all. ; read and check the shecksum value. 15 RSB r2, r0, #0 ; Subtract from the checksum byte LDR r0,=(ts_BBE2 + &3F00) ; r0 = base addr + start location MOV r1,#1 ; r1 = length of data to read BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT22 ; branch if NE - failed to ready at all. ; Check the checksum is correct MOV r8, r0, LSL #24 ; r8 = r0 << 24 : put the checksum value in r8 for displaying. ANDS r0, r0, #&FF ; r0 = r0 + &FF : If alls ok s/be a zero result ... MOV r1, #R_CHKFAILBIT ; r1 = checksum fail flag ADR r4,%FT3 ; Report checksum failure BNE %FT21 ; failed .. report error ] ; end ChecksumCMOS [ STB :LAND: :LNOT: AlwaysShortPOST ; Always do a short post on STBs LDR r0,=(ts_BBE2 + &FC00) ; Read Misc1CMOS byte MOV r1,#1 MOV r2,#0 BL ts_CMOSread BNE %FT22 ANDS r0,r0,#&80 ; Test the memory-test-disable bit BEQ %FT25 ] FAULT #R_MEMSKIP ; If set, skip the memory test B %FT25 ] 1 = "SRAM :",0 2 = "SRAM-F",0 3 = "SRAM-C",&8e,&ff,&ff,0 ALIGN 20 ; CMOS failed -> try 2K E2 [ E2ROMSupport [ ChecksumCMOS ; Accumulate the first RAM area LDR r0,=(ts_BB2KE2 + &4000) ; r0 = base addr + start location MOV r1,#&C0 ; r1 = length of data to read MOV r2,#CMOSxseed ; r2 = checksum seed or previous value BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT22 ; branch if NE - failed to ready at all. ; Accumulate the second RAM area MOV r2, r0 ; r2 = r0 = new checksum value. LDR r0,=(ts_BB2KE2 + &1000) ; r0 = base addr + start location MOV r1,#&2F ; r1 = length of data to read BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT22 ; branch if NE - failed to ready at all. RSB r2, r0, #0 ; Subtract from the checksum byte ; Check to see if we need to Accumulate the THIRD area. MOV r1,#?CMOSRAMCache ; r1 = size of the CMOS RAM TEQ r1,#240 ; Is r1 = 240 bytes ? BEQ %FT15 ; It is equal, go to checksum checking code ; Accumulate the third RAM area MOV r2,r0 ; r2 = r0 = new checksum value. LDR r0,=(ts_BB2KE2 + &10000); r0 = base addr + start location MOV r1,#&300 ; r1 = length of data to read BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT22 ; branch if NE - failed to ready at all. ; read and check the shecksum value. 15 RSB r2, r0, #0 ; Subtract from the checksum byte LDR r0,=(ts_BB2KE2 + &3F00) ; r0 = base addr + start location MOV r1,#1 ; r1 = length of data to read BL ts_CMOSread ; read the cmos r0 = new checksum. NE = failure; EQ = ok. BNE %FT22 ; branch if NE - failed to ready at all. ; Check the checksum is correct MOV r8, r0, LSL #24 ; r8 = r0 << 24 : put the checksum value in r8 for displaying. ANDS r0, r0, #&FF ; r0 = r0 + &FF : If alls ok s/be a zero result ... MOV r1, #R_CHKFAILBIT ; r1 = checksum fail flag ADR r4,%BT3 ; Report checksum failure BNE %FT21 ; failed .. report error ] ; end ChecksumCMOS [ :LNOT: AlwaysShortPOST ; Always do a short post on STBs LDR r0,=(ts_BB2KE2 + &FC00) ; Read Misc1CMOS byte MOV r1,#1 MOV r2,#0 BL ts_CMOSread BNE %FT22 ANDS r0,r0,#&80 ; Test the memory-test-disable bit BEQ %FT25 ] FAULT #R_MEMSKIP ; If set, skip the memory test B %FT25 ] 22 MOV r1,#R_CMSFAILBIT ; Real fault - set the fault bit ADR r4,%BT2 ; Report fault accessing IIC ; (Bitmap & POST display) 21 FAULT r1 BL ts_SendText ; Report one fault or another 25 B ts_IOinit ] ; DontDoCMOSTest LTORG ROUT ; ; Initialize various machine registers - e.g, turn off the floppy ; drive, etc, etc. ; 1 = "IOinit:",0 ALIGN ts_IOinit ADR r4,%BT1 BL ts_SendText ADRL r2,ts_IOinitab 10 LDR r0,[r2],#4 ; Get address LDR r1,[r2],#4 ; Get initialization data CMPS r0,#(-1) STRNE r1,[r0] ; write to IO port BNE %10 B Speedset ; ; Use the RISC OS MEMC setup code to guess the proper processor / memory ; configuration. The memory speed can then be set up correctly for ; fastest possible working, and the memory array tested in the ; configuration RISC OS expects. ; ; Display the results of the TimeCPU test as : ; ; ssss.m.r ; ; where ssss is the processor speed in hex kHz, ; m is 0 for MEMC, 1 for MEMC1a ; r is the MEMC rom speed switch setting. ; ROUT 1 = "Speed :",0 2 = "Speed",&88,&ff,&ff,&ff,&ff,".",&ff,".",&ff,0 ALIGN Speedset ADR r4,%BT1 BL ts_SendText [ MEMC_Type = "IOMD" MOV r9,#0 | MOV_fiq r0, r11_fiq ; get MEMC setup MOV r9,r0 ; compare IOC and CPU clocks ] BL TimeCPU MOV r0,r9 MOV_fiq r11_fiq,r0 MOV r8,r7,LSL #16 TST r7, #1 :SHL: 16 ; test bit 16 of r7 : ADDNE r8,r8,#&1000 ; MEMC1 / MEMC1a detected AND r9,r9,#&C0 ; get High ROM access bits ADD r8,r8,r9, LSL #2 ADR r4,%BT2 BL ts_SendText B RAMtest ; ; Long RAM test, ideally exercising all memory. ; In order to keep boot time short, the following scheme is used : ; ; Normal power-on boot - test VRAM and up to 4M of first DRAM entry ; CMOS disable set - test nothing ; Test hardware fitted - test entire memory ; ROUT 1 = "RAM :",0 2 = "RAM bad",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 3 = &89,"skipped",0 4 = "RAM :",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 ALIGN RAMtest [ {TRUE} B ts_VIDCtest ; skip memory test altogether | ADR r4,%BT1 ] BL ts_SendText ; ; if (R_MEMSKIP && R_HARD) ; skip all the remaining tests ; if (!R_LINFAILBIT) ; perform the long memory test ; MOV_fiq r0,r12_fiq ; skip this test if data line fault AND r1,r0,#(R_MEMSKIP :OR: R_HARD) ; or the user didn't want it TEQS r1,#(R_MEMSKIP :OR: R_HARD) ANDNE r1,r1,#R_LINFAILBIT TEQNE r1,#R_LINFAILBIT BNE %12 ADR r4,%BT3 ; skipping memory test .... BL ts_MoreText B ts_Report 12 [ STB :LAND: DontShowProgressColours MOV_fiq r0,r12_fiq ; restore the faultcode bits ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, ; NE : Adaptor fitted, show progress. ; EQ : No Adaptor fitted, don't show progress BEQ %FT13 ; EQ : Don't show colours ] LDR r1,=C_RAMTEST ; doing at least part of the long memory test LDR r0,=ts_VIDCPhys ; write the border colour STR r1,[r0] 13 BL MemSize ; Set MMU up, mapping (some) RAM at logical address 0 ; Note that this returns with the MMU enabled, ; the ROM remapped to it's ORGed address, ; and r4 the offset from physical to ORGed ROM addresses ; r4 = ROM - Phys[Ext]ROM RSB r4, r4, #PhysSpace ; r4 = PhysSpace - ROM + Phys[Ext]ROM, pc = ROM + offset MODE SVC32_mode ; Must do this, as PhysSpace is outside 26 bit addressing ADD pc, pc, r4 ; pc = PhysSpace + Phys[Ext]ROM + offset NOP ; this instruction skipped by pc adjustment ; ; Modify the PhysRamTable so only VRAM and the first ts_MaxRamTest of DRAM gets tested ; MOV_fiq r0,r12 ; get the test condition flags ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) BNE %FT16 ; do full test if test adapter is present MOV r9,#PhysRamTable ADD r10,r9,#(PhysRamTableEnd-PhysRamTable) 14 LDR r1,[r9, #4] ADD r0,r0,r1 ; r0 = running sum of memory sizes SUBS r2,r0,#ts_MaxRamTest ; r2 = excess over ts_MaxRamTest SUBHI r1,r1,r2 ; r1 = current size truncated STRHI r1,[r9, #4] MOVHI r0,#ts_MaxRamTest ; truncate running sum to MaxRamTest ADD r9,r9,#(DRAMPhysAddrB-DRAMPhysAddrA) CMPS r9,r10 BNE %BT14 16 FAULT #R_MEMORY ; memory tests were attempted MOV r9,#VideoPhysAddr LDR r8,[r9] ; report the test address ADRL r4,%BT4 BL ts_SendText LDR r0,[r9] ; get VRAM start address and size LDR r1,[r9,#4] ADD r0,r0,#PhysSpace BL ts_RamTest BNE %FT20 ; failed - abort ram testing ; ; VRAM (or 1st MB of DRAM, if no VRAM fitted) looks OK - move the translation ; table there so memory tests can proceed without smashing it. ; MOV r9,#PhysRamTable LDR r0,[r9,#VideoPhysAddr-PhysRamTable] ; get address of video RAM LDR r1,[r9,#DRAMPhysAddrA-PhysRamTable] ; get address of 1st DRAM bank LDR r3, =DRAMOffset_L2PT ADD r1, r1, r3 ; make r1 -> L2PT ADD r0, r0, r3 ; make r0 -> temporary L2PT BL ts_remap_ttab ; copy ttab at r1 to r0 and change table base ; ; Now run the RAM test at each DRAMPhysAddr until the end of the table or a zero entry ; is reached. Mark tested entries by setting the PhysSpace address, so a pointer to the ; next entry need not be kept. ; 18 MOV r9,#DRAMPhysAddrA ADD r10,r9,#(PhysRamTableEnd-DRAMPhysAddrA) 19 CMPS r9,r10 ; reached end of table ? LDRNE r0,[r9] TSTNE r0,r0 ; reached unused entries ? LDRNE r1,[r9,#4] ; or blanked-out entries ? TSTNE r1,r1 BEQ %FT21 ; .. all passed OK TSTS r0,#PhysSpace ADDNE r9,r9,#(DRAMPhysAddrB-DRAMPhysAddrA) BNE %BT19 ; this entry done .. find the next MOV r8,r0 ; report address of this block ADRL r4,%BT4 BL ts_SendText LDR r0,[r9] ; start testing it ADD r0,r0,#PhysSpace LDR r1,[r9, #4] STR r0,[r9] ; mark block so it isn't retested MOV r2,#PhysRamTable LDMIA r2,{r3-r14} ; save the PhysRamTable STMIA r0,{r3-r14} BL ts_RamTest LDMIA r13,{r1-r11,r14} ; restore the PhysRamTable MOV r13,#PhysRamTable STMIA r13,{r1-r11,r14} BEQ %BT18 ; if it passed, go look for another block 20 FAULT #R_MEMFAILBIT ; failed - report fault address ADRL r4,%BT2 MOV r11,r1 ; Save failed data MOV r8,r0 ; first failing address BL ts_SendText MOV r4,r12 ; get fault message MOV r8,r11 ; and fault data BL ts_SendText 21 [ MEMM_Type = "MEMC1" ; ; Test the CAMs - for each fitted MEMC, go through all the CAM entries ; remapping logical memory and testing against physical correspondence. ; Then try out the protection bits in each CAM entry and various ; processor modes. ; These tests return pointers to their own fault report strings. ; B ts_CAMtest ROUT 1 = "CAMs :",0 2 = "PPLs :",0 3 = &89,"skipped",0 ALIGN ts_CAMtest LDR r4,=%BT1 BL ts_SendText MOV_fiq r0,r12_fiq ; skip this test if memory fault MOV r1,#(R_LINFAILBIT :OR: R_MEMFAILBIT) ANDS r0,r0,r1 BEQ %08 LDR r4,=%BT3 BL ts_MoreText B %20 08 BL ts_CAM BEQ %10 BL ts_SendText FAULT #R_CAMFAILBIT 10 LDR r4,=%BT2 BL ts_SendText MOV_fiq r0,r12_fiq ; skip this test if memory fault MOV r1,#(R_LINFAILBIT :OR: R_MEMFAILBIT) ANDS r0,r0,r1 BEQ %18 LDR r4,=%BT3 BL ts_MoreText B %20 18 BL ts_memc_prot BEQ %20 BL ts_SendText FAULT #R_PROFAILBIT 20 ] ; ; After testing memory and translation, turn MMU off again before running remainder ; of tests. This simplifies finishing up (where system must be put back into 26-bit ; mode before initialising RISCOS) if memory tests were deselected. ; Take care to poke the real translation table - it's been relocated to video ; RAM during the memory tests. ; ts_restore_physical [ StrongARM_POST ;make sure ARM810 cache or StrongARM data cache is cleaned/flushed, because we are going to remap ARM_read_ID r5 AND r5,r5,#&F000 CMP r5,#&8000 BNE %FT22 ;ARM810 ;;; ARM8_cleanflush_IDC r5 ;not implemented yet B %FT24 22 CMP r5,#&A000 BNE %FT24 ;StrongARM ;tricky...we'll read 16k of data in current ROM space, to act as clean and flush of current data MOV r3,pc BIC r3,r3,#31 ;32 byte aligned ARMA_clean_DC r3,r5,r7 24 ] ;StrongARM_POST MOV r5, pc ; obtain current address SUB r5, r5,#PhysSpace ; adjust to point to unmapped version MOV r5, r5, LSR #20 ; divide by 1MB MOV r7, r5, LSL #20 ; r7 = physical address of base of section ORR r7, r7, #(AP_None * L1_APMult) ORR r7, r7, #L1_Section MOV r3, #VideoPhysAddr ; find the copied translation table LDR r3, [r3] ADD r3, r3, #PhysSpace ADD r3, r3, #DRAMOffset_L1PT STR r7, [r3, r5, LSL #2] ; store replacement entry in L1 (not U,C or B) [ StrongARM_POST ;flush cache if ARM 6/7 (ARM 8,StrongARM already sorted, above) ;flush TLB(s) ARM_read_ID r4 AND r4,r4,#&F000 CMP r4,#&8000 ;ARM 8? CMPNE r4,#&A000 ;or StrongARM? MCRNE ARM_config_cp,0,R0,ARM67_cacheflush_reg,C0,0 ;flush 6/7 cache MCRNE ARM_config_cp,0,R0,ARM67_TLBflush_reg,C0,0 ;flush 6/7 TLB MCREQ ARM_config_cp,0,R0,ARM8A_TLB_reg,C7,0 ;flush 8/StrongARM TLB(s) | SetCop r7, CR_IDCFlush ; flush cache + TLB just in case SetCop r7, CR_TLBFlush ; (data written is irrelevant) ] ; The ROM should now be mapped at the present address less PhysSpace, which is where it ; would be if the MMU were turned off. MOV r4,#PhysSpace SUB pc,pc,r4 NOP ; this instruction is skipped ; now turn the MMU off, also ensures 26 bit mode, if ARM 6/7 (since P bit zero) MOV r7, #MMUC_D SetCop r7, CR_Control B ts_VIDCtest ; ; The VIDC tests check vertical blanking frequency in a fixed video ; mode and measure the time taken for sound DMA. ; ROUT 1 = "VIDC :",0 2 = "Virq bad",&88,' ',&ff,'.',&ff,&ff,&ff,&ff,&ff,0 3 = "Sirq bad",&8B,&ff,&ff,&ff,&ff,&ff,0 4 = &8A,"Mid0 ",&ff,0 ALIGN ts_VIDCtest ADR r4,%BT1 BL ts_SendText [ IO_Type = "IOMD" LDR r0,=IOMD_MonitorType ; Indicate monitor ID bit's value LDR r0,[r0] AND r0,r0,#IOMD_MonitorIDMask MOV r8,r0,LSL #28 ADR r4,%BT4 BL ts_MoreText ] [ MorrisSupport MOV r3, #IOMD_Base LDRB r1,[r3,#IOMD_ID1] ; load r1 with IOMD ID high byte LDRB r0,[r3,#IOMD_ID0] ; load r1 with IOMD ID low byte ORR r0,r0,r1,LSL#8 ; Or r0 and r1, shifted left 8, put in r0 LDR r1,=ts_IOMD_ID1 ; get Ref IOMD ID code #1 (Original) CMPS r0,r1 ; check for IOMD ID Code #1 BNE %FT10 ; If not equal, got to 10 ; thus skip Virq test on ARM7500 and ARM7500FE (Morris) ] BL ts_VIDC_period BEQ %10 ADR r4,%B2 MOV r8, r0, LSL #8 BL ts_SendText ; Display Virq fail msg FAULT #R_VIDFAILBIT 10 [ IO_Type = "IOMD" ; RCM thinks this is no longer needed - all IOMD's are issue two ; besides, the test takes no account of Morris reusing the number space! ; MOV r3,#IOMD_Base ; skip Sirq test on version 1 IOMD ; LDRB r0,[r3,#IOMD_VERSION] ; CMPS r0,#1 ; BEQ %FT20 ] BL ts_SIRQ_period BEQ %20 ADR r4,%B3 MOV r8, r0, LSL #12 BL ts_SendText ; Display Sirq fail msg FAULT #R_SNDFAILBIT 20 MOV r1,#ts_VIDCPhys ; Restore full-screen ADRL r2,TestVIDCTAB ; border colour. [ IO_Type = "IOMD" LDR r0,=IOMD_MonitorType LDR r0,[r0] ANDS r0,r0,#IOMD_MonitorIDMask ADDEQ r2,r2,#(TestVVIDCTAB-TestVIDCTAB) ] 30 LDR r0, [r2],#4 CMP r0, #-1 STRNE r0, [r1] BNE %BT30 [ STB :LAND: DontShowProgressColours MOV_fiq r0,r12_fiq ; restore the faultcode bits ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, ; NE : Adaptor fitted, show progress. ; EQ : No Adaptor fitted, don't show progress BEQ ts_ARMtype_test ; EQ : Don't show colours ] LDR r0,=C_ARMOK ; set initial screen colour STR r0, [r1] B ts_ARMtype_test ; ; Read the ARM3 identification register. ; If memory tests failed, this won't be performed since the vector ; page must exist for error recovery on ARM2 systems. ; ROUT 1 = "ARM ID:",0 2 = "ARM ID",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 3 = &89,"skipped",0 ALIGN ts_ARMtype_test ADR r4,%BT1 BL ts_SendText MOV_fiq r0,r12_fiq ; skip this test if memory fault LDR r1,=((R_LINFAILBIT :OR: R_MEMFAILBIT) :OR: (R_CAMFAILBIT :OR: R_PROFAILBIT)) ANDS r0,r0,r1 BEQ %05 ADR r4,%BT3 BL ts_MoreText B %08 ; and quit 05 BL ts_ARM_type MOVS r8, r0 ; ready to display ID code ADR r4,%BT2 BEQ %FT07 ; ARM 2 : skip cache test FAULT #R_ARM3 ; not really a fault, just status 07 BL ts_SendText 08 B ts_Report ; ; Report the test results to the user ; ; If this was a forced test (test adapter fitted) then pause even when ; test passed : otherwise, pause only on error. ; ts_passmsg = "PASS :",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 ts_failmsg = "FAIL :",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0 ts_R00 & 00 [ STB :LAND: POSTFlashesFrontPanelLEDs ; Define Long, Equal and short flash delays ts_Long_Flash * &03 ; Number of 1/4 Sec delays for a long flash ts_Short_Flash * &01 ; Number of 1/4 Sec delays for a short flash ts_Equal_Flash * &02 ; Number of 1/4 Sec delays for a equal flash ts_Fail_Flash_Delay * &14 ; Number of Flash Cycles for a Fail, with adaptor ts_Pass_Flash_Delay * &0A ; Number of Flash Cycles for a Pass, with adaptor IOMD_LED_GREENLED * IOMD_C_FrontPanelRightLED ; The right LED should be the GREEN LED IOMD_LED_REDLED * IOMD_C_FrontPanelLeftLED ; The left LED should be the RED LED IOMD_LED_BOTH * IOMD_LED_REDLED :OR: IOMD_LED_GREENLED ; ] ; Endif (POSTFlashesFrontPanelLEDs) ts_Report ROUT MOV_fiq r7,r12_fiq ; check for fault bits set LDR r0,=R_STATUS BICS r0,r7,r0 ADREQ r4, ts_passmsg ; tests passed LDREQ r9,=C_PASSED ADRNE r4, ts_failmsg ; tests failed LDRNE r9,=C_FAULT LDR r0,=ts_VIDCPhys ; write the border colour STR r9,[r0] MOV r8,r7 BL ts_SendText ; write the message and fault code ; if the test adapter is present, leave green screen awhile ; otherwise, wait only if there's a fault. LDR r3,=ts_recover_time 00 ADDS r3,r3,r3 ; 16-loop delay BCC %B00 ; - let the adapter recover ; from previous bus activity ADR r2,ts_R00 ORR r2,r2,#ts_Alias_bits LDR r3,[r2] MOV r2,#-1 ADDS r3,r3,r2 BCS ts_Report_wait ; Here is r3 = 0, which ment a DUMP adaptor was present. ; ; Continue to the OS ; MOV_fiq r0,r12_fiq LDR r2,=R_STATUS BICS r0,r0,r2 BEQ ts_Hardstart ts_Report_wait ROUT ; ; Here if a Display or other type of adaptor found. ; [ STB :LAND: POSTFlashesFrontPanelLEDs ; ; Check to see if we are a PASS or FAIL ; MOV_fiq r7,r12_fiq ; check for fault bits set LDR r0,=R_STATUS BICS r0,r7,r0 BEQ ts_flash_leds_pass ; flash the leds to show a pass ; flash the leds to show a failure ; Fall through ! ts_flash_leds_fail ; ; Get here if the POST fails ! ; ; Set it so the RED LED is on. BL ts_led_redon_only ; Ensure that the RED LED only is on, ; Check for display adpator, if fitted, flash LED's for 20 times ; else flash LEDs forever. ; MOV_fiq r0,r12_fiq ; restore the faultcode bits ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, BNE %FT19 ; Adaptor : Goto 20 Flash loops Code ; No Adaptor : Goto Infinite flash loop Code ; Fall through ! 14 ; Infinite Flash loop ; Register usage .... ; r0, used by toggle leds & delay routines ; r1, used by toggle leds routine ; 15 BL ts_led_fail ; Call code to flash the leds B %BT15 ; Repeat forever. 19 ; Loop for specified time ; Register usage .... ; r0, used by toggle leds & delay routines ; r1, used by toggle leds routine ; ; r3, Loop counter ; r4, Pass delay time to delay code. ; MOV r3,#ts_Fail_Flash_Delay ; Set the loop counter. 20 BL ts_led_fail ; Call code to flash the leds SUBS r3,r3,#1 ; Decrment loop counter BNE %BT20 ; Repeat until r3 = 0 BEQ %FT50 ; r3=0, were all done ; Goto start the OS ts_flash_leds_pass ; Here if POST passed. ; If adaptor fitted, flash the LEDs for a 10 secs MOV_fiq r0,r12_fiq ; restore the faultcode bits ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, BEQ %FT55 ; No Adaptor : Goto start the OS ; Adaptor : Goto 10 Flash loops Code ; Fall through ! ; Set it so the RED LED is on. BL ts_led_redon_only ; Ensure that the RED LED only is on, ; Loop for specified time ; Register usage .... ; r0, used by toggle leds & delay routines ; r1, used by toggle leds routine ; ; r3, Loop counter ; r4, Pass delay time to delay code. ; MOV r3,#ts_Pass_Flash_Delay ; Set the loop counter. 30 BL ts_led_pass ; Call code to flash the leds SUBS r3,r3,#1 ; Decrment loop counter BNE %BT30 ; Repeat until r3 = 0 BEQ %FT50 ; r3=0, were all done ; Goto start the OS ts_led_fail ; Code to flash the LED's through one flash cycle (on-off) ; This will take 1 Second to complete. ; ;|------>|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--| ;|--Red--|---Green---|----Red----|----Red----|----Red----|\  ; \_______________________________________________/ ; ; Red Green MOV r13,r14 ; make a note of where we On Off ; came from. BL tl_Toggle_LEDs ; Toggle the LEDs Off On MOV r4,#ts_Short_Flash ; Load r4 with Short flash Off On BL ld_LED_Delay ; call delay routine Off On BL tl_Toggle_LEDs ; Toggle the LEDs On Off MOV r4,#ts_Long_Flash ; load r4 with long flash On Off BL ld_LED_Delay ; call delay routine On Off MOV pc,r13 ; move r13 (r14) back to ; where we came from. ts_led_pass ; Code to flash the LED's through one flash cycle (on-off) ; This will take 1 Second to complete. ; ;|------>|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--|--1/4 Sec--| ;|--Red--|---Green---|---Green---|---Green---|----RED----|\  ; \_______________________________________________/ ; ; Red Green MOV r13,r14 ; make a note of where we On Off ; came from. BL tl_Toggle_LEDs ; Toggle the LEDs Off On MOV r4,#ts_Long_Flash ; Load r4 with long flash Off On BL ld_LED_Delay ; call delay routine Off On BL tl_Toggle_LEDs ; Toggle the LEDs On Off MOV r4,#ts_Short_Flash ; load r4 with short flash On Off BL ld_LED_Delay ; call delay routine On Off MOV pc,r13 ; move r13 (r14) back to ; where we came from. ts_led_redon_only LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES LDRB r0,[r1] ; load r0 with the byte pointed to by r1 ; DREG r0,"contents of loc->r1" BIC r0,r0,#IOMD_LED_GREENLED ; Clear GREEN LED bit ORR r0,r0,#IOMD_LED_REDLED ; Set RED LED bit ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 MOV pc, r14 ; Return to caller ts_led_greenon_only LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES LDRB r0,[r1] ; load r0 with the byte pointed to by r1 ; DREG r0,"contents of loc->r1" BIC r0,r0,#IOMD_LED_REDLED ; clear RED LED bit ORR r0,r0,#IOMD_LED_GREENLED ; Set GREEN LED bit ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 MOV pc, r14 ; Return to caller ts_led_bothon LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES LDRB r0,[r1] ; load r0 with the byte pointed to by r1 ; DREG r0,"contents of loc->r1" ORR r0,r0,#IOMD_LED_BOTH ; Set Both Green & RED LED bits ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 MOV pc, r14 ; Return to caller ts_led_bothoff LDR r1, =IOMD_IOLINES ; r1 = addr of IOMD_IOLINES LDRB r0,[r1] ; load r0 with the byte pointed to by r1 ; DREG r0,"contents of loc->r1" BIC r0,r0,#IOMD_LED_BOTH ; Clear Both Green & RED LED bits ORR r0,r0,#IOMD_C_ReadMask ; OR with the default I/O settings STRB r0,[r1] ; store a byte of r0 in to loc pointed to by r1 MOV pc, r14 ; Return to caller 50 ; come here if we've finished showing pass/fail by flashing the LEDs ; thus a test link or display aaptor was fitted ; so turn on the LED's BL ts_led_bothon 55 ; come here because we passed, but no display adaptor ot test link, thus LEDs weren't flashed ; so ........ ; Continue on our way ; | ; else ; ; :LNOT: POSTFlashesFrontPanelLEDs ; Thus we use the old way of flashing the LED etc .... ; ; Indicate fault found : Set the border to fault colour and flash ; the disk LED, using the fault bitmap in r12_fiq to modulate the flashing. ; ts_oldLED_on * &be0000 ; assert SEL0 and INUSE ts_oldLED_off * &ff0000 ; on machines with 1772 controller ts_oldLEDaddr * (ts_S5_base :OR: &40) ts_710LED_on * &100000 ; assert SEL0 and MotorEN0 ts_710LED_off * &110000 ; on machines with 82C710 controller ts_710LEDaddr * (ts_PCaddress :OR: (&3f2 :SHL: 2)) ts_665LED_on * &10 ; assert SEL0 and MotorEN0 ts_665LED_off * &11 ; on machines with 37665 controller ; and Medusa low-byte I/O world ts_665LEDaddr * (ts_PCaddress :OR: (&3f2 :SHL: 2)) 01 MOV_fiq r6,r12_fiq LDR r2,=&11111111 [ :LNOT: STB LDR r7,=(35000 * 8) ; 1/4 second pause loop count ] [ IO_Type = "IOMD" LDRNE r1,=ts_665LEDaddr ; set up for Medusa disc address MOVNE r8,#ts_665LED_on MOVNE r9,#ts_665LED_off | TST r6, #R_IOEB ; determine original / 710 disc controller LDREQ r1,=ts_oldLEDaddr ; set up for Archimedes disc address MOVEQ r8,#ts_oldLED_on MOVEQ r9,#ts_oldLED_off LDRNE r1,=ts_710LEDaddr ; set up for Brisbane disc address MOVNE r8,#ts_710LED_on MOVNE r9,#ts_710LED_off ] 02 [ STB BL ld_LED_Delay ; call delay routine MOV r0,r8 ; turn the LED on STR r0,[r1] BL ld_LED_Delay ; call delay routine ADDS r6,r6,r6 ; if a '1' is to be written, BCC %06 BL ld_LED_Delay ; call delay routine } BL ld_LED_Delay ; call delay routine } Half A Second | MOV r0,r7 03 SUBS r0,r0,#1 ; pause for a 1/4 second BNE %03 MOV r0,r8 ; turn the LED on STR r0,[r1] MOV r0,r7 04 SUBS r0,r0,#1 ; pause for a 1/4 second BNE %04 ADDS r6,r6,r6 ; if a '1' is to be written, BCC %06 MOV r0,r7,LSL #1 ; then pause another 1/2 second 05 SUBS r0,r0,#1 BNE %05 ] 06 MOV r0, r9 ; turn the LED off STR r0,[r1] ; ; Count down 32 bits. Every 4 bits, insert an extra pause to simplify ; reading the flashes. ; ADDS r2,r2,r2 BCC %08 [ STB BL ld_LED_Delay ; call delay routine } BL ld_LED_Delay ; call delay routine } One Seconds Worth BL ld_LED_Delay ; call delay routine } BL ld_LED_Delay ; call delay routine } | MOV r0,r7,LSL #2 ; then pause another second 05 SUBS r0,r0,#1 BNE %05 ] 08 ANDS r2,r2,r2 ; all the bits displayed now ? BNE %02 MOV_fiq r0,r12_fiq ; restore the faultcode bits ] ; Endif (POSTFlashesFrontPanelLEDs) ; MOV_fiq r0,r12_fiq ; restore the faultcode bits ; Uncomment the following line if the POST code is to loop when the POST ; display adaptor (post box) is fitted. ; ; ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If the display adapter & test link are present, ; ; Comment this line out if POST Code is to loop when the POST display ; adaptor (post box) is fitted. ; ANDS r0,r0,# R_TESTED ; If the test link is present, BNE Reset ; repeat the test forever B CONT ; otherwise, run RISC OS ts_Hardstart MOVS r0,#R_HARD ; and report a hard start B CONT ; to RISC OS ; ; Tests skipped : fall into RISC-OS ; ts_Self_test_end [ STB :LAND: DontShowProgressColours MOV_fiq r0,r12_fiq ; restore the faultcode bits ANDS r0,r0,#(R_EXTERN :OR: R_TESTED) ; If test adapter present, ; NE : Adaptor fitted, show progress. ; EQ : No Adaptor fitted, don't show progress BEQ ts_Softstart ; EQ : Don't show colours ] LDR r1,=C_DEFAULT LDR r0,=ts_VIDCPhys ; write the border colour STR r1,[r0] ts_Softstart MOVS r0,#R_SOFT ; soft reset indicator B CONT ; ; ; ROUT ; ; This table consists of a series of address/data pairs for IO ; initialization. ; Note that these addresses are likely to be in the IO world, ; and hence the data written is that from the MOST significant ; 16 bits of the data bus. ; An 'address' of -1 terminates the table. ; ts_IOinitab [ IO_Type = "IOMD" | & ts_S5_base :OR: &10, &000000 ; Printer port data & ts_S5_base :OR: &18, &000000 ; FDC control & printer strobes & ts_S5_base :OR: &40, &ff0000 ; FDD select lines & ts_S5_base :OR: &48, &000000 ; VIDC clock control ] & (-1) ; ; ;--------------------------------------------------------------------------- LTORG ; Include test modules executed by call, rather than inline GET TestSrc.Mem2 GET TestSrc.Mem3 GET TestSrc.Mem4 GET TestSrc.Mem5 GET TestSrc.Vidc GET TestSrc.Ioc GET TestSrc.Cmos GET TestSrc.Arm3 ; amg: 7/12/96 Renaissance. Once again I wish AASM could understand conditionals ; around GETs GBLS get_toggleled GBLS get_leddelay GBLS get_showiomdrs [ STB get_toggleled SETS "GET TestSrc.ToggleLED" get_leddelay SETS "GET TestSrc.LEDDelay" get_showiomdrs SETS "GET TestSrc.ShowIOMDRs" | get_toggleled SETS "" get_leddelay SETS "" get_showiomdrs SETS "" ] $get_toggleled $get_leddelay $get_showiomdrs ALIGN 64 ; JRH: Kernel seems happier if we do this! END