assembly - How to use LDREX and MMU in bare metal for pi2-arm cortexA7 -
blockquote
----describe----
i'm trying run splash2 benchmark in pi2 bare metal. modify pthread library pi2. in implementation if mutex_lock(...), use instruction ldrex function fail. if use ldr replace ldrex function works in situation of single core. when comes multi-core, fail.
----question----
how make ldrex works? there should local/global monitor?
i try open mmu , set pthread memory session shareable in bootcode. not sure if mmu works correctly. following test special memory mapping. result
>before 0c000000 : 45515555 >after 0c000000 : 00000666 >_before 0a000000 : aaaaabaa >_after 0a000000 : 00000666
---code--- bootcode.s
_start_mmu: //------------------------------------------------------------------- // cortex-a7 mmu configuration // set translation table base //------------------------------------------------------------------- // cortex-a7 supports 2 translation tables // configure translation table base (ttb) control register cp15,c2 // value of zeros, indicates using ttb register 0. mov r0,#0x0 mcr p15, 0, r0, c2, c0, 2 // write address of our page table base ttb register 0 ldr r0,=ttb_base mov r1, #0x08 // rgn=b01 (outer cacheable write-back cached, write allocate) // s=0 (translation table walk non-shared memory) orr r1,r1,#0x40 // irgn=b01 (inner cacheability translation table walk write-back write-allocate) orr r0,r0,r1 mcr p15, 0, r0, c2, c0, 0 //------------------------------------------------------------------- // page table generation //wei: ref mpcore mamual 5-3 //------------------------------------------------------------------- ldr r0,=ttb_base ldr r1,=0xfff // loop counter ldr r2,=0b00000000000000000000110111100010 //wei: tex-000 bc-00 -> shareable & strongly_order // ldr r2,=0b00000000000000000001110111100010 init_ttb_1://10_0000 -->fff0_0000 orr r3, r2, r1, lsl#20 // r3 contains full level1 descriptor write orr r3, r3, #0b0000000010000 // set xn bit str r3, [r0, r1, lsl#2] // str table entry @ ttb base + loopcount*4 subs r1, r1, #1 // decrement loop counter bpl init_ttb_1 //0x00000000 ldr r1,=0x00000000 // base physical address of code segment lsr r1, #20 // shift right align 1mb boundaries orr r3, r2, r1, lsl#20 // setup initial level1 descriptor again orr r3, r3, #0b0000000001100 // set cb bits orr r3, r3, #0b1000000000000 // set tex bit 12 //wei: tex-001 bc-11 -> s bit & normal str r3, [r0, r1, lsl#2] // str table entry //0x0700_0000~ 0x0800_0000 pthread used ldr r4,=0x080 // loop region ldr r1,=0x010 // loop counter init_pthread: orr r3, r2, r4, lsl#20 // r3 contains full level1 descriptor write orr r3, r3, #0b0000000000000 // set cb:00 orr r3, r3, #0b1000000000000 //set tex bit 12 orr r3, r3, #0b10000000000000000// set s bit 16 //wei: tex-001 bc-00 -> s bit & normal str r3, [r0, r4, lsl#2] subs r4, r4, #1 // subs r1, r1, #1 // decrement loop counter bpl init_pthread //0x3f000000 device ldr r1,=0x3f000000 // base physical address of code segment lsr r1, #20 // shift right align 1mb boundaries orr r3, r2, r1, lsl#20 // setup initial level1 descriptor again orr r3, r3, #0b0000000000000 // set cb:00 orr r3, r3, #0b10000000000000 // set tex bit 13 str r3, [r0, r1, lsl#2] // str table entry //--------mmu test------------------------------------------------------- ldr r1,=0x0a000000 // base physical address of code segment lsr r1, #20 // shift right align 1mb boundaries orr r3, r2, r1, lsl#20 // setup initial level1 descriptor again orr r3, r3, #0b0000000010000 // set xn bit // orr r3, r3, #0b1000000000000 // tex ldr r1,=0x0c000000 // base virtual address of code segment lsr r1, #20 // shift right align 1mb boundaries str r3, [r0, r1, lsl#2] // str table entry //------------------------------------------------------------------- // setup domain control register - enable domains client mode //------------------------------------------------------------------- mrc p15, 0, r0, c3, c0, 0 // read domain access control register ldr r0, =0x55555555 // initialize every domain entry b01 (client) mcr p15, 0, r0, c3, c0, 0 // write domain access control register //------------------------------------------------------------------- // enable mmu , branch __main // leaving caches disabled until after scatter loading. //------------------------------------------------------------------- mrc p15, 0, r0, c1, c0, 0 // read cp15 system control register bic r0, r0, #(0x1 << 12) // clear bit 12 disable cache bic r0, r0, #(0x1 << 2) // clear c bit 2 disable d cache bic r0, r0, #0x2 // clear bit 1 disable strict alignment fault checking orr r0, r0, #0x1 // set m bit 0 enable mmu before scatter loading mcr p15, 0, r0, c1, c0, 0 // write cp15 system control register
c code testing mmu
test_base = 0x0a000000; printf(">before %08x : %08x\r\n",test_base ,*test_base ); *ttb_base = 0x678; printf(">after %08x : %08x\r\n",test_base ,*test_base ); test_base = 0x0c000000; printf(">_before %08x : %08x\r\n",test_base ,*test_base ); *test_base = 0x666; printf(">_after %08x : %08x\r\n",test_base ,*test_base );
pthead.c mutex
int pthread_mutex_lock(pthread_mutex_t *mutex){ /* prepare target address of lock pool */ __asm__ __volatile__ ( " stmfd sp!,{r1-r2}" "\r\r\n" " mov r1, #0x001" "\r\n" " mov r2, #0x000" "\r\n" /* provide lock address accroding lock variable */ " orr r2, r2, %[value]" "\r\n":: [value]"r" (*mutex) /* spin lock implementation ldrex */ "0: \r\n" " ldrex r0, [r2]" "\r\n" " cmp r0, #0x000" "\r\n" " strexeq r0,r1, [r2]" "\r\n" " cmpeq r0, #0x000" "\r\n" " bne 0b\r\n" ); return 0; }
Comments
Post a Comment