OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /neorv32/trunk/sw/lib/source
    from Rev 39 to Rev 40
    Reverse comparison

Rev 39 → Rev 40

/neorv32_cpu.c
295,3 → 295,123
return 1; // A extension not implemented -Y always fail
#endif
}
 
 
/**********************************************************************//**
* Physical memory protection (PMP): Get minimal region size (granularity).
*
* @warning This function overrides PMPCFG0[0] and PMPADDR0 CSRs.
*
* @warning This function requires the PMP CPU extension.
*
* @return Returns minimal region size in bytes; Returns 0 on failure.
**************************************************************************/
uint32_t neorv32_cpu_pmp_get_granularity(void) {
 
if ((neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) == 0) {
return 0; // PMP not implemented
}
 
// check min granulartiy
uint32_t tmp = neorv32_cpu_csr_read(CSR_PMPCFG0);
tmp &= 0xffffff00; // disable entry 0
neorv32_cpu_csr_write(CSR_PMPCFG0, tmp);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
uint32_t tmp_a = neorv32_cpu_csr_read(CSR_PMPADDR0);
 
uint32_t i;
 
// find least-significat set bit
for (i=31; i!=0; i--) {
if (((tmp_a >> i) & 1) == 0) {
break;
}
}
 
return (uint32_t)(1 << (i+1+2));
}
 
 
/**********************************************************************//**
* Physical memory protection (PMP): Configure region.
*
* @note Using NAPOT mode - page base address has to be naturally aligned.
*
* @warning This function requires the PMP CPU extension.
*
* @param[in] index Region number (index, 0..max_regions-1).
* @param[in] base Region base address (has to be naturally aligned!).
* @param[in] size Region size, has to be a power of 2 (min 8 bytes or according to HW's PMP.granularity configuration).
* @param[in] config Region configuration (attributes) byte (for PMPCFGx).
* @return Returns 0 on success, 1 on failure.
**************************************************************************/
int neorv32_cpu_pmp_configure_region(uint32_t index, uint32_t base, uint32_t size, uint8_t config) {
 
if ((neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) == 0) {
return 1; // PMP not implemented
}
 
if (size < 8) {
return 1; // minimal region size is 8 bytes
}
 
if ((size & (size - 1)) != 0) {
return 1; // region size is not a power of two
}
 
// setup configuration
uint32_t tmp;
uint32_t config_int = ((uint32_t)config) << ((index%4)*8);
uint32_t config_mask = ((uint32_t)0xFF) << ((index%4)*8);
config_mask = ~config_mask;
 
// clear old configuration
if (index < 3) {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG0);
tmp &= config_mask; // clear old config
neorv32_cpu_csr_write(CSR_PMPCFG0, tmp);
}
else {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG1);
tmp &= config_mask; // clear old config
neorv32_cpu_csr_write(CSR_PMPCFG1, tmp);
}
 
// set base address and region size
uint32_t addr_mask = ~((size - 1) >> 2);
uint32_t size_mask = (size - 1) >> 3;
 
tmp = base & addr_mask;
tmp = tmp | size_mask;
 
switch(index & 7) {
case 0: neorv32_cpu_csr_write(CSR_PMPADDR0, tmp); break;
case 1: neorv32_cpu_csr_write(CSR_PMPADDR1, tmp); break;
case 2: neorv32_cpu_csr_write(CSR_PMPADDR2, tmp); break;
case 3: neorv32_cpu_csr_write(CSR_PMPADDR3, tmp); break;
case 4: neorv32_cpu_csr_write(CSR_PMPADDR4, tmp); break;
case 5: neorv32_cpu_csr_write(CSR_PMPADDR5, tmp); break;
case 6: neorv32_cpu_csr_write(CSR_PMPADDR6, tmp); break;
case 7: neorv32_cpu_csr_write(CSR_PMPADDR7, tmp); break;
default: break;
}
 
// wait for HW to computer PMP-internal stuff (address masks)
for (tmp=0; tmp<16; tmp++) {
asm volatile ("nop");
}
 
// set new configuration
if (index < 3) {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG0);
tmp |= config_int; // set new config
neorv32_cpu_csr_write(CSR_PMPCFG0, tmp);
}
else {
tmp = neorv32_cpu_csr_read(CSR_PMPCFG1);
tmp |= config_int; // set new config
neorv32_cpu_csr_write(CSR_PMPCFG1, tmp);
}
 
return 0;
}
/neorv32_rte.c
45,7 → 45,7
/**********************************************************************//**
* The >private< trap vector look-up table of the NEORV32 RTE.
**************************************************************************/
static uint32_t __neorv32_rte_vector_lut[16] __attribute__((unused)); // trap handler vector table
static uint32_t __neorv32_rte_vector_lut[17] __attribute__((unused)); // trap handler vector table
 
// private functions
static void __attribute__((__interrupt__)) __neorv32_rte_core(void) __attribute__((aligned(16))) __attribute__((unused));
94,8 → 94,8
 
