如何在裸金属中使用LDREX和MMU用于pi2-arm cortexA7

时间:2017-07-28 04:25:11

标签: assembly raspberry-pi2 bare-metal mmu

  

块引用

---- ----描述

我正在尝试在pi2裸机中运行Splash2基准测试。 所以我修改pi2的pthread库。 在实现中,如果MUTEX_LOCK(...),我使用指令LDREX,那么函数失败。 如果我使用LDR替换LDREX,该功能适用​​于单核的情况。 当涉及到多核时,它有时会失败。

---- ----问题

如何让LDREX正常工作? 本地/全球监测有什么应该做的吗?

我尝试打开MMU并将pthread内存会话设置为可在bootcode中共享。 但不确定MMU是否正常工作。 以下测试是进行特殊的内存映射。 结果是

>before 0c000000 : 45515555
>after 0c000000 : 00000666
>_before 0a000000 : aaaaabaa
>_after 0a000000 : 00000666

--- ---代码 bootcode.s

_start_MMU:
//-------------------------------------------------------------------
// Cortex-A7 MMU Configuration
// Set translation table base
//-------------------------------------------------------------------
    // Cortex-A7 supports two translation tables
    // Configure translation table base (TTB) control register cp15,c2
    // to a value of all zeros, indicates we are using TTB register 0.
    MOV     r0,#0x0
    MCR     p15, 0, r0, c2, c0, 2
    // write the address of our page table base to TTB register 0
    LDR     r0,=TTB_BASE
    MOV     r1, #0x08                   // RGN=b01  (outer cacheable write-back cached, write allocate)
                                        // S=0      (translation table walk to non-shared memory)
    ORR     r1,r1,#0x40                 // IRGN=b01 (inner cacheability for the translation table walk is Write-back Write-allocate)
    ORR     r0,r0,r1                    
    MCR     p15, 0, r0, c2, c0, 0     
//-------------------------------------------------------------------
// PAGE TABLE generation 
//wei: ref to 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 now contains full level1 descriptor to write
    ORR     r3, r3, #0b0000000010000    // Set XN bit
    STR     r3, [r0, r1, LSL#2]         // Str table entry at 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 to align to 1MB boundaries
    ORR     r3, r2, r1, LSL#20          // Setup the 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 is for pthread used
    LDR     r4,=0x080                   // loop region
    LDR     r1,=0x010               // loop counter 
init_pthread:
    ORR     r3, r2, r4, LSL#20          // R3 now contains full level1 descriptor to 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 to align to 1MB boundaries
    ORR     r3, r2, r1, LSL#20          // Setup the 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 to align to 1MB boundaries
    ORR     r3, r2, r1, LSL#20          // Setup the 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 to align to 1MB boundaries
    STR     r3, [r0, r1, LSL#2]         // str table entry

//-------------------------------------------------------------------
// Setup domain control register - Enable all domains to client mode
//-------------------------------------------------------------------
    MRC     p15, 0, r0, c3, c0, 0       // Read Domain Access Control Register
    LDR     r0, =0x55555555             // Initialize every domain entry to b01 (client)
    MCR     p15, 0, r0, c3, c0, 0       // Write Domain Access Control Register          
//-------------------------------------------------------------------
// Enable MMU and branch to __main
// Leaving the caches disabled until after scatter loading.
//-------------------------------------------------------------------
    MRC     p15, 0, r0, c1, c0, 0       // Read CP15 System Control register
    BIC     r0, r0, #(0x1 << 12)        // Clear I bit 12 to disable I Cache
    BIC     r0, r0, #(0x1 <<  2)        // Clear C bit  2 to disable D Cache
    BIC     r0, r0, #0x2                // Clear A bit  1 to disable strict alignment fault checking
    ORR     r0, r0, #0x1                // Set M bit 0 to enable MMU before scatter loading
    MCR     p15, 0, r0, c1, c0, 0       // Write CP15 System Control register

测试MMU的C代码

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 to lock variable */
        "   orr r2, r2, %[value]" "\r\n":: [value]"r" (*mutex)
            /* spin lock implementation with 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;
}

0 个答案:

没有答案