Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
8 years ago

NIOS II MPU initialisation

Hi,

I am running a NIOS II/f core with MPU enabled. However NIOS doesnt seem to like it when I enable the MPU in software. I have followed the Altera MPU application notes and examples in setting up my data and instruction regions. The memory map is attached. I am using Limit for the region sizes. The number of regions is 8 for both data and instructions and minimum size is 4K.

My data and instruction region setup functions are below:

void nios2_mpu_data_init()

{Nios2MPURegion region[NIOS2_MPU_NUM_DATA_REGIONS];

unsigned int num_of_region = NIOS2_MPU_NUM_DATA_REGIONS;

/* DDR RAM memory region */

region[0].index = 0;

region[0].base = 0x10000; // Byte Address 0x10000000

region[0].mask = 0x20000; // Byte Address 0x20000000

region[0].c = 1;

region[0].perm = MPU_DATA_PERM_SUPER_RW_USER_RW;

/* System memory data region. */

region[1].index = 1;

region[1].base = 0; // Byte Address 0

region[1].mask = 0x40; // Byte Address 0x40000.

region[1].c = 1;

region[1].perm = MPU_DATA_PERM_SUPER_RW_USER_RW;

/* Debug RAM memory region */

region[2].index = 2;

region[2].base = 0x10C; // Byte Address 0x10C000

region[2].mask = 0x10E; // Byte Address 0x10E000

region[2].c = 1;

region[2].perm = MPU_DATA_PERM_SUPER_RW_USER_RW;

/* Audio RAM memory region */

region[3].index = 3;

region[3].base = 0x10E; // Byte Address 0x10E000

region[3].mask = 0x10F; // Byte Address 0x10F000

region[3].c = 1;

region[3].perm = MPU_DATA_PERM_SUPER_RW_USER_RW;

/* Host RAM memory region */

region[4].index = 4;

region[4].base = 0x10F; // Byte Address 0x10F000

region[4].mask = 0x110; // Byte Address 0x110000

region[4].c = 1;

region[4].perm = MPU_DATA_PERM_SUPER_RW_USER_RW;

unsigned int index;

unsigned int mask;

/* Rest of the regions are maximally sized and restrictive to supervisor/user. */

mask = 0x80000;

for (index = 5; index < num_of_region; index++){

region[index].base = 0x0;

region[index].index = index;

region[index].mask = mask;

region[index].c = 1;

region[index].perm = MPU_DATA_PERM_SUPER_NONE_USER_NONE; //No access for user and supervisor

}

nios2_mpu_load_region(region, num_of_region, 1);

}

void nios2_mpu_inst_init()

{unsigned int mask;

unsigned int num_of_region = NIOS2_MPU_NUM_INST_REGIONS;

Nios2MPURegion region[NIOS2_MPU_NUM_INST_REGIONS];

//Main instruction region.

region[0].index = 0;

region[0].base = 0; // Byte Address 0

region[0].mask = 0x40;

region[0].c = 0;

region[0].perm = MPU_INST_PERM_SUPER_EXEC_USER_EXEC;

/* Rest of the regions are maximally sized and restrictive to supervisor/user. */

mask = 0x80000;

unsigned int index;

for (index = 1; index < num_of_region; index++){

region[index].base = 0x0;

region[index].index = index;

region[index].mask = mask;

region[index].c = 0;

region[index].perm = MPU_INST_PERM_SUPER_NONE_USER_NONE; //No access for user and supervisor

}

nios2_mpu_load_region(region, NIOS2_MPU_NUM_INST_REGIONS, 0);

}

I have also added "flushp"s in the MPU load region function:

void nios2_mpu_load_region(nios2mpuregion region[], unsigned int num_of_region, unsigned int d)

{unsigned int region_num;

Nios2MPURegion current_region;

for(region_num = 0; region_num < num_of_region; region_num++){

current_region = region[region_num];

nios2_write_mpubase(current_region.base /*base*/, current_region.index /*index*/, d /*d*/);

asm volatile("flushp");

nios2_write_mpuacc(current_region.mask /*mask*/, current_region.c /*c*/, current_region.perm /*perm*/, 0 /*rd*/, 1 /*wr*/);

asm volatile("flushp");

}

}

What am I doing wrong here?

Thanks in advance.

R
No RepliesBe the first to reply