Nios® II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.

NIOS II MPU initialisation

Altera_Forum
Honored Contributor II
884 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