// id valid?
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) || (id == RTE_TRAP_UENV_CALL) ||
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
 
121,8 → 121,8
 
// id valid?
if ((id == RTE_TRAP_I_MISALIGNED) || (id == RTE_TRAP_I_ACCESS) || (id == RTE_TRAP_I_ILLEGAL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) ||
(id == RTE_TRAP_BREAKPOINT) || (id == RTE_TRAP_L_MISALIGNED) || (id == RTE_TRAP_L_ACCESS) ||
(id == RTE_TRAP_S_MISALIGNED) || (id == RTE_TRAP_S_ACCESS) || (id == RTE_TRAP_MENV_CALL) || (id == RTE_TRAP_UENV_CALL) ||
(id == RTE_TRAP_MSI) || (id == RTE_TRAP_MTI) || (id == RTE_TRAP_MEI) ||
(id == RTE_TRAP_FIRQ_0) || (id == RTE_TRAP_FIRQ_1) || (id == RTE_TRAP_FIRQ_2) || (id == RTE_TRAP_FIRQ_3)) {
 
177,6 → 177,7
case TRAP_CODE_L_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_L_ACCESS]; break;
case TRAP_CODE_S_MISALIGNED: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_MISALIGNED]; break;
case TRAP_CODE_S_ACCESS: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_S_ACCESS]; break;
case TRAP_CODE_UENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_UENV_CALL]; break;
case TRAP_CODE_MENV_CALL: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MENV_CALL]; break;
case TRAP_CODE_MSI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MSI]; break;
case TRAP_CODE_MTI: rte_handler = __neorv32_rte_vector_lut[RTE_TRAP_MTI]; break;
215,7 → 216,8
case TRAP_CODE_L_ACCESS: neorv32_uart_print("Load access fault"); break;
case TRAP_CODE_S_MISALIGNED: neorv32_uart_print("Store address misaligned"); break;
case TRAP_CODE_S_ACCESS: neorv32_uart_print("Store access fault"); break;
case TRAP_CODE_MENV_CALL: neorv32_uart_print("Environment call"); break;
case TRAP_CODE_UENV_CALL: neorv32_uart_print("Environment call from U-mode"); break;
case TRAP_CODE_MENV_CALL: neorv32_uart_print("Environment call from M-mode"); break;
case TRAP_CODE_MSI: neorv32_uart_print("Machine software interrupt"); break;
case TRAP_CODE_MTI: neorv32_uart_print("Machine timer interrupt"); break;
case TRAP_CODE_MEI: neorv32_uart_print("Machine external interrupt"); break;
249,7 → 251,7
neorv32_uart_printf("\n\n<< Hardware Configuration Overview >>\n");
 
// CPU configuration
neorv32_uart_printf("\n-- Central Processing Unit --\n");
neorv32_uart_printf("\n---- Central Processing Unit ----\n");
 
