From c3e4c9a25c2910d2d66d52215b3406b13d5b23d5 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Sun, 29 Jun 2014 12:34:32 +0300 Subject: Add more board models --- boards/ek-lm4f232/mpu_fault/mpu_fault.c | 413 ++++++++++++++++++++++++++++++++ 1 file changed, 413 insertions(+) create mode 100644 boards/ek-lm4f232/mpu_fault/mpu_fault.c (limited to 'boards/ek-lm4f232/mpu_fault/mpu_fault.c') diff --git a/boards/ek-lm4f232/mpu_fault/mpu_fault.c b/boards/ek-lm4f232/mpu_fault/mpu_fault.c new file mode 100644 index 0000000..88e2f24 --- /dev/null +++ b/boards/ek-lm4f232/mpu_fault/mpu_fault.c @@ -0,0 +1,413 @@ +//***************************************************************************** +// +// mpu_fault.c - MPU example. +// +// Copyright (c) 2011-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Texas Instruments (TI) is supplying this software for use solely and +// exclusively on TI's microcontroller products. The software is owned by +// TI and/or its suppliers, and is protected under applicable copyright +// laws. You may not combine this software with "viral" open-source +// software in order to form a larger program. +// +// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. +// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT +// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY +// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL +// DAMAGES, FOR ANY REASON WHATSOEVER. +// +// This is part of revision 2.1.0.12573 of the EK-LM4F232 Firmware Package. +// +//***************************************************************************** + +#include +#include +#include "inc/hw_ints.h" +#include "inc/hw_memmap.h" +#include "inc/hw_nvic.h" +#include "inc/hw_types.h" +#include "driverlib/debug.h" +#include "driverlib/fpu.h" +#include "driverlib/interrupt.h" +#include "driverlib/mpu.h" +#include "driverlib/sysctl.h" +#include "driverlib/rom.h" +#include "grlib/grlib.h" +#include "drivers/cfal96x64x16.h" + +//***************************************************************************** +// +//! \addtogroup example_list +//!

MPU (mpu_fault)

