I am working on an Arria10 SoC which has dual ARM Cortex-A9 MPCore. And I work on bare-metal environment with Intel SoCFPGA’s hardware library(HwLib).
On the shared SDRAM, I am planning to have dedicated memory regions for each core, and a shared non-cacheable memory area. And the FPGA does not get involved in the SDRAM. But my attemps to initialize MMU fails.
Here is what I have done:
For CPU0:
static void mmu_init(void) { uint32_t *ttb1 = NULL; /* Populate the page table with sections (1 MiB regions). */ ALT_MMU_MEM_REGION_t regions[] = { /* CPU0 Memory area: 256 MB */ { .va = (void *)0x00000000, .pa = (void *)0x00000000, .size = 0x10000000, .access = ALT_MMU_AP_FULL_ACCESS, .attributes = ALT_MMU_ATTR_WBA, .shareable = ALT_MMU_TTB_S_NON_SHAREABLE, .execute = ALT_MMU_TTB_XN_DISABLE, .security = ALT_MMU_TTB_NS_SECURE }, /* CPU1 Memory area: 512 MB */ /* CPU0 MUST NOT ACCESS THIS AREA */ { .va = (void *)0x10000000, .pa = (void *)0x10000000, .size = 0x20000000, .access = ALT_MMU_AP_NO_ACCESS, .attributes = ALT_MMU_ATTR_FAULT, .shareable = ALT_MMU_TTB_S_NON_SHAREABLE, .execute = ALT_MMU_TTB_XN_DISABLE, .security = ALT_MMU_TTB_NS_SECURE }, /* Shared Memory area: 256 MB */ { .va = (void *)0x30000000, .pa = (void *)0x30000000, .size = 0x10000000, .access = ALT_MMU_AP_FULL_ACCESS, .attributes = ALT_MMU_ATTR_DEVICE_NS, .shareable = ALT_MMU_TTB_S_NON_SHAREABLE, .execute = ALT_MMU_TTB_XN_ENABLE, .security = ALT_MMU_TTB_NS_SECURE }, /* Device area: Everything else */ { .va = (void *)0x40000000, .pa = (void *)0x40000000, .size = 0xc0000000, .access = ALT_MMU_AP_FULL_ACCESS, .attributes = ALT_MMU_ATTR_DEVICE_NS, .shareable = ALT_MMU_TTB_S_NON_SHAREABLE, .execute = ALT_MMU_TTB_XN_ENABLE, .security = ALT_MMU_TTB_NS_SECURE } }; assert(ALT_E_SUCCESS == alt_mmu_init()); assert(alt_mmu_va_space_storage_required(regions, ARRAY_SIZE(regions)) <= sizeof(alt_pt_storage)); assert(ALT_E_SUCCESS == alt_mmu_va_space_create(&ttb1, regions, ARRAY_SIZE(regions), alt_pt_alloc, alt_pt_storage)); assert(ALT_E_SUCCESS == alt_mmu_va_space_enable(ttb1)); }
For CPU1: Same initialization with CPU0 and CPU1’s .access and .attributes variables swapped.
.access
.attributes
This configuration results a system hang at alt_mmu_va_space_enable() function.
alt_mmu_va_space_enable()
Since each CPU has its own MMU, I think this configuration is necessary for memory safety. I don’t see any mechanism that handles intercore MMU and since each core has its own MMU, I think that this is the only way to implement a safe shared memory. Is my method and inference right? If so, what am I doing wrong? Thanks in advance.
Are you sure the heap is correctly setup? I think it is easier to use just a pointer to test the MMU configuration instead of malloc(). A failing malloc() is no indication of a wrong MMU setup.Is the code of CPU1 in the correct area? A common fault is to "cut the branch you are sitting on". Means, you make the memory NX your code is in.