Hello All,
I am trying to use MPU to protect a specific memory area in DDR3. I use MPU 7 to protect the area. But the area is not protected at all and all the accesses to the memory area pass through unimpeded. Please let me know what could be the issue. I have attached my code snippet here. I am using DSP core 0.
Regards, Yunas
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <ti/csl/csl_cache.h>
#include <ti/csl/csl_cacheAux.h>
/************************************************************
* Explicit External Declarations *
************************************************************/
extern void intcVectorTable(void);
/************************************************************
* Local Macro Declarations *
************************************************************/
#define INTERRUPTS_ENABLED
#define MPU1_REGION_START_ADDR (0x80000000)
#define MPU1_REGION_SIZE (0x00010000)
#define MPU1_TEST_ADDR (MPU1_REGION_START_ADDR)
#define MPU2_REGION_START_ADDR (0xC1000000)
#define MPU2_REGION_SIZE (0x00010000)
#define MPU2_TEST_ADDR (MPU2_REGION_START_ADDR)
#define MPU_IOPU_EVENT_NUMBER (74)
/************************************************************
* Local Typedef Declarations *
************************************************************/
// C6740 Megamodule Interrupt Controller
typedef struct _DEVICE_C6740_INTC_
{
volatile uint32_t EVTFLAG[4]; // 0x000
volatile uint8_t RSVD0[16]; // 0x010
volatile uint32_t EVTSET[4]; // 0x020
volatile uint8_t RSVD1[16]; // 0x030
volatile uint32_t EVTCLR[4]; // 0x040
volatile uint8_t RSVD2[48]; // 0x050
volatile uint32_t EVTMASK[4]; // 0x080
volatile uint8_t RSVD3[16]; // 0x090
volatile uint32_t MEVTFLAG[4]; // 0x0A0
volatile uint8_t RSVD4[16]; // 0x0B0
volatile uint32_t EXPMASK[4]; // 0x0C0
volatile uint8_t RSVD5[16];
volatile uint32_t MEXPFLAG[4];
volatile uint8_t RSVD6[20];
volatile uint32_t INTMUX1;
volatile uint32_t INTMUX2;
volatile uint32_t INTMUX3;
volatile uint8_t RSVD7[48];
volatile uint32_t AEGMUX0;
volatile uint32_t AEGMUX1;
volatile uint8_t RSVD8[56];
volatile uint32_t INTXSTAT;
volatile uint32_t INTXCLR;
volatile uint32_t INTDMASK;
volatile uint8_t RSVD9[52];
volatile uint32_t EVTASRT;
}
DEVICE_C6740_INTCRegs;
#define NUM_REG 2
#define DSP_INTC ((DEVICE_C6740_INTCRegs *) 0x01800000)
typedef struct _DEVICE_IOPU_REGS_
{
volatile uint32_t REVISION; // 0x000
volatile uint32_t CONFIGURATION; // 0x004
volatile uint32_t RSVD0[2]; // 0x008
volatile uint32_t INTR_RAW_STATUS; // 0x010
volatile uint32_t INTR_ENABLED_STATUS; // 0x014
volatile uint32_t INTR_ENABLE; // 0x018
volatile uint32_t INTR_ENABLE_CLR; // 0x01C
volatile uint32_t EOI; // 0x020
volatile uint32_t INTR_VECTOR; // 0x024
volatile uint8_t RSVD1[0xD8]; // 0x028
volatile uint32_t IO_MPPA[128]; // 0x100
volatile uint32_t MPFAR; // 0x300
volatile uint32_t MPFSR; // 0x304
volatile uint32_t MPFCR; // 0x308
}
DEVICE_IopuRegs;
#define IOPU0 ((DEVICE_IopuRegs *) 0x01C16000)
#define IOPU1 ((DEVICE_IopuRegs *) 0x01C24000)
#define IOPU2 ((DEVICE_IopuRegs *) 0x01C17000)
#define IOPU3 ((DEVICE_IopuRegs *) 0x01E29000)
#define IOPU4 ((DEVICE_IopuRegs *) 0x01D0E000)
#define IOPU5 ((DEVICE_IopuRegs *) 0x01F0B000)
#define IOPU0_IO_CNT (2)
#define IOPU1_IO_CNT (3)
#define IOPU2_IO_CNT (2)
#define IOPU3_IO_CNT (2)
#define IOPU4_IO_CNT (0)
#define IOPU5_IO_CNT (0)
#define IOPU6_IO_CNT (8)
typedef struct _MPU_RANGE_
{
volatile uint32_t MPSAR; // 0x00
volatile uint32_t MPEAR; // 0x04
volatile uint32_t MPPA; // 0x08
volatile uint32_t RSVD; // 0x0C
}
MPU_Range;
typedef struct _DEVICE_MPU_REGS_
{
volatile uint32_t REVISION; // 0x000
volatile uint32_t CONFIGURATION; // 0x004
volatile uint8_t RSVD0[8]; // 0x008
volatile uint32_t INTR_RAW_STATUS; // 0x010
volatile uint32_t INTR_ENABLED_STATUS;
volatile uint32_t INTR_ENABLE; // 0x018
volatile uint32_t INTR_ENABLE_CLR; // 0x01C
volatile uint32_t EOI; // 0x020
volatile uint32_t INTR_VECTOR; // 0x024
volatile uint8_t RSVD1[0xD8]; // 0x028
volatile uint32_t FIXED_MPSAR; // 0x100
volatile uint32_t FIXED_MPEAR; // 0x104
volatile uint32_t FIXED_MPPA; // 0x108
volatile uint8_t RSVD2[0xF4]; // 0x10C
MPU_Range PROG_RANGE[16]; // 0x200 - 0x300
volatile uint32_t MPFAR; // 0x300
volatile uint32_t MPFSR; // 0x304
volatile uint32_t MPFCR; // 0x308
}
DEVICE_MpuRegs;
#define MPU1 ((DEVICE_MpuRegs *) 0x02388800)
#define MPU2 ((DEVICE_MpuRegs *) 0x02368000)
#define MPU1_RANGE_CNT (6)
#define MPU2_RANGE_CNT (12)
/************************************************************
* Local Function Declarations *
************************************************************/
static void LOCAL_interruptsInit();
/************************************************************
* Local Variable Definitions *
************************************************************/
/************************************************************
* Global Variable Definitions *
************************************************************/
/************************************************************
* Global Function Definitions *
************************************************************/
/*
interrupt void MPU_IOPU_isr()
{
// Clear the MPU1 interrupt status
if (MPU1->INTR_ENABLED_STATUS !=0)
{
// Clear the MPU1 interrupt status
MPU1->INTR_ENABLED_STATUS = 0x3;
// Clear fault status
MPU1->MPFCR = 0x1;
}
if (MPU2->INTR_ENABLED_STATUS !=0)
{
// Clear the MPU2 interrupt status
MPU2->INTR_ENABLED_STATUS = 0x3;
// Clear fault status
MPU2->MPFCR = 0x1;
}
// Clear Event in the interrupt controller
DSP_INTC->EVTCLR[2] = DSP_INTC->EVTCLR[2] | (1<< MPU_IOPU_EVENT_NUMBER - 64);
// Clear INT4 in the C674x core
ICR = 0x0010;
// In general, don't use printf in an ISR
printf("\tMPU_IOPU_isr: ACCESS DENIED!\n");
}
*/
// Top level driver for the test.
int main()
{
unsigned int *pData;
int i = 0;
#if defined(INTERRUPTS_ENABLED)
// LOCAL_interruptsInit();
#endif
// MPU1 test
printf("MPU1 Testing Begins\n");
printf("------------------------------------------------------------------\n");
pData = (unsigned int *) MPU1_TEST_ADDR;
#if defined(INTERRUPTS_ENABLED)
// Clear any old status
MPU1->INTR_ENABLED_STATUS = 0x3;
// Enable the interrupts
MPU1->INTR_ENABLE = 0x3;
#endif
for(i=0;i<NUM_REG;i++)
{
// Setup the range we will be working with
// MPU1->PROG_RANGE[i].MPSAR = MPU1_REGION_START_ADDR;
// MPU1->PROG_RANGE[i].MPEAR = MPU1_REGION_START_ADDR + MPU1_REGION_SIZE - 1;
MPU1->PROG_RANGE[i].MPSAR = MPU1_REGION_START_ADDR;
MPU1->PROG_RANGE[i].MPEAR = MPU1_REGION_START_ADDR + MPU1_REGION_START_ADDR - 1; // + MPU1_REGION_SIZE - 1;
MPU1->PROG_RANGE[i].MPPA = 0x03FFFEE4;
}
// Write a known value to the memory
*pData = 0x0BADBEEF;
CACHE_wbL1d (pData, 32, CACHE_FENCE_WAIT);
CACHE_wbL2 (pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
printf("FULL ACCESS: Value wrote to memory = 0x%08X\n",0x0BADBEEF);
printf("FULL ACCESS: Value read from memory = 0x%08X\n",*pData);
for(i=0;i<NUM_REG;i++)
{
// Restrict read/write/execute access for all AIDs
MPU1->PROG_RANGE[i].MPPA = 0x03FFFEC0;
}
*pData = 0x76543210;
CACHE_wbL1d (pData, 32, CACHE_FENCE_WAIT);
CACHE_wbL2 (pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
printf("NO ACCESS: Value wrote to memory = 0x%08X\n",0x76543210);
printf("NO ACCESS: Value read from memory = 0x%08X\n",*pData);
// Restrict write/execute access, only allow read access for all AIDs
MPU1->PROG_RANGE[0].MPPA = 0x03FFFEE4;
*pData = 0x01234567;
CACHE_wbL1d (pData, 32, CACHE_FENCE_WAIT);
CACHE_wbL2 (pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
printf("READ-ONLY ACCESS: Value wrote to memory = 0x%08X\n",0x01234567);
printf("READ-ONLY ACCESS: Value read from memory = 0x%08X\n",*pData);
// Restrict read/execute access, only allow write access for all AIDs
MPU1->PROG_RANGE[0].MPPA = 0x03FFFED2;
*pData = 0xA5A50F0F;
CACHE_wbL1d (pData, 32, CACHE_FENCE_WAIT);
CACHE_wbL2 (pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
CACHE_invL1d(pData, 32, CACHE_FENCE_WAIT);
printf("WRITE-ONLY ACCESS: Value wrote to memory = 0x%08X\n",0xA5A50F0F);
printf("WRITE-ONLY ACCESS: Value read from memory = 0x%08X\n",*pData);
// Setup Region 1 to allow read/write access for all AIDs (but no execute)
MPU1->PROG_RANGE[0].MPPA = 0x03FFFEF6;
printf("READ/WRITE ACCESS: Value read from memory = 0x%08X\n",*pData);
printf("------------------------------------------------------------------\n\n");
// MPU2 test
printf("MPU2 Testing Begins\n");
printf("------------------------------------------------------------------\n");
pData = (unsigned int *) MPU2_TEST_ADDR;
// Clear any old status
#if defined(INTERRUPTS_ENABLED)
MPU2->INTR_ENABLED_STATUS = 0x3;
// Enable the interrupts
MPU2->INTR_ENABLE = 0x3;
#endif
// Setup the range we will be working with
MPU2->PROG_RANGE[0].MPSAR = MPU2_REGION_START_ADDR;
MPU2->PROG_RANGE[0].MPEAR = MPU2_REGION_START_ADDR + MPU2_REGION_SIZE - 1;
// Write a known value to the memory
*pData = 0x0BADBEEF;
printf("FULL ACCESS: Value wrote to memory = 0x%08X\n",0x0BADBEEF);
printf("FULL ACCESS: Value read from memory = 0x%08X\n",*pData);
// Restrict read/write/execute access for all AIDs
MPU2->PROG_RANGE[0].MPPA = 0x03FFFEC0;
*pData = 0x76543210;
printf("NO ACCESS: Value wrote to memory = 0x%08X\n",0x76543210);
printf("NO ACCESS: Value read from memory = 0x%08X\n",*pData);
// Restrict write/execute access, only allow read access for all AIDs
MPU2->PROG_RANGE[0].MPPA = 0x03FFFEE4;
*pData = 0x01234567;
printf("READ-ONLY ACCESS: Value wrote to memory = 0x%08X\n",0x01234567);
printf("READ-ONLY ACCESS: Value read from memory = 0x%08X\n",*pData);
// Restrict read/execute access, only allow write access for all AIDs
MPU2->PROG_RANGE[0].MPPA = 0x03FFFED2;
*pData = 0xA5A50F0F;
printf("WRITE-ONLY ACCESS: Value wrote to memory = 0x%08X\n",0xA5A50F0F);
printf("WRITE-ONLY ACCESS: Value read from memory = 0x%08X\n",*pData);
// Setup Region 1 to allow read/write access for all AIDs (but no execute)
MPU2->PROG_RANGE[0].MPPA = 0x03FFFEF6;
printf("READ/WRITE ACCESS: Value read from memory = 0x%08X\n",*pData);
printf("------------------------------------------------------------------\n\n");
return 0;
}
/************************************************************
* Local Function Definitions *
************************************************************/
/*
* DSP interrupt controller configuration.
*/
/*
static void LOCAL_interruptsInit()
{
// Clear the MPU_IOPU event (event 74)
DSP_INTC->EVTCLR[2] = DSP_INTC->EVTCLR[2] | (1<< MPU_IOPU_EVENT_NUMBER - 64);
// Connect the MPU_IOPU event to the DSP interrupt 4
DSP_INTC->INTMUX1 = (DSP_INTC->INTMUX1 & 0xFFFFFF80) | (0x0000007F & MPU_IOPU_EVENT_NUMBER);
// set ISTP to point to the vector table address
ISTP = (uint32_t)intcVectorTable;
// clear all interrupts, bits 4 thru 15
ICR = 0xFFF0;
// enable the bits for maskable interrupt 4 and NMIE
IER = 0x0012;
// enable interrupts, set GIE bit
_enable_interrupts();
}
*/
/***********************************************************
* End file *
***********************************************************/