+//! +//! This example application demonstrates the use of the MPU to protect a +//! region of memory from access, and to generate a memory management fault +//! when there is an access violation. +// +//***************************************************************************** + +//***************************************************************************** +// +// Variables to hold the state of the fault status when the fault occurs and +// the faulting address. +// +//***************************************************************************** +static volatile uint32_t g_ui32MMAR; +static volatile uint32_t g_ui32FaultStatus; + +//***************************************************************************** +// +// A counter to track the number of times the fault handler has been entered. +// +//***************************************************************************** +static volatile uint32_t g_ui32MPUFaultCount; + +//***************************************************************************** +// +// A location for storing data read from various addresses. Volatile forces +// the compiler to use it and not optimize the access away. +// +//***************************************************************************** +static volatile uint32_t g_ui32Value; + +//***************************************************************************** +// +// Graphics context used to show text on the CSTN display. +// +//***************************************************************************** +tContext g_sContext; + +//***************************************************************************** +// +// The error routine that is called if the driver library encounters an error. +// +//***************************************************************************** +#ifdef DEBUG +void +__error__(char *pcFilename, uint32_t ui32Line) +{ +} +#endif + +//***************************************************************************** +// +// The exception handler for memory management faults, which are caused by MPU +// access violations. This handler will verify the cause of the fault and +// clear the NVIC fault status register. +// +//***************************************************************************** +void +MPUFaultHandler(void) +{ + // + // Preserve the value of the MMAR (the address causing the fault). + // Preserve the fault status register value, then clear it. + // + g_ui32MMAR = HWREG(NVIC_MM_ADDR); + g_ui32FaultStatus = HWREG(NVIC_FAULT_STAT); + HWREG(NVIC_FAULT_STAT) = g_ui32FaultStatus; + + // + // Increment a counter to indicate the fault occurred. + // + g_ui32MPUFaultCount++; + + // + // Disable the MPU so that this handler can return and cause no more + // faults. The actual instruction that faulted will be re-executed. + // + ROM_MPUDisable(); +} + +//***************************************************************************** +// +// This example demonstrates how to configure MPU regions for different levels +// of memory protection. The following memory map is set up: +// +// 0000.0000 - 0000.1C00 - rgn 0: executable read-only, flash +// 0000.1C00 - 0000.2000 - rgn 0: no access, flash (disabled sub-region 7) +// 2000.0000 - 2000.4000 - rgn 1: read-write, RAM +// 2000.4000 - 2000.6000 - rgn 2: read-only, RAM (disabled sub-rgn 4 of rgn 1) +// 2000.6000 - 2000.7FFF - rgn 1: read-write, RAM +// 4000.0000 - 4001.0000 - rgn 3: read-write, peripherals +// 4001.0000 - 4002.0000 - rgn 3: no access (disabled sub-region 1) +// 4002.0000 - 4006.0000 - rgn 3: read-write, peripherals +// 4006.0000 - 4008.0000 - rgn 3: no access (disabled sub-region 6, 7) +// E000.E000 - E000.F000 - rgn 4: read-write, NVIC +// 0100.0000 - 0100.FFFF - rgn 5: executable read-only, ROM +// +// The example code will attempt to perform the following operations and check +// the faulting behavior: +// +// - write to flash (should fault) +// - read from the disabled area of flash (should fault) +// - read from the read-only area of RAM (should not fault) +// - write to the read-only section of RAM (should fault) +// +//***************************************************************************** +int +main(void) +{ + tRectangle sRect; + unsigned int bFail = 0; + + // + // Enable lazy stacking for interrupt handlers. This allows floating-point + // instructions to be used within interrupt handlers, but at the expense of + // extra stack usage. + // + ROM_FPULazyStackingEnable(); + + // + // Set the clocking to run directly from the crystal. + // + ROM_SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | + SYSCTL_XTAL_16MHZ); + + // + // Initialize the display driver. + // + CFAL96x64x16Init(); + + // + // Initialize the graphics context and find the middle X coordinate. + // + GrContextInit(&g_sContext, &g_sCFAL96x64x16); + + // + // Fill the top part of the screen with blue to create the banner. + // + sRect.i16XMin = 0; + sRect.i16YMin = 0; + sRect.i16XMax = GrContextDpyWidthGet(&g_sContext) - 1; + sRect.i16YMax = 9; + GrContextForegroundSet(&g_sContext, ClrDarkBlue); + GrRectFill(&g_sContext, &sRect); + + // + // Change foreground for white text. + // + GrContextForegroundSet(&g_sContext, ClrWhite); + + // + // Put the application name in the middle of the banner. + // + GrContextFontSet(&g_sContext, g_psFontFixed6x8); + GrStringDrawCentered(&g_sContext, "mpu-fault", -1, + GrContextDpyWidthGet(&g_sContext) / 2, 4, 0); + GrContextFontSet(&g_sContext, g_psFontFixed6x8); + + // + // Configure an executable, read-only MPU region for flash. It is a 16 KB + // region with the last 2 KB disabled to result in a 14 KB executable + // region. This region is needed so that the program can execute from + // flash. + // + ROM_MPURegionSet(0, FLASH_BASE, + MPU_RGN_SIZE_16K | MPU_RGN_PERM_EXEC | + MPU_RGN_PERM_PRV_RO_USR_RO | MPU_SUB_RGN_DISABLE_7 | + MPU_RGN_ENABLE); + + // + // Configure a read-write MPU region for RAM. It is a 32 KB region. There + // is a 4 KB sub-region in the middle that is disabled in order to open up + // a hole in which different permissions can be applied. + // + ROM_MPURegionSet(1, SRAM_BASE, + MPU_RGN_SIZE_32K | MPU_RGN_PERM_NOEXEC | + MPU_RGN_PERM_PRV_RW_USR_RW | MPU_SUB_RGN_DISABLE_4 | + MPU_RGN_ENABLE); + + // + // Configure a read-only MPU region for the 4 KB of RAM that is disabled in + // the previous region. This region is used for demonstrating read-only + // permissions. + // + ROM_MPURegionSet(2, SRAM_BASE + 0x4000, + MPU_RGN_SIZE_2K | MPU_RGN_PERM_NOEXEC | + MPU_RGN_PERM_PRV_RO_USR_RO | MPU_RGN_ENABLE); + + // + // Configure a read-write MPU region for peripherals. The region is 512 KB + // total size, with several sub-regions disabled to prevent access to areas + // where there are no peripherals. This region is needed because the + // program needs access to some peripherals. + // + ROM_MPURegionSet(3, 0x40000000, + MPU_RGN_SIZE_512K | MPU_RGN_PERM_NOEXEC | + MPU_RGN_PERM_PRV_RW_USR_RW | MPU_SUB_RGN_DISABLE_1 | + MPU_SUB_RGN_DISABLE_6 | MPU_SUB_RGN_DISABLE_7 | + MPU_RGN_ENABLE); + + // + // Configure a read-write MPU region for access to the NVIC. The region is + // 4 KB in size. This region is needed because NVIC registers are needed + // in order to control the MPU. + // + ROM_MPURegionSet(4, NVIC_BASE, + MPU_RGN_SIZE_4K | MPU_RGN_PERM_NOEXEC | + MPU_RGN_PERM_PRV_RW_USR_RW | MPU_RGN_ENABLE); + + // + // Configure an executable, read-only MPU region for ROM. It is a 64 KB + // region. This region is needed so that ROM library calls work. + // + ROM_MPURegionSet(5, (uint32_t)ROM_APITABLE & 0xFFFF0000, + MPU_RGN_SIZE_64K | MPU_RGN_PERM_EXEC | + MPU_RGN_PERM_PRV_RO_USR_RO | MPU_RGN_ENABLE); + + // + // Need to clear the NVIC fault status register to make sure there is no + // status hanging around from a previous program. + // + g_ui32FaultStatus = HWREG(NVIC_FAULT_STAT); + HWREG(NVIC_FAULT_STAT) = g_ui32FaultStatus; + + // + // Enable the MPU fault. + // + ROM_IntEnable(FAULT_MPU); + + // + // Enable the MPU. This will begin to enforce the memory protection + // regions. The MPU is configured so that when in the hard fault or NMI + // exceptions, a default map will be used. Neither of these should occur + // in this example program. + // + ROM_MPUEnable(MPU_CONFIG_HARDFLT_NMI); + + // + // Attempt to write to the flash. This should cause a protection fault due + // to the fact that this region is read-only. + // + GrStringDraw(&g_sContext, "Flash write", -1, 0, 12, 0); + g_ui32MPUFaultCount = 0; + HWREG(0x100) = 0x12345678; + + // + // Verify that the fault occurred, at the expected address. + // + if((g_ui32MPUFaultCount == 1) && (g_ui32FaultStatus == 0x82) && + (g_ui32MMAR == 0x100)) + { + GrStringDraw(&g_sContext, " OK", -1, 72, 12, 0); + } + else + { + bFail = 1; + GrStringDraw(&g_sContext, "NOK", -1, 72, 12, 0); + } + + // + // The MPU was disabled when the previous fault occurred, so it needs to be + // re-enabled. + // + ROM_MPUEnable(MPU_CONFIG_HARDFLT_NMI); + + // + // Attempt to read from the disabled section of flash, the upper 2 KB of + // the 16 KB region. + // + GrStringDraw(&g_sContext, "Flash read", -1, 0, 22, 0); + g_ui32MPUFaultCount = 0; + g_ui32Value = HWREG(0x3820); + + // + // Verify that the fault occurred, at the expected address. + // + if((g_ui32MPUFaultCount == 1) && (g_ui32FaultStatus == 0x82) && + (g_ui32MMAR == 0x3820)) + { + GrStringDraw(&g_sContext, " OK", -1, 72, 22, 0); + } + else + { + bFail = 1; + GrStringDraw(&g_sContext, "NOK", -1, 72, 22, 0); + } + + // + // The MPU was disabled when the previous fault occurred, so it needs to be + // re-enabled. + // + ROM_MPUEnable(MPU_CONFIG_HARDFLT_NMI); + + // + // Attempt to read from the read-only area of RAM, the middle 4 KB of the + // 32 KB region. + // + GrStringDraw(&g_sContext, "RAM read", -1, 0, 32, 0); + g_ui32MPUFaultCount = 0; + g_ui32Value = HWREG(0x20004440); + + // + // Verify that the RAM read did not cause a fault. + // + if(g_ui32MPUFaultCount == 0) + { + GrStringDraw(&g_sContext, " OK", -1, 72, 32, 0); + } + else + { + bFail = 1; + GrStringDraw(&g_sContext, "NOK", -1, 72, 32, 0); + } + + // + // The MPU should not have been disabled since the last access was not + // supposed to cause a fault. But if it did cause a fault, then the MPU + // will be disabled, so re-enable it here anyway, just in case. + // + ROM_MPUEnable(MPU_CONFIG_HARDFLT_NMI); + + // + // Attempt to write to the read-only area of RAM, the middle 4 KB of the + // 32 KB region. + // + GrStringDraw(&g_sContext, "RAM write", -1, 0, 42, 0); + g_ui32MPUFaultCount = 0; + HWREG(0x20004460) = 0xabcdef00; + + // + // Verify that the RAM write caused a fault. + // + if((g_ui32MPUFaultCount == 1) && (g_ui32FaultStatus == 0x82) && + (g_ui32MMAR == 0x20004460)) + { + GrStringDraw(&g_sContext, " OK", -1, 72, 42, 0); + } + else + { + bFail = 1; + GrStringDraw(&g_sContext, "NOK", -1, 72, 42, 0); + } + + // + // Display the results of the example program. + // + if(bFail) + { + GrStringDrawCentered(&g_sContext, "Failure!", -1, + GrContextDpyWidthGet(&g_sContext) / 2, 56, 0); + } + else + { + GrStringDrawCentered(&g_sContext, "Success!", -1, + GrContextDpyWidthGet(&g_sContext) / 2, 56, 0); + } + + // + // Disable the MPU, so there are no lingering side effects if another + // program is run. + // + ROM_MPUDisable(); + + // + // Loop forever. + // + while(1) + { + } +} -- cgit v1.3.1