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

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -