Commit a80f2602 authored by Kevin Bracey's avatar Kevin Bracey
Browse files

First attempt to get POST working with >8M ROMs.

Version 4.77. Tagged as 'Kernel-4_77'
parent 0821a76d
;
; A600tlb
;
; POST procedure for checking the TLB in A600 MMU.
;
; for each of level 1, level 2 small-page, level 2 large-page
; construct page table
; flush cache
; start timer
; for 32 addresses (with different mappings)
; check address mapping
; save timer
; for same 32 addresses
; check address mapping
; compare test times (did 2nd test require table walk ?)
Use a list of addresses that cover a good mixture of virtual addresses
Build a page table that maps these to physical RAM addresses in various ways
Access the addresses in such an order that the cache rotates, scrapping
one entry each time through the list, and loading another. So each cache
entry gets used 31 times, then is lost.
Choice of physical mapping should ensure that the cache entries contain
lots of different values of page and section base addresses.
Choice of virtual test address should ensure that cache tag varies as
widely as posible, too. PRBS ?
Very widely varying values of cache tag require that a large number
of mappings exist .. if these are 2-level mappings, that requires
a lot of RAM. Page tables should be multiply-mapped.
RISC OS puts lots of stuff below the 4M mark. Limits App space to 16M
for backwards compatibility. Probably worth testing outside these
limits to ensure Gold doesn't fall over, but failure rates would be
very low.
;
; POST procedure for checking access faults (was PPL test)
;
; for each of level 1, level 2 small-page, level 2 large-page
; construct page table
; for user, supervisor mode
; check address alignment fault
; check section translation fault
; check
; check page translation fault
; for 3 domain types
; for 16 domains
; check access permissions
;
;
; POST procedure for checking IDC
;
;
; > TestSrc.ARM3
TTL RISC OS 2+ POST ARM version determination
;
; Reads ARM3 version register, returns 0 if ARM 2 fitted.
;
;------------------------------------------------------------------------
; History
;
; Date Name Comment
; ---- ---- -------
; 20-Apr-89 ArtG Initial version
;
;
;------------------------------------------------------------------------
A3Cid CN 0
A3Cfls CN 1
A3Cmod CN 2
A3Ccac CN 3
A3Cupd CN 4
A3Cdis CN 5
A3CON CP 15
ts_ARM_type
MOV r13,lr
;
; First, set up an undefined instruction vector to catch an ARM 2
; (or a faulty ARM 3 ??) when the copro instruction is run.
; Only applies on systems where ROM isn't mapped at zero.
[ CPU_Type = "ARM2" :LOR: CPU_Type = "ARM3"
MOV r0,#0 ; set a page at logical 0
MOV r1,r0
BL ts_set_cam
ADR r0,ts_ARM_undefined
LDMIA r0,{r2,r3}
MOV r1,#4
STMIA r1,{r2,r3} ; set the undefined instruction trap
]
;
; Read ARM3C0 version I.D.
;
MOV r0, #(-1) ; should always be altered
MRC A3CON,0,r0,A3Cid,A3Cid ; Read control register 0
MOV r12, r0
[ CPU_Type = "ARM2" :LOR: CPU_Type = "ARM3"
MOV r1,#0
BL ts_set_cam_idle ; remove the vector page again
]
MOVS r0, r12 ; return the ID (0 for ARM 2)
MOV pc,r13
;
; Trap to be taken when ARM 2 is fitted
;
ts_ARM_undefined
MOV r0,#0
MOVS pc,r14_svc
10
ASSERT ((%10 - ts_ARM_undefined) / 4 = 2)
END
This diff is collapsed.
; > TestSrc.Cmos
TTL RISC OS 2+ POST battery-backed RAM access
;
; A function to read bytes from CMOS, for use in verifying the checksum
; and reading memory test flag & video modes.
;------------------------------------------------------------------------
; History
;
; Date Name Comment
; ---- ---- -------
; 05-Apr-91 ArtG Initial version, based on IICMod.
;
;
;------------------------------------------------------------------------
;
; in:
; R0 = device address (bit 8 - 15 register address )
; R1 = length of block to read
; R2 = initial sum value
;
; out: R0 = sum of all bytes in block
; R1 - R13 trashed
;
ts_CMOSread ROUT
MOV R13,R14
MOV R8,R2 ; initialise accumulator
MOV R7,R1 ; initialise byte counter
MOV R6,R0 ; stash register address
MOV R2, #IOC
MOV R0, #-1 ; ensure timer is ticking
STRB R0, [R2, #Timer0LL] ; (nonzero in input latch)
STRB R0, [R2, #Timer0LH]
STRB R0, [R2, #Timer0GO] ; load the count registers
BL ts_Start
BEQ %FT30 ; check clock line toggles OK
AND R0, R6, #&FE
BL ts_TXCheckAck ; transmit device address (write)
BVS %FT30
MOV R0, R6, LSR #8
BL ts_TXCheckAck ; write register address
BVS %FT30
BL ts_Start ; Extra START bit to switch modes
AND R0, R6, #&FE
ORR R0, R0, #1
BL ts_TXCheckAck ; transmit device address (read)
BVS %FT30
20
BL ts_RXByte ; read byte from bus
ADD R8, R8, R0 ; accumulate total
SUBS R7, R7, #1 ; is it last byte ?
MOVNE R0, #0 ; no, then acknowledge with 0 bit
MOVEQ R0, #1 ; yes, then don't acknowledge
BL ts_ClockData ; but always send ack clock pulse
TEQ R7, #0 ; loop, until last byte
BNE %BT20
30
MOVVS R7, #-1 ; pass error indicator to caller
BL ts_Stop
MOV R0, R8
TEQ R7, #0 ; return zero flag if read OK
MOV PC,R13
; *****************************************************************************
;
; TXCheckACK - transmit a byte and wait for slave to ACK
;
; out: Trashes r0,r1,r2,r3,r4,r5,r9,r10,r11,r12
; V bit set on error.
;
ts_TXCheckAck ROUT
MOV R12,R14
BL ts_TXByte
BL ts_Acknowledge
MOVVC PC, R12 ; acknowledged ok, so return
ORRS PC, R12, #V_bit
; *****************************************************************************
;
; SetC1C0 - Set clock and data lines to values in R1 and R0 respectively
;
; out: Trashes r0,r1,r2,r11
;
ts_SetC1C0 ROUT
MOV R11, R14
BIC R14, R14, #Z_bit ; indicate not checking clock
ts_SetOrCheck
ORR R14, R14, #I_bit ; disable interrupts
TEQP R14, #0
ADD R0, R0, R1, LSL #1 ; R0 := C0 + C1*2
ORR R0, R0, #&C0 ; make sure two test bits are
; always set to 1 !
MOV R2, #IOC
STRB R0, [R2, #IOCControl]
10
LDREQB R1, [R2, #IOCControl] ; wait for clock
TSTEQ R1, #i2c_clock_bit ; to read high
BEQ %BT10
MOV R0, #10 ; delay for >= 10/2 microsecs
;
; in-line do-micro-delay to save a stack level
;
STRB R0, [R2, #Timer0LR] ; copy counter into output latch
LDRB R1, [R2, #Timer0CL] ; R1 := low output latch
20
STRB R0, [R2, #Timer0LR] ; copy counter into output latch
LDRB R14, [R2, #Timer0CL] ; R14 := low output latch
TEQ R14, R1 ; unchanged ?
MOVNE R1, R14 ; copy anyway
BEQ %BT20 ; then loop
SUBS R0, R0, #1 ; decrement count
BNE %BT20 ; loop if not finished
;
; end do-micro-delay
;
MOV PC, R11
; Set clock and data lines to R1 and R0 and then wait for clock to be high
ts_SetC1C0CheckClock ROUT
MOV R11, R14
ORR R14, R14, #Z_bit ; indicate checking clock
B ts_SetOrCheck
; *****************************************************************************
;
; ClockData - Clock a bit of data down the IIC bus
;
; in: R0 = data bit
;
; out: Trashes r0,r1,r2,r3,r10,r11
;
ts_ClockData ROUT
MOV R10,R14
MOV R3, R0 ; save data
MOV R1, #0 ; clock LO
BL ts_SetC1C0
MOV R1, #1 ; clock HI
MOV R0, R3
BL ts_SetC1C0CheckClock
; Delay here must be >= 4.0 microsecs
MOV R1, #0 ; clock LO
MOV R0, R3
BL ts_SetC1C0
MOV PC,R10
; *****************************************************************************
;
; Start - Send the Start signal
;
; out: Trashes r0,r1,r2,r9,r11
; R0 (and Z flag) indicates state of clock .. should be NZ.
;
ts_Start ROUT
MOV R9,R14
MOV R0, #1 ; clock HI, data HI
MOV R1, #1
BL ts_SetC1C0
; Delay here must be >= 4.0 microsecs
MOV R0, #0 ; clock HI, data LO
MOV R1, #1
BL ts_SetC1C0
; Make sure clock really is high (and not shorted to gnd)
LDRB R3, [R2, #IOCControl]
; Delay here must be >= 4.7 microsecs
MOV R0, #0 ; clock LO, data LO
MOV R1, #0
BL ts_SetC1C0
ANDS R0, R3, #i2c_clock_bit
MOV PC,R9
; *****************************************************************************
;
; Acknowledge - Check acknowledge after transmitting a byte
;
; out: Trashes r0,r1,r2,r3,r9,r11
; V=0 => acknowledge received
; V=1 => no acknowledge received
;
ts_Acknowledge ROUT
MOV R9,R14
MOV R0, #1 ; clock LO, data HI
MOV R1, #0
BL ts_SetC1C0
MOV R0, #1 ; clock HI, data HI
MOV R1, #1
BL ts_SetC1C0CheckClock
; Delay here must be >= 4.0 microsecs
MOV R2, #IOC
LDRB R3, [R2, #IOCControl] ; get the data from IOC
MOV R0, #1 ; clock LO, data HI
MOV R1, #0
BL ts_SetC1C0
TST R3, #1 ; should be LO for correct acknowledge
MOV R3, PC
BICEQ R3, R3, #V_bit ; clear V if correct acknowledge
ORRNE R3, R3, #V_bit ; set V if no acknowledge
TEQP R3, #0
MOV PC,R9
; *****************************************************************************
;
; Stop - Send the Stop signal
;
; out: Trashes r0,r1,r2,r9,r11
;
ts_Stop ROUT
MOV R9,R14
MOV R0, #0 ; clock HI, data LO
MOV R1, #1
BL ts_SetC1C0
; Delay here must be >= 4.0 microsecs
MOV R0, #1 ; clock HI, data HI
MOV R1, #1
BL ts_SetC1C0
MOV PC,R9
; *****************************************************************************
;
; TXByte - Transmit a byte
;
; in: R0 = byte to be transmitted
;
; out: Trashes r0,r1,r2,r3,r4,r5,r9,r10,r11
;
ts_TXByte ROUT
MOV R9, R14
MOV R4, R0 ; byte goes into R4
MOV R5, #&80 ; 2^7 the bit mask
10
ANDS R0, R4, R5 ; zero if bit is zero
MOVNE R0, #1
BL ts_ClockData ; send the bit
MOVS R5, R5, LSR #1
BNE %BT10
MOV PC, R9
; *****************************************************************************
;
; RXByte - Receive a byte
;
; out: R0 = byte received
; Trashes r1,r2,r3,r4,r9,r11
;
ts_RXByte ROUT
MOV R9, R14
MOV R3, #0 ; byte:=0
MOV R2, #IOC
MOV R4, #7
MOV R0, #1 ; clock LO, data HI
MOV R1, #0
BL ts_SetC1C0
10
MOV R0, #1 ; pulse clock HI
MOV R1, #1
BL ts_SetC1C0CheckClock
LDRB R1, [R2, #IOCControl] ; get the data from IOC
AND R1, R1, #1
ADD R3, R1, R3, LSL #1 ; byte:=byte*2+(IOC?0)AND1
MOV R0, #1 ; return clock LO
MOV R1, #0
BL ts_SetC1C0
SUBS R4, R4, #1
BCS %BT10
MOV R0, R3 ; return the result in R0
MOV PC, R9
LTORG
END
This diff is collapsed.
This diff is collapsed.
; > TestSrc.IOC
TTL RISC OS 2+ POST IO controller
;
; This initial IOC test simply reports the content of the IRQ and FIRQ
; registers, to show any unexpected pending IRQs.
; Certain of these should really be cleared, and the effect of an
; interrupt tested.
;
;------------------------------------------------------------------------
; History
;
; Date Name Comment
; ---- ---- -------
; 18-Dec-89 ArtG Initial version
; 29-Nov-91 ArtG Added IOC bus test using mask registers
; 20-Jun-93 ArtG Modified for 29-bit IOMD test
;
;
;------------------------------------------------------------------------
[ IO_Type = "IOMD"
ts_IObase * IOMD_Base
ts_IOmask * &1fffffff
ts_IOreg1 * IOMD_VIDCUR
ts_IOreg2 * IOMD_VIDSTART
ts_IObswap * 32
ts_IOMD_ID * &D4E7
|
ts_IObase * IOC
ts_IOmask * &ff0000
ts_IOreg1 * IOCIRQMSKA
ts_IOreg2 * IOCIRQMSKB
ts_IObswap * 16
]
ts_IOCreg
MOV r0,#0 ; zero error accumulator
LDR r3, =ts_IObase
MOV r1,#(1 :SHL: 31) ; initialise bit-set test mask
0
MVN r2,r1 ; make bit-clear test mask
ANDS r4,r1,#ts_IOmask
BEQ %FT1 ; skip if this bit isn't tested
STR r1,[r3,#ts_IOreg1]
STR r2,[r3,#ts_IOreg2]
LDR r4,[r3,#ts_IOreg1]
; EOR r4, r4, r1, LSR #ts_IObswap ; check bit-set test was OK
EOR r4, r4, r1 ; check bit-set test was OK
ORR r0, r0, r4 ; accumulate errors in r0
LDR r4,[r3,#ts_IOreg2]
; EOR r4, r4, r2, LSR #ts_IObswap ; check bit-clear test was OK
EOR r4, r4, r2 ; check bit-clear test was OK
ORR r0, r0, r4 ; accumulate errors in r0
1
MOV r1, r1, LSR #1 ; shift mask downwards
TEQ r1,#0
BNE %BT0 ; and loop until all bits tested
ANDS r8, r0, #ts_IOmask
MOV pc,r14 ; return error if any bit failed
ts_IOCstat
LDR r3, =ts_IObase
MOV r0,#0
[ IO_Type = "IOMD"
LDRB r1,[r3,#IOMD_ID1]
ORR r0,r0,r1, LSL #(32-24)
LDRB r1,[r3,#IOMD_ID0]
ORR r0,r0,r1
LDR r1,=ts_IOMD_ID
CMPS r0,r1 ; check IOMD identity
MOV r0,r0,LSL #16
LDRB r1,[r3,#IOMD_VERSION]
ORR r8,r0,r1, LSL #12
MOV pc,r14
|
LDRB r1,[r3,#IOCControl]
ORR r0,r0,r1, LSL #(32 - 8)
LDRB r1,[r3,#IOCIRQSTAA]
ORR r0,r0,r1, LSL #(32 - 16)
LDRB r1,[r3,#IOCIRQSTAB]
ORR r0,r0,r1, LSL #(32 - 24)
LDRB r1,[r3,#IOCFIQSTA]
ORR r8,r0,r1
ANDS r1,r1,#0 ; return zero flag (OK)
MOV pc,r14
]
END
; > MEMC1
; MEMC interface file - MEMC1 version
; Created by TMD 10-Aug-90
VInit * &03600000
VStart * &03620000
VEnd * &03640000
CInit * &03660000
; SStart * &03680000
; SEnd * &036A0000
; SPtr * &036C0000
; *****************************************************************************
;
; SetDAG - Program DMA address generator R1 with physical address R0
;
; in: r0 = physical address
; r1 = index of DMA address generator to program, as defined in vdudecl
;
; out: All registers preserved, operation ignored if illegal
;
[ {FALSE}
SetDAG ENTRY "r0"
CMP r1, #MEMCDAG_MaxReason
EXIT HI
ADR r14, DAGAddressTable
LDR r14, [r14, r1, LSL #2] ; load base address in MEMC1
MOV r0, r0, LSR #4 ; bottom 4 bits irrelevant
CMP r0, #(1 :SHL: 15) ; ensure in range
ORRCC r14, r14, r0, LSL #2
STRCC r14, [r14] ; any old data will do
EXIT
GBLA DAGIndex
DAGIndex SETA 0
MACRO
DAGTab $reason, $address
ASSERT ($reason)=DAGIndex
& $address
DAGIndex SETA DAGIndex + 1
MEND
DAGAddressTable
DAGTab MEMCDAG_VInit, VInit
DAGTab MEMCDAG_VStart, VStart
DAGTab MEMCDAG_VEnd, VEnd
DAGTab MEMCDAG_CInit, CInit
]
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; CAM manipulation utility routines
BangCamUpdate ROUT
; R2 = CAM entry no
; R3 = logaddr
; R9 = current MEMC value
; R11 = PPL
; set and update tables
MOV R4, #0
LDR R4, [R4, #CamEntriesPointer]
ORR r0, r3, r11, LSL #28 ; top nibble is PPL
STR r0, [R4, R2, LSL #2]
BangCam
; r0 corrupted
; r1 corrupted
; R2 = CAM entry no
; R3 = logaddr
; r4 corrupted
; r5 spare!
; r6 corrupted
; r7, r8 spare
; R9 = current MEMC value
; r10 spare
; R11 = PPL
; r12 spare
AND R4, R9, #&C ; pagesize
ADR R0, PageMangleTable
LDR R0, [R0, R4] ; load data table pointer
MOV R4, #0
01 LDR R1, [R0], #4
CMP R1, #-1
BEQ %FT02
AND R6, R2, R1
LDR R1, [R0], #4
CMP R1, #0
RSBMI R1, R1, #0
ORRPL R4, R4, R6, LSL R1
ORRMI R4, R4, R6, LSR R1
B %BT01
02 LDR R1, [R0], #4
CMP R1, #-1
BEQ %FT03
AND R6, R3, R1
LDR R1, [R0], #4
CMP R1, #0
RSBMI R1, R1, #0
ORRPL R4, R4, R6, LSL R1
ORRMI R4, R4, R6, LSR R1
B %BT02
03 ORR R4, R4, #CAM
ORR R4, R4, R11, LSL #8 ; stuff in PPL
STR R4, [R4] ; and write it
MOV PC, LR
; Data to drive CAM setting
PageMangleTable
& PageMangle4K
& PageMangle8K
& PageMangle16K
& PageMangle32K
; For each page size, pairs of masks and shift factors to put the bits in the
; right place. Two sets: operations on Physical Page Number, operations on
; Logical Page Number.
; Shifts are Shift Left values (<<). Each section terminated by -1
PageMangle4K
; PPN:
& 2_011111111
& 0 ; bits in right place
& -1
; LPN:
& 2_1100000000000:SHL:12
& (11-12)-12 ; LPN[12:11] -> A[11:10]
& 2_0011111111111:SHL:12
& (22-10)-12 ; LPN[10:0 ] -> A[22:12]
& -1
PageMangle8K
; PPN:
& 2_010000000
& 7-7 ; PPN[7] -> A[7]
& 2_001000000
& 0-6 ; PPN[6] -> A[0]
& 2_000111111
& 6-5 ; PPN[5:0] -> A[6:1]
& -1
; LPN:
& 2_110000000000:SHL:13
& (11-11)-13 ; LPN[11:10] -> A[11:10]
& 2_001111111111:SHL:13
& (22-9)-13 ; LPN[9:0] -> A[22:13]
& -1
PageMangle16K
; PPN:
& 2_010000000
& 7-7 ; PPN[7] -> A[7]
& 2_001100000
& 1-6 ; PPN[6:5] -> A[1:0]
& 2_000011111
& 6-4 ; PPN[4:0] -> A[6:2]
& -1
; LPN:
& 2_11000000000:SHL:14
& (11-10)-14 ; LPN[10:9] -> A[11:10]
& 2_00111111111:SHL:14
& (22-8)-14 ; LPN[8:0] -> A[22:14]
& -1
PageMangle32K
; PPN:
& 2_100000000
& 12-8 ; PPN[8] -> A[12]
& 2_010000000
& 7-7 ; PPN[7] -> A[7]
& 2_001000000
& 1-6 ; PPN[6] -> A[1]
& 2_000100000
& 2-5 ; PPN[5] -> A[2]
& 2_000010000
& 0-4 ; PPN[4] -> A[0]
& 2_000001111
& 6-3 ; PPN[3:0] -> A[6:3]
& -1
; LPN:
& 2_1100000000:SHL:15
& (11-9)-15 ; LPN[9:8] -> A[11:10]
& 2_0011111111:SHL:15
& (22-7)-15 ; LPN[7:0] -> A[22:15]
& -1
PageSizes
& 4*1024 ; 0 is 4K
& 8*1024 ; 4 is 8K
& 16*1024 ; 8 is 16
& 32*1024 ; C is 32
PageShifts
= 12, 13, 0, 14 ; 1 2 3 4
= 0, 0, 0, 15 ; 5 6 7 8
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; SWI OS_UpdateMEMC: Read/write MEMC1 control register
SSETMEMC ROUT
AND r10, r0, r1
MOV r12, #0
TEQP pc, #SVC_mode+I_bit+F_bit
LDR r0, [r12, #MEMC_CR_SoftCopy] ; return old value
BIC r11, r0, r1
ORR r11, r11, R10
BIC r11, r11, #&FF000000
BIC r11, r11, #&00F00000
ORR r11, r11, #MEMCADR
STR r11, [r12, #MEMC_CR_SoftCopy]
STR r11, [r11]
TEQP pc, #SVC_mode+I_bit
ExitSWIHandler
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; ClearPhysRAM - Routine to clear "all" memory
;
; While this routine is running, keyboard IRQs may happen. For this reason
; it avoids LogRAM 0..31 (where hardware IRQ vector is) and PhysRAM
; 0..31 where the IRQ workspace is.
;
ClearPhysRAM ROUT
MOV R0, #0
MOV R1, #0
MOV R2, #0
MOV R3, #0
MOV R4, #0
MOV R5, #0
MOV R6, #0
MOV R11, #0
MOV R8, #PhysRam
CMP R13, #512*1024
ADDEQ R10, R8, #(512-64)*1024 ; get address that's logram 0
ADDNE R10, R8, #512*1024
ADD R13, R13, #PhysRam ; end of memory
ADD R8, R8, #4*8 ; skip minimal startup workspace
10 CMP R8, R10
ADDEQ R8, R8, #4*8 ; skip physram that's logram 0
STMNEIA R8!, {R0-R6, r11}
CMP R8, R13
BNE %BT10
SUB R13, R13, #PhysRam
LDR R0, =OsbyteVars + :INDEX: LastBREAK
MOV R1, #&80
STRB R1, [R0] ; flag the fact that RAM cleared
MOV pc, lr
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;
; InitMEMC - Initialise memory controller
;
InitMEMC ROUT
LDR R0, ResetMemC_Value
STR R0, [R0] ; set ROM access times, refresh on flyback, no DMA
MOV pc, lr
; -> MemSize
; (non-destructive) algorithm to determine MEMC RAM configuration
;
; Dave Flynn and Alasdair Thomas
; 17-March-87
;
; Spooling checkered by NRaine and SSwales !
; 8MByte check bodged in by APT
;
; NOTE: Routines MemSize and TimeCPU are called by the power-on test software,
; so their specifications MUST not change.
;
; Set MEMC for 32-k page then analyse signature of possible
; external RAM configurations...
; The configurations are:
;
; Ram Size Page Size Configuration (Phys RAM) Signature
;--------------------------------------------------------------------
; 16MByte 32k 4*32*1Mx1 A13,A20,A21,A22,A23,A23.5 distinct
; 16MByte 32k 16*8*256kx4 A13,A20,A21,A22,A23,A23.5 distinct
;
; 12MByte 32k 3*32*1Mx1 A13,A20,A21,A22,A23 OK, A23.5 fail
; 12MByte 32k 12*8*256kx4 A13,A20,A21,A22,A23 OK, A23.5 fail
;
; 8MByte 32k 2*32*1Mx1 A13,A20,A21,A22 distinct, A23 fail
; 8MByte 32k 8*8*256kx4 A13,A20,A21,A22 distinct, A23 fail
;
; 4Mbyte 32k 32*1Mx1 A13,A21,A20 distinct, A22,A23 fail
; 4Mbyte 32k 4*8*256kx4 A13,A21,A20 distinct, A22,A23 fail
;
; 2Mbyte 32k expandable 2*8*256kx4 A13,A20 distinct, A21 fails
; 2Mbyte ??? 16k fixed 2*8*256kx4 A13,A21 distinct, A20 fails
;
; 1Mbyte 8k 32*256kx1 A13,A20 fail, A19,A18,A12 distinct
; 1Mbyte 8k 8*256kx1 A13,A20 fail, A19,A18,A12 distinct
; 1Mbyte 8k 4*8*64kx4 A13,A20 fail, A19,A18,A12 distinct
;
; 512Kbyte 8k expandable 2*8*64kx4 A13,A20,A19 fail, A12,A18 distinct
; 512Kbyte 4k fixed 2*8*64kx4 A13,A20,A12 fail, A19,A18 distinct
;
; 256Kbyte 4K 8*64kx4 A13,A20,A12,A18 fail, A21,A19 ok
; 256Kbyte 4K 32*64kx1 A13,A20,A12,A18 fail, A21,A19 ok
;
Z_Flag * &40000000
; MemSize routine... enter with 32K pagesize set
; R0 returns page size
; R1 returns memory size
; R2 returns value set in MEMC
; uses R3-R7
MemSize ROUT
MOV r7, lr
MOV r0, #PhysRam
ADD r1, r0, #A13
BL DistinctAddresses
BNE %10
ADD r1, r0, #A21
BL DistinctAddresses
MOVNE r0, #Page32K
MOVNE r1, #2048*1024
BNE MemSizeDone
MOV r0, #PhysRam
ADD r1, r0, #4*1024*1024
BL DistinctAddresses
MOVNE r0, #Page32K
MOVNE r1, #4*1024*1024
BNE MemSizeDone
MOV r0, #PhysRam
ADD r1, r0, #8*1024*1024
BL DistinctAddresses
MOVNE r0, #Page32K
MOVNE r1, #8*1024*1024
BNE MemSizeDone
MOV r0, #PhysRam
ADD r1, r0, #12*1024*1024
BL DistinctAddresses
MOV r0, #Page32K
MOVNE r1, #12*1024*1024
MOVEQ r1, #16*1024*1024
B MemSizeDone
10 ADD r1, r0, #A20
BL DistinctAddresses
BNE %20
MOV r0, #Page16K
MOV r1, #2048*1024
B MemSizeDone
20 ADD r1, r0, #A19
BL DistinctAddresses
BEQ %30
MOV r0, #Page8K
MOV r1, #512*1024
B MemSizeDone
30 ADD r1, r0, #A18
BL DistinctAddresses
BEQ %40
MOV r0, #Page4K
MOV r1, #256*1024
B MemSizeDone
40 ADD r1, r0, #A12
BL DistinctAddresses
BEQ %50
MOV r0, #Page4K
MOV r1, #512*1024
B MemSizeDone
50 MOV r0, #Page8K
MOV r1, #1024*1024
MemSizeDone
LDR r2, ResetMemC_Value
BIC r2, r2, #&C
ORR r2, r2, r0
STR r2, [r2] ; set MEMC to right state
MOV pc, r7
; DistinctAddresses routine...
; r0,r1 are the addresses to check
; uses r2-5
; writes interleaved patterns (to prevent dynamic storage...)
; checks writing every bit low and high...
; return Z-flag set if distinct
DistinctAddresses ROUT
LDR r2, [r0] ; preserve
LDR r3, [r1]
LDR r4, Pattern
STR r4, [r0] ; mark first
MOV r5, r4, ROR #16
STR r5, [r1] ; mark second
LDR r5, [r0]
CMP r5, r4 ; check first
BNE %10 ; exit with Z clear
LDR r5, [r1] ; check second
CMP r5, r4, ROR #16 ; clear Z if not same
BNE %10
; now check inverse bit writes
STR r4, [r1] ; mark second
MOV r5, r4, ROR #16
STR r5, [r0] ; mark first
LDR r5, [r1]
CMP r5, r4 ; check second
BNE %10 ; exit with Z clear
LDR r5, [r0] ; check first
CMP r5, r4, ROR #16 ; clear Z if not same
10 STR r3, [r1] ; restore
STR r2, [r0]
ORREQ lr, lr, #Z_Flag
BICNE lr, lr, #Z_Flag
MOVS pc, lr
Pattern
& &AAFF5500 ; shiftable bit check pattern
; init state with masked out page size
ResetMemC_Value
& &E010C :OR: MEMCADR ; slugged ROMs + flyback refresh only + 32K page
; Constants
;
A21 * 1:SHL:21
A20 * 1:SHL:20
A19 * 1:SHL:19
A18 * 1:SHL:18
A13 * 1:SHL:13
A12 * 1:SHL:12
Page32K * &C ; in MEMC control reg patterns...
Page16K * &8
Page8K * &4
Page4K * &0
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; In r0-r6 trashable
; r9 = Current MEMC CR
; Out r9 MEMC value with slowest ROM speed, correct pagesize
; r7 processor speed in kHz, tbs -> MEMC1a
ncpuloops * 1024 ; don't go longer than 4ms without refresh !
nmulloops * 128
TimeCPU ROUT
BIC r9, r9, #3 :SHL: 8
STR r9, [r9] ; turn off refresh for a bit
; Time CPU/Memory speed
LDR r1, =&7FFE ; 32K @ 2MHz = ~16ms limit
MOV r3, #IOC
MOV r0, r1, LSR #8
STRB r1, [r3, #Timer1LL]
STRB r0, [r3, #Timer1LH]
LDR r0, =ncpuloops
STRB r0, [r3, #Timer1GO] ; start the timer NOW
B %FT10 ; Looks superfluous, but is required
; to get ncpuloops pipeline breaks
10 SUBS r0, r0, #1 ; 1S
BNE %BT10 ; 1N + 2S
STRB r0, [r3, #Timer1LR] ; latch count NOW
LDRB r2, [r3, #Timer1CL]
LDRB r0, [r3, #Timer1CH]
ADD r2, r2, r0, LSL #8 ; count after looping is ...
SUB r2, r1, r2 ; decrements !
MOV r2, r2, LSR #1 ; IOC clock decrements at 2MHz
; Time CPU/MEMC Multiply time
MOV r4, #-1 ; Gives worst case MUL
MOV r0, r1, LSR #8
STRB r1, [r3, #Timer1LL]
STRB r0, [r3, #Timer1LH]
LDR r0, =nmulloops
STRB r0, [r3, #Timer1GO] ; start the timer NOW
B %FT20 ; Looks superfluous, but is required
; to get nmulloops pipeline breaks
20 MUL r5, r4, r4 ; 1S + 16I
MUL r5, r4, r4 ; 1S + 16I
SUBS r0, r0, #1 ; 1S
BNE %BT20 ; 1N + 2S
STRB r0, [r3, #Timer1LR] ; latch count NOW
LDRB r4, [r3, #Timer1CL]
LDRB r0, [r3, #Timer1CH]
ADD r4, r4, r0, LSL #8 ; count after looping is ...
SUB r4, r1, r4 ; decrements !
MOV r4, r4, LSR #1 ; IOC clock decrements at 2MHz
ORR r9, r9, #1 :SHL: 8 ; set refresh on flyback
STR r9, [r9] ; restore MEMC state a.s.a.p.
; In ROM - each cpu loop took 4R cycles @ 8/f*500ns/cycle
LDR r0, =4*(8*500/1000)*ncpuloops*1000
DivRem r7, r0, r2, r1 ; r2 preserved
MOV r0, #&80 ; At 8 MHz and below, run fast ROMs
LDR r1, =8050 ; Over 8 MHz, need medium ROMs
CMP r7, r1
MOVHI r0, #&40
LDR r1, =13000 ; Over 13 MHz, need slowest ROMs
CMP r7, r1
MOVHI r0, #&00
ORR r9, r9, r0
STR r9, [r9] ; Set ROM speed appropriately
ASSERT ncpuloops = 8*nmulloops ; for given ratio cutoff <------------
MOV r4, r4, LSL #10 ; *1024 to get resolution on divide
DivRem r0, r4, r2, r1
LDR r1, =1100 ; Cutoff point; MEMC1 longer than this
CMP r0, r1
ORRLO r7, r7, #1 :SHL: 16 ; Note MEMC1a prescence
MOV pc, lr
; Typical figures give (in ROM at 8MHz):
; MEMC1 2048 CPU, 2432 MEMC -> MUL ratio 1216
; MEMC1a 2048 864 432
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
END
This diff is collapsed.
This diff is collapsed.
;> MEM2C
;
; RISC OS 2+ BOOT TEST SOFTWARE
; MEMORY TEST 2 VERSION A.
; BRIAN RICE 30-10-89
; 06-Apr-90 ArtG 0.1 Test variable memory size
;
; This file will perform a simple test on all DRAM.
; The test code for this test was taken from thhe A680 Quick memory
; test software. The software was copied straight but the number of times
; the test looped arround was cut down to two loops, because of time
; constraints when testing the memory.
Test_wks_msize * &40 ; Space for test block size
Test_wks_return1 * &44 ; Space for return addresses
Test_wks_return2 * &48
Test_code_off * &4C ; Where testing starts
test_size * 13 * 4 ; Size of test group
test_mem_rsvd * Test_code_off+test_mem_template_end-test_mem_template
;
; Quick test the RAM (pre boot style)
;
ts_RamTest ROUT
MOV r13,r0
STR r14,[r13,#Test_wks_return1]
STR r1,[r13,#Test_wks_msize]
LDR r0, test_quick_pattern
BL test_mem_code
ORRS r0,r0,r0
BNE test_mem_quit
;
LDR r0, test_quick_pattern
MVN r0, r0 ; inverse pattern
BL test_mem_code
ORRS r0,r0,r0
test_mem_quit
ADR r12,%22
BEQ %10
; If fault detected, exit with zero flag clear, r0 pointing to failing
; location, r1 containing faulty data and r2 pointing a suitable error
; message indicating whether all-0 or all-1 data was expected.
LDR r2,[r14] ; fetch failing instructiom
ANDS r2,r2,#1 ; calculate expected data
ADREQ r12,%20 ; and load suitable message
ADRNE r12,%21
MOVS r0,r0 ; with zero flag set for PASS.
10
LDR pc,[r13,#Test_wks_return1]
; Fail messages indicate incorrect data read after WRote 0 or Wrote 1
; to all bits at that location.
20
= "WR-0 RD",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0
21
= "WR-1 RD",&88,&ff,&ff,&ff,&ff,&ff,&ff,&ff,&ff,0
22
= "??",0
ALIGN
test_quick_pattern & &0f76
; Large Memory test. Generates the write + test routines in memory
; then calls them. The routine tests patterns as defined by the bottom
; 13 bits of r0.
;
; N.B. The test start address must be calculated to ensure that
; the loops finish exactly with r0 equal to End_memory
;
; The routine returns with eq true if the memory is OK.
test_mem_code
ROUT
STR r14, [r13, #Test_wks_return2]
;
; Copy the ram test code into low ram, modifying MOV instructions
; to MVN in accordance with the test pattern.
;
ADR r1, test_mem_template
ADD r2, r13, #Test_code_off
LDMIA r1!, {r3-r4} ; copy initial 2 instrucions
STMIA r2!, {r3-r4}
MOV r4, #1
0 MOVS r0, r0, ROR #1
LDR r3, [r1], #4
ORRCS r3, r3, #&00400000 ; Convert MOV => MVN
STR r3, [r2], #4
ADD r4, r4, #1
CMP r4, #13
BLE %B0
;
; Copy the load loop control and verify start instructions
;
LDMIA r1!, {r5-r9}
STMIA r2!, {r5-r9}
;
; Copy and modify the CMP instructions
;
MOV r0, r0, ROR #32-13
MOV r4, #1
1 MOVS r0, r0, ROR #1
LDR r3, [r1], #4
ORRCS r3, r3, #&00200000 ; Convert CMP => cmn
ORRCS r3, r3, #&00000001 ; Convert #0 => #1
STR r3, [r2], #4
ADD r4, r4, #1
CMP r4, #13
BLE %B1
;
; Copy the verify loop control and finishing-up instructions
;
LDMIA r1!, {r5-r12}
STMIA r2!, {r5-r12}
LDMIA r1!, {r5-r12}
STMIA r2!, {r5-r12}
LDMIA r1!, {r5-r12}
STMIA r2!, {r5-r12}
; check we've copied enough
ASSERT ((test_mem_stadd - test_mem_chk) = (24 * 4))
;
; Calculate the test start and end addresses
;
LDR r0, [r13, #Test_wks_msize] ; size of test area
ADD r14, r13, r0 ; end of test area
SUB r1, r0, #test_mem_rsvd ; testable size
MOV r2, #test_size ; adjust r1 to (r1 / 13*4) * (13*4)
DivRem r3, r1, r2, r4
MUL r1, r3, r2
SUB r0, r14, r1 ; rounded test start address
; Do it.
MOV r1, #Test_code_off
ADD r1, r1, r13 ; pointer to copied code
MOV pc, r1
;
; The following code is copied (and modified) into RAM for execution
;
test_mem_template
ROUT
STR r0, test_mem_stadd ; save initial RAM address
STR r13, test_mem_base ; save test area base address
MOV r1, #0 ; Converted to MVN if bit = 1
MOV r2, #0 ; Converted to MVN if bit = 1
MOV r3, #0 ; Converted to MVN if bit = 1
MOV r4, #0 ; Converted to MVN if bit = 1
MOV r5, #0 ; Converted to MVN if bit = 1
MOV r6, #0 ; Converted to MVN if bit = 1
MOV r7, #0 ; Converted to MVN if bit = 1
MOV r8, #0 ; Converted to MVN if bit = 1
MOV r9, #0 ; Converted to MVN if bit = 1
MOV r10, #0 ; Converted to MVN if bit = 1
MOV r11, #0 ; Converted to MVN if bit = 1
MOV r12, #0 ; Converted to MVN if bit = 1
MOV r13, #0 ; Converted to MVN if bit = 1
0
STMIA r0!, {r1-r13}
CMP r0, r14
BLO %B0
LDR r0, test_mem_stadd
1
LDMIA r0!, {r1-r13}
2
CMP r1, #0 ; Converted to cmn if bit = 1
CMPEQ r2, #0 ; Converted to cmneq if bit = 1
CMPEQ r3, #0 ; Converted to cmneq if bit = 1
CMPEQ r4, #0 ; Converted to cmneq if bit = 1
CMPEQ r5, #0 ; Converted to cmneq if bit = 1
CMPEQ r6, #0 ; Converted to cmneq if bit = 1
CMPEQ r7, #0 ; Converted to cmneq if bit = 1
CMPEQ r8, #0 ; Converted to cmneq if bit = 1
CMPEQ r9, #0 ; Converted to cmneq if bit = 1
CMPEQ r10, #0 ; Converted to cmneq if bit = 1
CMPEQ r11, #0 ; Converted to cmneq if bit = 1
CMPEQ r12, #0 ; Converted to cmneq if bit = 1
CMPEQ r13, #0 ; Converted to cmneq if bit = 1
test_mem_chk
BNE %F5 ; go report fault data
CMP r0, r14
BLO %B1 ; else loop for next batch
MOVS r0, #0 ; All OK : return with NULL r0
4
LDR r13,test_mem_base
LDR pc, [r13, #Test_wks_return2]
; Failed : repeat the last batch of tests one at a time, to determine
; the first failing address and data.
; Note that the test instructions are copied to %8 to permit individual
; execution, and %7 is overwritten with an instruction used to copy
; the failing data into r1. Change this code very carefully !
5
LDR r14,%2 ; Obtain first test in the set
STR r14,%8 ; and re-execute it
SUB r0,r0,#(13*4) ; adjust pointer to bad data
ADR r14,%2 ; point to first test.
7
B %8 ; make sure %8 is refetched
8
& 0 ; redo the test here :
BNE %4 ; if it failed, exit with
; r0 = ptr to memory
; r1 = wrongly read data
; r14 => failing instruction
LDR r1,[r14,#4]! ;fetch next instruction
AND r1,r1,#&f0000 ;make an instruction
MOV r1,r1,LSR #16 ;to copy the next register
ORR r1,r1,#&E1000000 ;down to r1
ORR r1,r1,#&00A00000 ;e.g. CMPEQ r10,#0
ORR r1,r1,#&00001000
STR r1,%7 ;and put it at %7
LDR r1,[r14] ;then copy the next test
STR r1,%8 ;to %8
ADD r0,r0,#4 ;bump the fault pointer
B %7 ;and execute %7 and %8.
test_mem_stadd ; address of first test location
& 0
test_mem_base
& 0 ; address of test block
test_mem_template_end
;
; Copy the L2 page table from r1 to r0, then remap the translation table's
; base address in the MMU to point to an L1 page table within it.
;
ROUT
ts_remap_ttab
MOV r2,#FixedAreasL2Size
ADD r0,r0,r2 ; point to locations in PhysSpace
ADD r0,r0,#PhysSpace
ADD r1,r1,r2
ADD r1,r1,#PhysSpace
10
ASSERT ((FixedAreasL2Size :AND: ((8*4)-1)) = 0)
LDMDB r1!,{r3-r10} ; copy the page & section tables
STMDB r0!,{r3-r10}
SUBS r2,r2,#(8*4)
BNE %BT10
SUB r9,r1,r0 ; r9 = offset from original to copy
ADD r0, r0, #DRAMOffset_L1PT-DRAMOffset_L2PT ; r0 -> copy of L1Phys
SUB r10, r0, #PhysSpace ; keep real address of L1PT for MMU
ADD r2,r0,#((1 :SHL: (32-20))*4) ; size of L1PT - 1 word per meg of memory
11 LDR r3,[r0],#4 ; check each L1 table entry
ANDS r4,r3,#3
CMPS r4,#L1_Page ; if it's page mapped ..
SUBEQ r3,r3,r9 ; adjust the page table base address
STREQ r3,[r0,#-4]
CMPS r0,r2 ; repeat for all the level 1 table
BNE %BT11
SetCop r10, CR_TTabBase ; set up MMU pointer to L1
SetCop r0, CR_IDCFlush ; flush cache + TLB just in case
SetCop r0, CR_TLBFlush ; (data written is irrelevant)
MOV pc,r14
END
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
; > TestMain
; Main assembly file for isolated assembly of machine test software
MEMCADR * &3600000
ROM * &3800000
[ MEMC_Type = "IOMD"
VideoPhysRam * &02000000 ; Amazing - it's in the same place!
DRAM0PhysRam * &10000000 ; 4 DRAM banks
DRAM1PhysRam * &14000000
DRAM2PhysRam * &18000000
DRAM3PhysRam * &1C000000
DRAMBaseAddressMask * &1C000000 ; used to mask off bits after stealing video RAM
PhysSpaceSize * &20000000 ; IOMD physical map is 512M big
PhysROM * &00000000 ; and real ROM starts at 0
SAMLength * 512*4 ; SAM length in bytes for 1 bank of VRAM
EASISpacePhys * &08000000
EASISpace * PhysSpace + EASISpacePhys
|
VideoPhysRam * &02000000
PhysSpaceSize * &04000000 ; MEMC1 physical map is 64M big
PhysROM * &03800000
PhysRamPhys * &02000000 ; physical space starts here
]
ORG ROM
GET TestSrc/Begin
CONT
ADRL r2,TestVIDCTAB
LDR r0,=IOMD_MonitorType
LDR r0,[r0]
ANDS r0,r0,#IOMD_MonitorIDMask
ADDEQ r2,r2,#(TestVVIDCTAB-TestVIDCTAB)
MOV r0,#ts_VIDCPhys
08 LDR r1, [r2],#4
CMP r1, #-1
STRNE r1, [r0]
BNE %BT08
MOV r9,#0
10
ORR r9,r9,#&40000000
STR r9,[r0] ; write the border colour
ADD r9,r9,#&00000005
ADD r9,r9,#&00000300
ADD r9,r9,#&00010000
AND r9,r9,#&00ffffff
MOV r1,#&10000
12 ADDS r1,r1,#(-1)
BNE %BT12
B %BT10
;
; The RISC-OS MEMC setup code is re-used to ensure similar
; detection of memory configuration. The MEMC1 code is modified only
; to remove an unnecessary function.
GBLL Module
Module SETL {FALSE}
GBLL AssembleSAtest
AssembleSAtest SETL {FALSE}
DynAreaFlags_DoublyMapped * 1 :SHL: 6
DynAreaFlags_NotCacheable * 1 :SHL: 5
DynAreaFlags_NotBufferable * 1 :SHL: 4
DynAreaFlags_APBits * 15 :SHL: 0 ; currently onl
END
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment