blob: e767e1e135481184735e528c2dee49e1d63cc893 [file] [log] [blame]
//; Copyright Marvell Semiconductor, Inc. 2006. All rights reserved.
//;
//; This code initialises the Integrator board (eg REMAP) before calling
//; TCM Initialization and MMU Initialization if they exist.
//; this allows scatter loading to relocate code into the TCMs
//;
//; This code must be run from a privileged mode
#define Access_R_ONLY ox2
#define Access_R_W 0x3
.global InitMultiLevelMMU
InitMultiLevelMMU:
//; --- if MMU/MPU enabled - disable (useful for ARMulator tests)
MRC p15, 0, r0, c1, c0, 0 //; read CP15 register 1 into r0
BIC r0, r0, #0x1 //; clear bit 0
MCR p15, 0, r0, c1, c0, 0 //; write value back
STMFD r13!, {r0-r12,lr}
BL FLAT_MAP_SECTION
LDR r0, ttb
MCR p15, 0, r0, c2, c0, 0 //; write TTB address to CP15 register
LDR r0, =0x3 //accesses domain #0 are not checked against the access permission
MCR p15, 0, r0, c3, c0, 0 //; bits so a permission fault cannot be generated.
MRC p15, 0, r0, c1, c0, 0
ORR r0, r0, #0x1000 //; icache on
ORR r0, r0, #0x4 //; dcache on
ORR r0, r0, #0x1 //; mmu on
MCR p15, 0, r0, c1, c0, 0
NOP
LDMFD r13!, {r0-r12, lr}
BX lr
//; --- make section descriptor
//; --- r0 = section mva base
//; --- r1 = section pa base
//; --- r2 = AP
//; --- r3 = domain
//; --- r4 = c,b bit
//; --- r7 = coarse L2 page table base
//; --- return r0 = 1st level descriptor
//; --- return r1 = 1st level descriptor addr
//; bit 31-20: section base address
//; bit 19-12: SBZ
//; bit 11,10: Access Permission
//; bit 9: SBZ
//; bit 8-5: domain
//; bit 4: 1
//; bit 3: Cachable
//; bit 2: Bufferable
//; bit 1,0: 10 (section descriptor)
MK_SECTION_DS:
MOV r1, r1, LSR #20 //; | clear the last 20 bits
MOV r1, r1, LSL #20 //; | section base addr
ORR r1, r1, r2, LSL #10 //; | access permission bits
ORR r1, r1, r3, LSL #5 //; | domain
LDR r3, ttb
ORR r1, r1, r4, LSL #2 //; | shift domain
ORR r1, r1, #0x2 //; | level 1 entry is section
MOV r2, r1
MOV r1, r0, LSR #20
MOV r1, r1, LSL #2
MOV r3, r3, LSR #14
MOV r3, r3, LSL #14
ORR r1, r3, r1 //; | get the TTB entry address in r1
MOV r0, r2
BX lr
//; --- build flat map secion
FLAT_MAP_SECTION:
STMFD r13!, {r2-r9, lr}
MOV r5, #0x0
MOV r6, #0 //; counter
FLAT_MAP_SECTION_LOOP:
MOV r0, r5
MOV r1, r5
MOV r2, #Access_R_W //; access permission -- read/write
MOV r3, #0x0 //; domain #0
MOV r4, #0x0 //; default non-cacheable/non-bufferable
CMP r6, #1024 //; first 1 GB address space
MOVLT r4, #0x3 //; cacheable/bufferable
BL MK_SECTION_DS
STR r0, [r1]
ADD r5, r5, #0x100000 //; incrememt 1 MB
ADD r6, r6, #1
CMP r6, #4096 //; 4 GB address space
BLT FLAT_MAP_SECTION_LOOP //; < 4GB
LDMFD r13!, {r2-r9, lr}
BX lr
//; put ttb to a safe place, table size is 16KB
ttb: .word __ttb_base_start