// ID
neorv32_uart_printf("Hart ID: 0x%x\n", neorv32_cpu_csr_read(CSR_MHARTID));
285,6 → 287,15
}
// CPU extensions
neorv32_uart_printf("\nEndianness: ");
if (neorv32_cpu_csr_read(CSR_MSTATUSH) & (1<<CPU_MSTATUSH_MBE)) {
neorv32_uart_printf("big\n");
}
else {
neorv32_uart_printf("little\n");
}
// CPU extensions
neorv32_uart_printf("\nExtensions: ");
tmp = neorv32_cpu_csr_read(CSR_MISA);
for (i=0; i<26; i++) {
295,7 → 306,7
}
}
// Z* CPU extensions (from custom CSR "mzext")
// Z* CPU extensions (from custom "mzext" CSR)
tmp = neorv32_cpu_csr_read(CSR_MZEXT);
if (tmp & (1<<CPU_MZEXT_ZICSR)) {
neorv32_uart_printf("Zicsr ");
306,6 → 317,9
if (tmp & (1<<CPU_MZEXT_PMP)) {
neorv32_uart_printf("PMP ");
}
if (tmp & (1<<CPU_MZEXT_ZICNT)) {
neorv32_uart_printf("Zicnt ");
}
 
 
// check physical memory protection
312,27 → 326,9
neorv32_uart_printf("\n\nPhysical memory protection: ");
if (neorv32_cpu_csr_read(CSR_MZEXT) & (1<<CPU_MZEXT_PMP)) {
 
// check granulartiy
neorv32_cpu_csr_write(CSR_PMPCFG0, 0);
neorv32_cpu_csr_write(CSR_PMPADDR0, 0xffffffff);
uint32_t pmp_test_g = neorv32_cpu_csr_read(0x3b0);
// get minimal region siz (granulartiy)
neorv32_uart_printf("\n- Minimal granularity: %u bytes per region\n", neorv32_cpu_pmp_get_granularity());
 
// find least-significat set bit
for (i=31; i!=0; i--) {
if (((pmp_test_g >> i) & 1) == 0) {
break;
}
}
 
neorv32_uart_printf("\n- Min granularity: ");
if (i < 29) {
neorv32_uart_printf("%u bytes per region\n", (uint32_t)(1 << (i+1+2)));
}
else {
neorv32_uart_printf("2^%u bytes per region\n", i+1+2);
}
 
// test available modes
neorv32_uart_printf("- Mode TOR: ");
neorv32_cpu_csr_write(CSR_PMPCFG0, 0x08);
370,13 → 366,13
 
 
// Misc - system
neorv32_uart_printf("\n\n-- Processor --\n");
neorv32_uart_printf("\n\n---- Processor - General ----\n");
neorv32_uart_printf("Clock: %u Hz\n", SYSINFO_CLK);
neorv32_uart_printf("User ID: 0x%x\n", SYSINFO_USER_CODE);
 
 
// Memory configuration
neorv32_uart_printf("\n-- Processor Memory Configuration --\n");
neorv32_uart_printf("\n---- Processor - Memory Configuration ----\n");
 
neorv32_uart_printf("Instr. base address: 0x%x\n", SYSINFO_ISPACE_BASE);
neorv32_uart_printf("Internal IMEM: ");
385,7 → 381,7
neorv32_uart_printf("Internal IMEM as ROM: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_IMEM_ROM));
 
neorv32_uart_printf("Data base address: 0x%x\n", SYSINFO_DSPACE_BASE);
neorv32_uart_printf("\nData base address: 0x%x\n", SYSINFO_DSPACE_BASE);
neorv32_uart_printf("Internal DMEM: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_INT_DMEM));
neorv32_uart_printf("DMEM size: %u bytes\n", SYSINFO_DMEM_SIZE);
393,11 → 389,18
neorv32_uart_printf("Bootloader: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_BOOTLOADER));
 
neorv32_uart_printf("External M interface: ");
neorv32_uart_printf("\nExternal memory bus interface: ");
__neorv32_rte_print_true_false(SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT));
neorv32_uart_printf("External memory bus Endianness: ");
if (SYSINFO_FEATURES & (1 << SYSINFO_FEATURES_MEM_EXT_ENDIAN)) {
neorv32_uart_printf("big\n");
}
else {
neorv32_uart_printf("little\n");
}
 
// peripherals
neorv32_uart_printf("\n-- Available Processor Peripherals --\n");
neorv32_uart_printf("\n\n---- Processor - Peripherals ----\n");
 
tmp = SYSINFO_FEATURES;
 
516,20 → 519,39
**************************************************************************/
void neorv32_rte_print_logo(void) {
 
neorv32_uart_print(
"\n"
" ##\n"
" ## ## ## ##\n"
" ## ## ######### ######## ######## ## ## ######## ######## ## ###############\n"
"#### ## ## ## ## ## ## ## ## ## ## ## ## ## #### ####\n"
"## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ##\n"
"## ## ## ######### ## ## ######### ## ## ##### ## ## #### ##### ####\n"
"## ## ## ## ## ## ## ## ## ## ## ## ## ## ##### ##\n"
"## #### ## ## ## ## ## ## ## ## ## ## ## #### ####\n"
"## ## ######### ######## ## ## ## ######## ########## ## ###############\n"
" ## ## ## ##\n"
" ##\n"
"\n");
const uint32_t logo_data_c[11][4] =
{
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000},
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
{0b01100000110001111111110001111111,0b10000111111110001100000011000111,0b11111000011111111000000110000000,0b11111111111111110000000000000000},
{0b11110000110011000000000011000000,0b11001100000011001100000011001100,0b00001100110000001100000110000011,0b11000000000000111100000000000000},
{0b11011000110011000000000011000000,0b11001100000011001100000011000000,0b00001100000000011000000110000000,0b11000111111000110000000000000000},
{0b11001100110011111111100011000000,0b11001111111110001100000011000000,0b11111000000001100000000110000011,0b11000111111000111100000000000000},
{0b11000110110011000000000011000000,0b11001100001100000110000110000000,0b00001100000110000000000110000000,0b11000111111000110000000000000000},
{0b11000011110011000000000011000000,0b11001100000110000011001100001100,0b00001100011000000000000110000011,0b11000000000000111100000000000000},
{0b11000001100001111111110001111111,0b10001100000011000000110000000111,0b11111000111111111100000110000000,0b11111111111111110000000000000000},
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00110001100011000000000000000000},
{0b00000000000000000000000000000000,0b00000000000000000000000000000000,0b00000000000000000000000110000000,0b00000000000000000000000000000000}
};
 
int u,v,w;
uint32_t tmp;
 
for (u=0; u<11; u++) {
neorv32_uart_print("\n");
for (v=0; v<4; v++) {
tmp = logo_data_c[u][v];
for (w=0; w<32; w++){
if (tmp & (1 << (31-w))) {
neorv32_uart_putc('#');
}
else {
neorv32_uart_putc(' ');
}
}
}
}
neorv32_uart_print("\n");
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.