块引用
---- ----描述
我正在尝试在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;
}