|
|
 | | From: | thepitbullofprogramming at yahoo.com | | Subject: | need help initializing ARM11 MMU/cache | | Date: | 12 Jan 2005 15:43:14 -0800 |
|
|
 | I'm having problems initializing ARM11 to enable MMU/cache for entire SDRAM address space. Does anybody have source for a working example I can run on Integrator AP/CM1136JF-S board? Or if can possible help debug my setup described below.
I have an Integrator AP board with CM1136JF-S card. I'm using the boot monitor's "m" command to download a program which tries to initialize ARM11's MMU to use flat mapping (i.e. virtual space same as physical space) and enable cache for write-back mode. When I enable caches (i.e. set CP15 C and I bits) it crashes. If I don't enable caches or I disable C and B bits in page table entries it does not crash. So it appears address translation and protection are not causing any faults. It appears I am missing something related to cache init.
The startup code I am using was derived from the ARM9 example provided in RVDS/Examples/2.1/11/unix/emb_sw_dev/build4.
First here's a look at my scatter file showing the memory layout:
;; This file assumes the bootMonitor program will be used to load ;; image to RAM. In this case SDRAM will actually start at 0x00100000 ;; because of Integrator's memory remap for bootMonitor when REMAP=0 & S1.1=1 ;; (i.e. at reset first 1MB at base addr 0x0 is mapped to BOOTROM flash).
;; Note: Heap and stack locations are set by linker, they are not hardcoded. ;; So the routine __user_initial_stackheap() must be called to init for ARM's C library.
RAM_LOAD 0x00100000 0x07f00000 { ROM_EXEC +0 { start.o (INIT, +FIRST) ; Must have initialization code first initMMU.o ; code to create translation table and init cache/MMU * (InRoot$$Sections) ; All library sections that must be in a root region ; e.g. __main.o, __scatter*.o, * (Region$$Table) }
ER_RO +0 ; read-only text and data { * (+RO) }
ER_RW +0 ; read-write text and data { * (+RW) }
ER_ZI +0 ; bss { * (+ZI) }
TTB 0x00200000 UNINIT 0x8000 ; reserve 32KB for translation table, and do not let scatter load zero it ; also must be located at 16KB aligned address { TTB.o (+ZI) }
HEAP +0 EMPTY 0x01C00000 ; symbols used by embed_uish.s to init heap_base and heap_limit {
}
STACKS 0x07F00000 EMPTY -0x30000 ; symbols used by start.s to init stack_base and stack_limit {
} }
So my startup code calls InitMMU() routine which was taken from RVDS/Examples/2.1/11/unix/emb_sw_dev/source/926ej-s/initmmu.s. I modified this to enable C and B bits (i.e. enable write-back) in all page table entries, set page table walk cacheable, set manager instead of client, and to specify TTB location using scatter file. This routine leaves caches disabled and MMU enable before scatter load is called by ARM C lib. It invalidates the TLBs just in case.
;; Copyright ARM Ltd 2002. All rights reserved. ;; ;; This code provides basic initialization for an ARM92XT including: ;; ;; - creation of a 16KB level 1 page table in physical memory (this will probably ;; need to be changed for your target) ;; - possible modifying of this table to perform ROM/RAM remapping ;; ;; This code must be run from a privileged mode PRESERVE8
AREA InitMMU, CODE, READONLY ; name this block of code
Fault EQU 2_00 ; constant defines for level 1 pagetable Section EQU 2_0010 ; 2_ denotes a binary number B EQU 2_0100 C EQU 2_1000 TTBit EQU 2_10000 Domain EQU 2_111100000 FullAccess EQU 2_110000000000
EXPORT ttb_first_level IMPORT TTB ttb_first_level DCD TTB
EXPORT InitMMUentry
InitMMUentry FUNCTION
; ; if MMU/MPU enabled - disable it (useful for ARMulator tests) ; also disable the caches and and invalidate the TLBs ; NOTE: this would not be required from a cold reset ; 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 ; MOV r0, #0 MCR p15, 0, r0, c7, c7, 0 ; invalidate caches MCR p15, 0, r0, c8, c7, 0 ; invalidate TLBs ; ; init_ttb LDR r0, ttb_first_level ; set start of Translation Table base (16k Boundary) ORR r0, r0, #1 ; set PTE walk is inner cacheable MCR p15, 0, r0, c2, c0, 0 ; write to CP15 register 2 ; ; ; Create translation table for flat mapping ; Top 12 bits of VA is pointer into table ; Create 4096 entries from 000xxxxx to fffxxxxx ; ;
LDR r1,=0xfff ; loop counter MOV r2, #TTBit:OR:Section ; build descriptor pattern in register ORR r2, r2, #Domain:OR:FullAccess ORR r2, r2, #C:OR:B ; C=1, B=1 for cache enable and write-back mode ; init_ttb_1 ORR r3, r2, r1, LSL#20 ; use loop counter to create individual table entries STR r3, [r0, r1, LSL#2] ; str r3 at TTB base + loopcount*4 SUBS r1, r1, #1 ; decrement loop counter BPL init_ttb_1 ; ; In this example we will set the cacheable ; and bufferable attribute in the first descriptor only ; ORR r3,r3,#2_1100 ; set cachable and bufferable attributes for section 0 (3:2) STR r3,[r0] ; ie lower 1MB - this will set cache to Write Back mode
; ; init_domains ; MOV r0,#(2_01 << 30) ; must define behaviour for domain 15 (31:30), set client MOV r0,#(2_11 << 30) ; must define behaviour for domain 15 (31:30), set manager MCR p15, 0, r0, c3, c0, 0 ; write to CP15 register 5
; enable MMU
MRC p15, 0, r0, c1, c0, 0 ; read CP15 register 1 into r0 BIC r0, r0, #(0x1 <<12) ; ensure I Cache disabled BIC r0, r0, #(0x1 <<2) ; ensure D Cache disabled ORR r0, r0, #0x1 ; enable MMU before scatter loading MCR p15, 0, r0, c1, c0, 0 ; write CP15 register 1 ; ; Now the MMU is enabled, virtual to physical address translations will occur and effect the next ; instruction fetch. Even if this module is remapped, the branch instruction should be safe as it is ; contained in the pipeline. However, this should not be relied upon (as this file stands, it flat-maps ; the entire address space, so there is no problem.
BX LR ENDFUNC
END ; mark the end of this file
After returning from the ARM C lib init stuff it calls $Sub$$main() in submain.c. This routine calls cache_init() to change CP15 C and I bits to enable cache. If I remove the ifdef it call this and board crashes.
void $Sub$$main(void) { int temp; /* setTTB(100, 10) ; */ #if 0 cache_init(); // enables caches #endif #ifdef USE_SERIAL_PORT init_serial_A(); // initialize the AP serial port A #endif __asm // enable IRQs { MRS temp, CPSR BIC temp, temp, #0x80 MSR CPSR_c, temp }
$Super$$main(); // calls the original function main() }
For cache_init() routine I used an unmodified copy of the file RVDS/Examples/2.1/11/unix/emb_sw_dev/source/926ej-s/initcache.s.
;; Copyright ARM Ltd 2002. All rights reserved. ;; ;; This code enables caches on a 92X core ;; ;; It is called by $Sub$$main(), before the main application is entered ;; ;; This code must be run from a privileged mode
PRESERVE8
AREA INIT92XCACHE, CODE, READONLY ; name this block of code
EXPORT cache_init cache_init FUNCTION
; ; Set global core configurations ;=============================== ; MRC p15, 0, r0, c1, c0, 0 ; read CP15 register 1 into r0
ORR r0, r0, #(0x1 <<12) ; enable I Cache ORR r0, r0, #(0x1 <<2) ; enable D Cache
MCR p15, 0, r0, c1, c0, 0 ; write CP15 register 1 MOV pc, lr ENDFUNC
END ; mark the end of this file
I don't have a probe so I don't know why board is crashing when cache enable bits are flipped.
Below is a dump of the page table entries created (only first 10 and last 10 shown), followed by dump of important CP15 registers. Note: CP15's C and I bits are 0 so caches are disabled here. If those bits are turned on the board crashes.
Other important settings to note ... .. ARMv5 backward compatibility mode is used .. Page table entries use domain 15, AP-bits set for full access, and CP15.DAC.D15 is set to manager. .. All page table entries have TEX, C, and B bits specified to use write-back mode. .. I did not modify memory remap registers and I'm not sure what they are used for, but I dumped them below anyway. .. I think CP15.TTB0.C should be 1 (i.e. set page table walk inner cacheable) but I also tried this set to 0 and it had no effect.
0x00200000 : [0x00000dfe] TYPE=SECTION, BASE=0x00000000, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00200004 : [0x00100dfe] TYPE=SECTION, BASE=0x00000001, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00200008 : [0x00200dfe] TYPE=SECTION, BASE=0x00000002, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x0020000c : [0x00300dfe] TYPE=SECTION, BASE=0x00000003, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00200010 : [0x00400dfe] TYPE=SECTION, BASE=0x00000004, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00200014 : [0x00500dfe] TYPE=SECTION, BASE=0x00000005, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00200018 : [0x00600dfe] TYPE=SECTION, BASE=0x00000006, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x0020001c : [0x00700dfe] TYPE=SECTION, BASE=0x00000007, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00200020 : [0x00800dfe] TYPE=SECTION, BASE=0x00000008, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00200024 : [0x00900dfe] TYPE=SECTION, BASE=0x00000009, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 .... 0x00203fd4 : [0xff500dfe] TYPE=SECTION, BASE=0x00000ff5, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203fd8 : [0xff600dfe] TYPE=SECTION, BASE=0x00000ff6, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203fdc : [0xff700dfe] TYPE=SECTION, BASE=0x00000ff7, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203fe0 : [0xff800dfe] TYPE=SECTION, BASE=0x00000ff8, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203fe4 : [0xff900dfe] TYPE=SECTION, BASE=0x00000ff9, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203fe8 : [0xffa00dfe] TYPE=SECTION, BASE=0x00000ffa, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203fec : [0xffb00dfe] TYPE=SECTION, BASE=0x00000ffb, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203ff0 : [0xffc00dfe] TYPE=SECTION, BASE=0x00000ffc, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203ff4 : [0xffd00dfe] TYPE=SECTION, BASE=0x00000ffd, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203ff8 : [0xffe00dfe] TYPE=SECTION, BASE=0x00000ffe, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 0x00203ffc : [0xfff00dfe] TYPE=SECTION, BASE=0x00000fff, TEX=0x0, AP=0x3, P=0, DOMAIN=0xf, C=1, B=1 CP15: Id_Code = 0x4107b361 CP15: Cache_Type = 0x1d152152 CP15: TCM_Status = 0x00010001 CP15: TLB_Type = 0x00000800 CP15: Control = 0x00050079, EE=0, VE=0, XP=0, U=0, FI=0, IT=1, DT=1, L4=0, RR=0, V=0, I=0, Z=0, F=0, R=0, S=0, B=0, W=1, C=0, A=0, M=1 CP15: Aux_Control = 0x00000007 CP15: CP_Access_Control = 0x00000000 CP15: TTB0 = 0x00200001 CP15: TTB1 = 0x00000000 CP15: TTBC = 0x00000000 CP15: DAC = 0xc0000000 CP15: FCSE_PID = 0x00000000 CP15: Context_ID = 0x00000000 CP15: Data_Memory_Remap = 0x01c97cc8 CP15: Instr_Memory_Remap = 0x01c97cc8 CP15: DMA_Memory_Remap = 0x01c97cc8 CP15: Peripheral_Port_Memory_Remap = 0x00000000
Well that's it. If you see anything I am missing here let me know. I also tried modifying the code to enable C, I and M bits all at the same time. This did not change the behavior. Only idea I have left is to use my own abort handler to try and dump the FAR and WFAR regs.
|
|
 | | From: | thepitbullofprogramming at yahoo.com | | Subject: | Re: need help initializing ARM11 MMU/cache | | Date: | 12 Jan 2005 16:20:51 -0800 |
|
|
 | Just as quick as I posted this I found my own bug!!
The code is building page table entries to cover entire 4GB address space so I should not be setting C and B bits for every page table entry!!! I should only set these bits for the first 128MB to cover the SDRAM range. I changed this in my code and the crash problem went away. ;-)
|
|
 | | From: | Joseph | | Subject: | Re: need help initializing ARM11 MMU/cache | | Date: | Thu, 13 Jan 2005 14:51:50 +0000 |
