/** * \brief Set up a memory region. */ void _SetupMemoryRegion( void ) { uint32_t dwRegionBaseAddr; uint32_t dwRegionAttr; memory_barrier(); /*************************************************** ITCM memory region --- Normal START_Addr:- 0x00000000UL END_Addr:- 0x00400000UL ****************************************************/ dwRegionBaseAddr = ITCM_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_ITCM_REGION; // 1 dwRegionAttr = MPU_AP_PRIVILEGED_READ_WRITE | MPU_CalMPURegionSize(ITCM_END_ADDRESS - ITCM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** Internal flash memory region --- Normal read-only (update to Strongly ordered in write accesses) START_Addr:- 0x00400000UL END_Addr:- 0x00600000UL ******************************************************/ dwRegionBaseAddr = IFLASH_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_IFLASH_REGION; //2 dwRegionAttr = MPU_AP_READONLY | INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** DTCM memory region --- Normal START_Addr:- 0x20000000L END_Addr:- 0x20400000UL ******************************************************/ /* DTCM memory region */ dwRegionBaseAddr = DTCM_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_DTCM_REGION; //3 dwRegionAttr = MPU_AP_PRIVILEGED_READ_WRITE | MPU_CalMPURegionSize(DTCM_END_ADDRESS - DTCM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** SRAM Cacheable memory region --- Normal START_Addr:- 0x20400000UL END_Addr:- 0x2043FFFFUL ******************************************************/ /* SRAM memory region */ dwRegionBaseAddr = SRAM_FIRST_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_SRAM_REGION_1; //4 dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | MPU_CalMPURegionSize(SRAM_FIRST_END_ADDRESS - SRAM_FIRST_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** Internal SRAM second partition memory region --- Normal START_Addr:- 0x20440000UL END_Addr:- 0x2045FFFFUL ******************************************************/ /* SRAM memory region */ dwRegionBaseAddr = SRAM_SECOND_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_SRAM_REGION_2; //5 dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | MPU_CalMPURegionSize(SRAM_SECOND_END_ADDRESS - SRAM_SECOND_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** Peripheral memory region --- DEVICE Shareable START_Addr:- 0x40000000UL END_Addr:- 0x5FFFFFFFUL ******************************************************/ dwRegionBaseAddr = PERIPHERALS_START_ADDRESS | MPU_REGION_VALID | MPU_PERIPHERALS_REGION; //6 dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | SHAREABLE_DEVICE_TYPE | MPU_CalMPURegionSize(PERIPHERALS_END_ADDRESS - PERIPHERALS_START_ADDRESS) |MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** External EBI memory memory region --- Strongly Ordered START_Addr:- 0x60000000UL END_Addr:- 0x6FFFFFFFUL ******************************************************/ dwRegionBaseAddr = EXT_EBI_START_ADDRESS | MPU_REGION_VALID | MPU_EXT_EBI_REGION; dwRegionAttr = MPU_AP_FULL_ACCESS | /* External memory Must be defined with 'Device' or 'Strongly Ordered' attribute for write accesses (AXI) */ STRONGLY_ORDERED_SHAREABLE_TYPE | MPU_CalMPURegionSize(EXT_EBI_END_ADDRESS - EXT_EBI_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** SDRAM Cacheable memory region --- Normal START_Addr:- 0x70000000UL END_Addr:- 0x7FFFFFFFUL ******************************************************/ dwRegionBaseAddr = SDRAM_START_ADDRESS | MPU_REGION_VALID | MPU_DEFAULT_SDRAM_REGION; //7 dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_RWA_TYPE( SHAREABLE ) | MPU_CalMPURegionSize(SDRAM_END_ADDRESS - SDRAM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** QSPI memory region --- Strongly ordered START_Addr:- 0x80000000UL END_Addr:- 0x9FFFFFFFUL ******************************************************/ dwRegionBaseAddr = QSPI_START_ADDRESS | MPU_REGION_VALID | MPU_QSPIMEM_REGION; //8 dwRegionAttr = MPU_AP_FULL_ACCESS | STRONGLY_ORDERED_SHAREABLE_TYPE | MPU_CalMPURegionSize(QSPI_END_ADDRESS - QSPI_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /**************************************************** USB RAM Memory region --- Device START_Addr:- 0xA0100000UL END_Addr:- 0xA01FFFFFUL ******************************************************/ dwRegionBaseAddr = USBHSRAM_START_ADDRESS | MPU_REGION_VALID | MPU_USBHSRAM_REGION; //9 dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | SHAREABLE_DEVICE_TYPE | MPU_CalMPURegionSize(USBHSRAM_END_ADDRESS - USBHSRAM_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion( dwRegionBaseAddr, dwRegionAttr); /* Enable the memory management fault , Bus Fault, Usage Fault exception */ SCB->SHCSR |= (SCB_SHCSR_MEMFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_USGFAULTENA_Msk); /* Enable the MPU region */ MPU_Enable( MPU_ENABLE | MPU_PRIVDEFENA); memory_sync(); }
/** * \brief Application entry point for MPU example. * * \return Unused (ANSI-C compatibility). */ extern int main( void ) { uint8_t ucChoice = 0; /* Disable watchdog */ WDT_Disable(WDT); uint32_t *pdw = (uint32_t *)MPU_SRAM_PRIVILEGE_START_ADDRESS; /* Output example information */ printf("\n\r\n\r\n\r"); printf("-- MPU Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); LED_Configure(LED_YELLOW0); /* Set up the default memory regions */ _SetupMPU(); /* Set the environment to thread mode */ __set_CONTROL(USER_MODE); while (ucChoice != '9') { printf("----------------------------------------\n\r"); printf(" Choose an option below:\n\r"); printf(" 1. Protect the Yellow LED region\n\r"); printf(" 2. UN-protect the Yellow LED region\n\r"); printf(" 3. Toggle the green LED\n\r"); printf(" 4. Set the RAM region to read only \n\r"); printf(" 5. Set the RAM region to read/write\n\r"); printf(" 6. Read the RAM content at offset 0\n\r"); printf(" 7. Write the RAM context at offset 0\n\r"); printf(" 8. Quit the external program\n\r"); printf("\n\r"); printf(" Choice: "); ucChoice = DBG_GetChar(); DBG_PutChar(ucChoice); printf("\n\r"); switch (ucChoice) { case '1': _UpdateMPU(MPU_PIOC_REGION_REGION, MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS | MPU_REGION_VALID | MPU_PIOC_REGION_REGION, MPU_AP_UNPRIVILEGED_READONLY | MPU_REGION_EXECUTE_NEVER | MPU_CalMPURegionSize(MPU_PIOC_PERIPHERALS_REGION_END_ADDRESS - MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS) | MPU_REGION_ENABLE); break; case '2': _UpdateMPU(MPU_PIOC_REGION_REGION, MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS | MPU_REGION_VALID | MPU_PIOC_REGION_REGION, MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | MPU_CalMPURegionSize(MPU_PIOC_PERIPHERALS_REGION_END_ADDRESS - MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS) | MPU_REGION_ENABLE); break; case '3': /* Set back to unprivileged mode*/ LED_Toggle(LED_YELLOW0); __set_CONTROL(USER_MODE); break; case '4': _UpdateMPU(MPU_PRIVILEGE_RAM_REGION, MPU_SRAM_PRIVILEGE_START_ADDRESS | MPU_REGION_VALID | MPU_PRIVILEGE_RAM_REGION, MPU_AP_UNPRIVILEGED_READONLY | MPU_REGION_CACHEABLE | MPU_REGION_BUFFERABLE | MPU_TEX_B001| MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE_END_ADDRESS - MPU_SRAM_PRIVILEGE_START_ADDRESS) | MPU_REGION_ENABLE); break; case '5': _UpdateMPU(MPU_PRIVILEGE_RAM_REGION, MPU_SRAM_PRIVILEGE_START_ADDRESS | MPU_REGION_VALID | MPU_PRIVILEGE_RAM_REGION, MPU_AP_FULL_ACCESS | MPU_REGION_CACHEABLE | MPU_REGION_BUFFERABLE | MPU_TEX_B001| MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE_END_ADDRESS - MPU_SRAM_PRIVILEGE_START_ADDRESS) | MPU_REGION_ENABLE); break; case '6': printf("-I- RAM address has content %x \n\r",(unsigned)(pdw[0])); break; case '7': printf("-I- Write offset 0 of RAM region with content 0x55AA55AA\n\r"); pdw[0] = 0x55AA55AA; break; case '8': printf("-I- MPU TEST FINISH ...\n\r"); break; default: printf("-I- This option is not valid\n\r"); break; } } /* Setback to privilege mode, before entering the main routine, it is supervisor mode*/ __ASM volatile(" svc 0x00 "); while (!dwRaisePriDone); dwRaisePriDone = 0; __set_CONTROL(PRIVILEGE_MODE); return 0; }
int main(void) { uint8_t MemVerify = 0; uint32_t __Start_SP, idx; uint32_t (*__Start_New)(void); uint8_t *pMemory = (uint8_t *)( QSPIMEM_ADDR ); /* Disable watchdog */ WDT_Disable(WDT); SCB_EnableICache(); SCB_EnableDCache(); /* Output example information */ printf("-- QSPI XIP Example %s --\n\r", SOFTPACK_VERSION); printf("-- %s\n\r", BOARD_NAME); printf("-- Compiled: %s %s With %s--\n\r", __DATE__, __TIME__, COMPILER_NAME); /* Configure systick */ TimeTick_Configure(); /* Initialize the QSPI and serial flash */ PIO_Configure(pins, PIO_LISTSIZE(pins)); /* Enable the clock of QSPI */ ENABLE_PERIPHERAL(ID_QSPI); S25FL1D_InitFlashInterface(1); printf("QSPI drivers initialized\n\r"); /* enable quad mode */ S25FL1D_QuadMode(ENABLE); /* get the code at the beginning of QSPI, run the code directly if it's valid */ S25FL1D_ReadQuadIO(Buffer, sizeof(Buffer), 0, 1, 0); printf("-I- data at the beginning of QSPI: %08x %08x %08x %08x\n\r", (unsigned int)Buffer[0], (unsigned int)Buffer[1], (unsigned int)Buffer[2], (unsigned int)Buffer[3]); if ((IRAM_ADDR <= Buffer[0]) && (IRAM_ADDR + IRAM_SIZE > Buffer[0]) && (QSPIMEM_ADDR < Buffer[1]) && (1 == (Buffer[1]&0x3))) { __Start_New = (uint32_t(*)(void)) Buffer[1]; __Start_SP = Buffer[0]; printf("-I- a valid application is already in QSPI, run it from QSPI\n\r"); printf("========================================================= \n\r"); __set_MSP(__Start_SP); __Start_New(); } else { printf("-I- there isn't a valid application in QSPI, program first\n\r"); } if (S25FL1D_Unprotect()) { printf("Unprotect QSPI Flash failed!\n\r"); while (1); } /* erase entire chip */ S25FL1D_EraseChip(); /* Flash the code to QSPI flash */ printf("Writing to Memory\n\r"); S25FL1D_Write((uint32_t *)pBuffercode, sizeof(pBuffercode), 0, 0); printf("Example code written 0x%x to Memory\n\r", sizeof(pBuffercode)); printf("Verifying \n\r"); /* Update QSPI Region to Full Access and cacheable*/ MPU_UpdateRegions(MPU_QSPIMEM_REGION, QSPI_START_ADDRESS, \ MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE( NON_SHAREABLE ) | MPU_CalMPURegionSize(QSPI_END_ADDRESS - QSPI_START_ADDRESS) | MPU_REGION_ENABLE); /* Start continuous read mode to enter in XIP mode*/ S25FL1D_ReadQuadIO(Buffer, sizeof(Buffer), 0, 1, 0); for (idx = 0; idx < sizeof(pBuffercode); idx++) { if (*pMemory == pBuffercode[idx]) { pMemory++; } else { MemVerify = 1; printf("Data does not match at 0x%x \n\r", (unsigned)pMemory); break; } } if (!MemVerify) { printf("Everything is OK \n\r"); /* set PC and SP */ __Start_New = (uint32_t(*) (void) ) Buffer[1]; __Start_SP = Buffer[0]; printf("\n\r Starting getting started example from QSPI flash \n\r"); printf("========================================================= \n\r"); __set_MSP(__Start_SP); __Start_New(); } while (1); }
/** * \brief Setup a memory region. */ static void _SetupMPU(void) { uint32_t dwRegionBaseAddr; uint32_t dwRegionAttr; /* Internal flash privilege memory region */ dwRegionBaseAddr = IFLASH_PRIVILEGE_START_ADDRESS | MPU_REGION_VALID | MPU_PRIVILEGED_FLASH_REGION; dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_CalMPURegionSize(IFLASH_PRIVILEGE_END_ADDRESS - IFLASH_PRIVILEGE_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* Internal flash unprivileged memory region */ dwRegionBaseAddr = IFLASH_START_ADDRESS | MPU_REGION_VALID | MPU_UNPRIVILEGED_FLASH_REGION; dwRegionAttr = MPU_AP_READONLY | MPU_CalMPURegionSize(IFLASH_END_ADDRESS - IFLASH_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* SRAM memory unprivileged region */ dwRegionBaseAddr = MPU_SRAM_UNPRIVILEGE_START_ADDRESS | MPU_REGION_VALID | MPU_UNPRIVILEGED_RAM_REGION; dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE) | MPU_CalMPURegionSize(MPU_SRAM_UNPRIVILEGE_END_ADDRESS - MPU_SRAM_UNPRIVILEGE_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* SRAM memory privilege region */ dwRegionBaseAddr = MPU_SRAM_PRIVILEGE_START_ADDRESS | MPU_REGION_VALID | MPU_PRIVILEGE_RAM_REGION; dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE ) | MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE_END_ADDRESS - MPU_SRAM_PRIVILEGE_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* SRAM memory privilege region */ dwRegionBaseAddr = MPU_SRAM_PRIVILEGE2_START_ADDRESS | MPU_REGION_VALID | MPU_PRIVILEGE_RAM_REGION_2; dwRegionAttr = MPU_AP_FULL_ACCESS | INNER_NORMAL_WB_NWA_TYPE(NON_SHAREABLE ) | MPU_CalMPURegionSize(MPU_SRAM_PRIVILEGE2_END_ADDRESS - MPU_SRAM_PRIVILEGE2_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* Peripheral memory region */ dwRegionBaseAddr = MPU_PERIPHERALS_START_ADDRESS_0 | MPU_REGION_VALID | MPU_PERIPHERALS_REGION_0; dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | MPU_CalMPURegionSize(MPU_PERIPHERALS_END_ADDRESS_0 - MPU_PERIPHERALS_START_ADDRESS_0) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* Peripheral memory region */ dwRegionBaseAddr = MPU_PERIPHERALS_START_ADDRESS_1 | MPU_REGION_VALID | MPU_PERIPHERALS_REGION_1; dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | 1 << MPU_RASR_SRD_Pos | MPU_CalMPURegionSize(MPU_PERIPHERALS_END_ADDRESS_1 - MPU_PERIPHERALS_START_ADDRESS_1) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* Sub Peripheral memory region */ dwRegionBaseAddr = MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS | MPU_REGION_VALID | MPU_PIOC_REGION_REGION; dwRegionAttr = MPU_AP_FULL_ACCESS | MPU_REGION_EXECUTE_NEVER | MPU_CalMPURegionSize(MPU_PIOC_PERIPHERALS_REGION_END_ADDRESS - MPU_PIOC_PERIPHERALS_REGION_START_ADDRESS) | MPU_REGION_ENABLE; MPU_SetRegion(dwRegionBaseAddr, dwRegionAttr); /* Enable the memory management fault exception */ SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; /* Enable the MPU region */ MPU_Enable(MPU_ENABLE | MPU_PRIVDEFENA); }