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.

[6638K2K] Memory Protection Unit issue

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

2425.hello.c
#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                                                 *
***********************************************************/