|
|
 | thepitbullofprogramming@yahoo.com wrote:
> Just as quick as I posted this I found my own bug!! > > The code is building page table entries to cover entire 4GB address > space > so I should not be setting C and B bits for every page table entry!!! > I should only set these bits for the first 128MB to cover the SDRAM > range. I changed this in my code and the crash problem went away. ;-) >
A good book might help (my own opinion) : http://www.amazon.com/exec/obidos/ASIN/1558608745/102-4424111-6324910
It covered MMU,MPU and some of the V6 stuffs. (Can't remember if it has example code for ARM1136 MMU initialisation, but certainly covered ARM9 MMU initialisation example).
regards, Joseph
____________________________________________________ This e-mail message is intended for the addressee(s) only and may contain information that is the property of, and/or subject to a confidentiality agreement between the intended recipient(s), their organisation and/or the ARM Group of Companies. If you are not an intended recipient of this e-mail message, you should not read, copy, forward or otherwise distribute or further disclose the information in it; misuse of the contents of this e-mail message may violate various laws in your state, country or jurisdiction. If you have received this e-mail message in error, please contact the originator of this e-mail message via e-mail and delete all copies of this message from your computer or network, thank you. ____________________________________________________
|
|
 | | From: | thepitbullofprogramming at yahoo.com | | Subject: | Re: need help initializing ARM11 MMU/cache | | Date: | 18 Jan 2005 18:54:45 -0800 |
|
|
 | Joseph wrote: > A good book might help (my own opinion) : > http://www.amazon.com/exec/obidos/ASIN/1558608745/102-4424111-6324910 > > It covered MMU,MPU and some of the V6 stuffs. (Can't remember if it has > example code for ARM1136 MMU initialisation, but certainly covered ARM9 > MMU initialisation example).
I have this book!! Has very good intro to ARM MMU/cache architecture. But you still need ARM1136 manual to read write the code. It does not cover ARMv6 page entry formats but it does cover ARMv5 which ARM1136 can use in backward compatible mode. But even then they added TEX and P bits to that page entry format which are not covered by the book. Regardless the book really helped me to understand the reference manual which is not as user friendly.
PS: In addition to init code I listed earlier. You also need to set C and B bits for page table entries BEFORE the MMU is enabled and for the range of pages you wished to be cached. You should also enable the Z-bit to turn on branch prediction when you enable cache bits in CP15.
The Pitbull of Programming
|
|
|