Hazard3/test/sim/sw_testcases/include/pmp.h

158 lines
2.8 KiB
C

#ifndef _PMP_H
#define _PMP_H
#include "hazard3_csr.h"
#define PMPCFG_L_LSB 7
#define PMPCFG_L_BITS 0x80
#define PMPCFG_A_LSB 3
#define PMPCFG_A_BITS 0x18
#define PMPCFG_R_BITS 0x01
#define PMPCFG_W_BITS 0x02
#define PMPCFG_X_BITS 0x04
#define PMPCFG_A_OFF 0x0
#define PMPCFG_A_TOR 0x1
#define PMPCFG_A_NA4 0x2
#define PMPCFG_A_NAPOT 0x3
// Note these aren't declared as inline -- presumably ok as our tests are single C files
void write_pmpaddr(unsigned int region, uintptr_t addr) {
switch (region) {
case 0:
write_csr(pmpaddr0, addr);
break;
case 1:
write_csr(pmpaddr1, addr);
break;
case 2:
write_csr(pmpaddr2, addr);
break;
case 3:
write_csr(pmpaddr3, addr);
break;
case 4:
write_csr(pmpaddr4, addr);
break;
case 5:
write_csr(pmpaddr5, addr);
break;
case 6:
write_csr(pmpaddr6, addr);
break;
case 7:
write_csr(pmpaddr7, addr);
break;
case 8:
write_csr(pmpaddr8, addr);
break;
case 9:
write_csr(pmpaddr9, addr);
break;
case 10:
write_csr(pmpaddr10, addr);
break;
case 11:
write_csr(pmpaddr11, addr);
break;
case 12:
write_csr(pmpaddr12, addr);
break;
case 13:
write_csr(pmpaddr13, addr);
break;
case 14:
write_csr(pmpaddr14, addr);
break;
case 15:
write_csr(pmpaddr15, addr);
break;
}
}
uintptr_t read_pmpaddr(unsigned int region) {
switch (region) {
case 0:
return read_csr(pmpaddr0);
case 1:
return read_csr(pmpaddr1);
case 2:
return read_csr(pmpaddr2);
case 3:
return read_csr(pmpaddr3);
case 4:
return read_csr(pmpaddr4);
case 5:
return read_csr(pmpaddr5);
case 6:
return read_csr(pmpaddr6);
case 7:
return read_csr(pmpaddr7);
case 8:
return read_csr(pmpaddr8);
case 9:
return read_csr(pmpaddr9);
case 10:
return read_csr(pmpaddr10);
case 11:
return read_csr(pmpaddr11);
case 12:
return read_csr(pmpaddr12);
case 13:
return read_csr(pmpaddr13);
case 14:
return read_csr(pmpaddr14);
case 15:
return read_csr(pmpaddr15);
default:
return 0;
}
}
void write_pmpcfg(unsigned int region, uint8_t cfg) {
int regnum = region / 4;
int lsb = (region % 4) * 8;
uint32_t set_mask = (uint32_t)cfg << lsb;
uint32_t clr_mask = ~(uint32_t)cfg & 0xffu << lsb;
switch (regnum) {
case 0:
clear_csr(pmpcfg0, clr_mask);
set_csr(pmpcfg0, set_mask);
break;
case 1:
clear_csr(pmpcfg1, clr_mask);
set_csr(pmpcfg1, set_mask);
break;
case 2:
clear_csr(pmpcfg2, clr_mask);
set_csr(pmpcfg2, set_mask);
break;
case 3:
clear_csr(pmpcfg3, clr_mask);
set_csr(pmpcfg3, set_mask);
break;
}
}
uint8_t read_pmpcfg(unsigned int region) {
uint32_t cfgreg = 0;
switch (region / 4) {
case 0:
cfgreg = read_csr(pmpcfg0);
break;
case 1:
cfgreg = read_csr(pmpcfg1);
break;
case 2:
cfgreg = read_csr(pmpcfg2);
break;
case 3:
cfgreg = read_csr(pmpcfg3);
break;
}
return (cfgreg >> (region % 4 * 8)) & 0xffu;
}
#endif