This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software:
I've been experimenting with the MPU background region and have noticed that calling HALcoGen's _mpuEnableBackgroundRegion_() function from sys_mpu.asm seems to perform the opposite operation compared to what I'm expecting and disables the background region. As detailed in the ARMv7-A/ARMv7-R reference manual, "When the SCTLR.BR bit is set to 0, the MPU behaves as if there is a background region that generates a Background fault memory abort on any access."
The _mpuEnableBackgroundRegion_() function sets the SCTLR.BR bit to 1 via "orr r0, r0, #0x20000". When performing a read or write to a memory address which does not correspond to a configured MPU region and does not generate a data abort by default as defined in table 6.9.2 within the TMS570LS3137 datasheet (e.g: 0x80000000), no data abort is generated. When removing the call to _mpuEnableBackgroundRegion_() (i.e: SCTLR.BR is 0), a data abort is generated.
Just want to confirm whether or not this behaviour is expected and my understanding is backwards, or if HALcoGen's "Enable" and "Disable" terminology in this case is backwards in reference to the ARM reference manual.
Thanks!
Hi Tyler Bailey,
Is it possible to share your project to re-create the issue at my end?
--
Thanks & regards,
Jagadish.
Hi Jagadish,
My apologies for the late reply. Unfortuntately, I'm unable to share the full project, however here are the details necessary to recreate the issue:
static void prvSetupDefaultMPU( void ) { /* make sure MPU is disabled */ prvMpuDisable(); /* First setup the entire flash for unprivileged read only access. */ prvMpuSetRegion(portUNPRIVILEGED_FLASH_REGION, 0x00000000, portMPU_SIZE_4MB | portMPU_REGION_ENABLE, portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Setup the first 32K for privileged only access. This is where the kernel code is placed. */ prvMpuSetRegion(portPRIVILEGED_FLASH_REGION, 0x00000000, portMPU_SIZE_32KB | portMPU_REGION_ENABLE, portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Setup the the entire RAM region for privileged read-write and unprivileged read only access */ prvMpuSetRegion(portPRIVILEGED_RAM_REGION, 0x08000000, portMPU_SIZE_512KB | portMPU_REGION_ENABLE, portMPU_PRIV_RW_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Default peripherals setup */ prvMpuSetRegion(portGENERAL_PERIPHERALS_REGION, 0xF0000000, portMPU_SIZE_256MB | portMPU_REGION_ENABLE | portMPU_SUBREGION_1_DISABLE | portMPU_SUBREGION_2_DISABLE | portMPU_SUBREGION_3_DISABLE | portMPU_SUBREGION_4_DISABLE, portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_DEVICE_NONSHAREABLE); /* Privilege System Region setup */ prvMpuSetRegion(portPRIVILEGED_SYSTEM_REGION, 0xFFF80000, portMPU_SIZE_512KB | portMPU_REGION_ENABLE, portMPU_PRIV_RW_USER_RO_NOEXEC | portMPU_DEVICE_NONSHAREABLE); /* START ADDED FOR TEST 1. */ _mpuEnableBackgroundRegion_(); /* END ADDED FOR TEST 1. */ /* Enable MPU */ prvMpuEnable(); /* START ADDED FOR TEST 2. */ // Perform a read at EMIF CS 0 uint8_t data = *(uint8_t*)(0x80000000U); /* END ADDED FOR TEST 2. */ }
static void prvSetupDefaultMPU( void ) { /* make sure MPU is disabled */ prvMpuDisable(); /* First setup the entire flash for unprivileged read only access. */ prvMpuSetRegion(portUNPRIVILEGED_FLASH_REGION, 0x00000000, portMPU_SIZE_4MB | portMPU_REGION_ENABLE, portMPU_PRIV_RO_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Setup the first 32K for privileged only access. This is where the kernel code is placed. */ prvMpuSetRegion(portPRIVILEGED_FLASH_REGION, 0x00000000, portMPU_SIZE_32KB | portMPU_REGION_ENABLE, portMPU_PRIV_RO_USER_NA_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Setup the the entire RAM region for privileged read-write and unprivileged read only access */ prvMpuSetRegion(portPRIVILEGED_RAM_REGION, 0x08000000, portMPU_SIZE_512KB | portMPU_REGION_ENABLE, portMPU_PRIV_RW_USER_RO_EXEC | portMPU_NORMAL_OIWTNOWA_SHARED); /* Default peripherals setup */ prvMpuSetRegion(portGENERAL_PERIPHERALS_REGION, 0xF0000000, portMPU_SIZE_256MB | portMPU_REGION_ENABLE | portMPU_SUBREGION_1_DISABLE | portMPU_SUBREGION_2_DISABLE | portMPU_SUBREGION_3_DISABLE | portMPU_SUBREGION_4_DISABLE, portMPU_PRIV_RW_USER_RW_NOEXEC | portMPU_DEVICE_NONSHAREABLE); /* Privilege System Region setup */ prvMpuSetRegion(portPRIVILEGED_SYSTEM_REGION, 0xFFF80000, portMPU_SIZE_512KB | portMPU_REGION_ENABLE, portMPU_PRIV_RW_USER_RO_NOEXEC | portMPU_DEVICE_NONSHAREABLE); /* START ADDED FOR TEST 1. */ _mpuDisableBackgroundRegion_(); /* END ADDED FOR TEST 1. */ /* Enable MPU */ prvMpuEnable(); /* START ADDED FOR TEST 2. */ // Perform a read at EMIF CS 0 uint8_t data = *(uint8_t*)(0x80000000U); /* END ADDED FOR TEST 2. */ }
These results illustrate the inverted behaviour I've described - when the MPU background region is "enabled", no data abort occurs - this is the opposite of what I'm expecting given the details provided about the TMS570LS3137's Cortex-R4F MPU.
Thanks,
Tyler
Hi Tyler,
Thanks for your code, i will go through it and i will try to provide my updates as soon as possible.
--
Thanks & regards,
Jagadish.
Hi Tyler,
Apologies for the delay in late response, i was stuck with other issues in this mean time.
I found something:
I think you should need to disable the region-1 to test the Background region enable check:
Please refer below highlighted sentences in the core reference manual:
Can you please once again test the behavior of BR bit by disabling the region-1 once.
--
Thanks & regards,
Jagadish.