Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

NIOS II MPU initialisation

Altera_Forum
Honored Contributor II
1,551 Views

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
0 Kudos
0 Replies
Reply