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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [sw/] [lib/] [source/] [neorv32_cpu.c] - Diff between revs 42 and 45

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 42 Rev 45
Line 41... Line 41...
 
 
#include "neorv32.h"
#include "neorv32.h"
#include "neorv32_cpu.h"
#include "neorv32_cpu.h"
 
 
 
 
 
 
 
/**********************************************************************//**
 
 * >Private< helper functions.
 
 **************************************************************************/
 
static uint32_t __neorv32_cpu_pmp_cfg_read(uint32_t index);
 
static void __neorv32_cpu_pmp_cfg_write(uint32_t index, uint32_t data);
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Enable specific CPU interrupt.
 * Enable specific CPU interrupt.
 *
 *
 * @note Interrupts have to be globally enabled via neorv32_cpu_eint(void), too.
 * @note Interrupts have to be globally enabled via neorv32_cpu_eint(void), too.
 *
 *
Line 290... Line 298...
    return 1;
    return 1;
  }
  }
 
 
  return 0;
  return 0;
#else
#else
  return 1; // A extension not implemented -Y always fail
  return 1; // A extension not implemented - function always fails
#endif
#endif
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
Line 305... Line 313...
 *
 *
 * @return Returns number of available PMP regions.
 * @return Returns number of available PMP regions.
 **************************************************************************/
 **************************************************************************/
uint32_t neorv32_cpu_pmp_get_num_regions(void) {
uint32_t neorv32_cpu_pmp_get_num_regions(void) {
 
 
 
  uint32_t i = 0;
 
 
  // try setting R bit in all PMPCFG CSRs
  // try setting R bit in all PMPCFG CSRs
  neorv32_cpu_csr_write(CSR_PMPCFG0,  0x01010101);
  const uint32_t tmp = 0x01010101;
  neorv32_cpu_csr_write(CSR_PMPCFG1,  0x01010101);
  for (i=0; i<16; i++) {
  neorv32_cpu_csr_write(CSR_PMPCFG2,  0x01010101);
    __neorv32_cpu_pmp_cfg_write(i, tmp);
  neorv32_cpu_csr_write(CSR_PMPCFG3,  0x01010101);
  }
  neorv32_cpu_csr_write(CSR_PMPCFG4,  0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG5,  0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG6,  0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG7,  0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG8,  0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG9,  0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG10, 0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG11, 0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG12, 0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG13, 0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG14, 0x01010101);
 
  neorv32_cpu_csr_write(CSR_PMPCFG15, 0x01010101);
 
 
 
  // sum up all written ones (only available PMPCFG* CSRs/entries will return =! 0)
  // sum up all written ones (only available PMPCFG* CSRs/entries will return =! 0)
  union {
  union {
    uint32_t uint32;
    uint32_t uint32;
    uint8_t  uint8[sizeof(uint32_t)/sizeof(uint8_t)];
    uint8_t  uint8[sizeof(uint32_t)/sizeof(uint8_t)];
  } cnt;
  } cnt;
 
 
  cnt.uint32 = 0;
  cnt.uint32 = 0;
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG0);
  for (i=0; i<16; i++) {
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG1);
    cnt.uint32 += __neorv32_cpu_pmp_cfg_read(i);
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG2);
  }
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG3);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG4);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG5);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG6);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG7);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG8);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG9);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG10);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG11);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG12);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG13);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG14);
 
  cnt.uint32 += neorv32_cpu_csr_read(CSR_PMPCFG15);
 
 
 
  // sum up bytes
  // sum up bytes
  uint32_t num_regions = 0;
  uint32_t num_regions = 0;
  num_regions += (uint32_t)cnt.uint8[0];
  num_regions += (uint32_t)cnt.uint8[0];
  num_regions += (uint32_t)cnt.uint8[1];
  num_regions += (uint32_t)cnt.uint8[1];
Line 412... Line 397...
 
 
  if ((size & (size - 1)) != 0) {
  if ((size & (size - 1)) != 0) {
    return 1; // region size is not a power of two
    return 1; // region size is not a power of two
  }
  }
 
 
 
  // pmpcfg register index
 
  uint32_t pmpcfg_index = index >> 4; // 4 entries per pmpcfg csr
 
 
  // setup configuration
  // setup configuration
  uint32_t tmp;
  uint32_t tmp;
  uint32_t config_int  = ((uint32_t)config) << ((index%4)*8);
  uint32_t config_int  = ((uint32_t)config) << ((index%4)*8);
  uint32_t config_mask = ((uint32_t)0xFF)   << ((index%4)*8);
  uint32_t config_mask = ((uint32_t)0xFF)   << ((index%4)*8);
  config_mask = ~config_mask;
  config_mask = ~config_mask;
 
 
  // clear old configuration
  // clear old configuration
  switch(index & 15) {
  __neorv32_cpu_pmp_cfg_write(pmpcfg_index, __neorv32_cpu_pmp_cfg_read(pmpcfg_index) & config_mask);
    case 0:  neorv32_cpu_csr_write(CSR_PMPCFG0,  neorv32_cpu_csr_read(CSR_PMPCFG0)  & config_mask); break;
 
    case 1:  neorv32_cpu_csr_write(CSR_PMPCFG1,  neorv32_cpu_csr_read(CSR_PMPCFG1)  & config_mask); break;
 
    case 2:  neorv32_cpu_csr_write(CSR_PMPCFG2,  neorv32_cpu_csr_read(CSR_PMPCFG2)  & config_mask); break;
 
    case 3:  neorv32_cpu_csr_write(CSR_PMPCFG3,  neorv32_cpu_csr_read(CSR_PMPCFG3)  & config_mask); break;
 
    case 4:  neorv32_cpu_csr_write(CSR_PMPCFG4,  neorv32_cpu_csr_read(CSR_PMPCFG4)  & config_mask); break;
 
    case 5:  neorv32_cpu_csr_write(CSR_PMPCFG5,  neorv32_cpu_csr_read(CSR_PMPCFG5)  & config_mask); break;
 
    case 6:  neorv32_cpu_csr_write(CSR_PMPCFG6,  neorv32_cpu_csr_read(CSR_PMPCFG6)  & config_mask); break;
 
    case 7:  neorv32_cpu_csr_write(CSR_PMPCFG7,  neorv32_cpu_csr_read(CSR_PMPCFG7)  & config_mask); break;
 
    case 8:  neorv32_cpu_csr_write(CSR_PMPCFG8,  neorv32_cpu_csr_read(CSR_PMPCFG8)  & config_mask); break;
 
    case 9:  neorv32_cpu_csr_write(CSR_PMPCFG9,  neorv32_cpu_csr_read(CSR_PMPCFG9)  & config_mask); break;
 
    case 10: neorv32_cpu_csr_write(CSR_PMPCFG10, neorv32_cpu_csr_read(CSR_PMPCFG10) & config_mask); break;
 
    case 11: neorv32_cpu_csr_write(CSR_PMPCFG11, neorv32_cpu_csr_read(CSR_PMPCFG11) & config_mask); break;
 
    case 12: neorv32_cpu_csr_write(CSR_PMPCFG12, neorv32_cpu_csr_read(CSR_PMPCFG12) & config_mask); break;
 
    case 13: neorv32_cpu_csr_write(CSR_PMPCFG13, neorv32_cpu_csr_read(CSR_PMPCFG13) & config_mask); break;
 
    case 14: neorv32_cpu_csr_write(CSR_PMPCFG14, neorv32_cpu_csr_read(CSR_PMPCFG14) & config_mask); break;
 
    case 15: neorv32_cpu_csr_write(CSR_PMPCFG15, neorv32_cpu_csr_read(CSR_PMPCFG15) & config_mask); break;
 
    default: break;
 
  }
 
 
 
  // set base address and region size
  // set base address and region size
  uint32_t addr_mask = ~((size - 1) >> 2);
  uint32_t addr_mask = ~((size - 1) >> 2);
  uint32_t size_mask = (size - 1) >> 3;
  uint32_t size_mask = (size - 1) >> 3;
 
 
Line 520... Line 491...
  for (tmp=0; tmp<16; tmp++) {
  for (tmp=0; tmp<16; tmp++) {
    asm volatile ("nop");
    asm volatile ("nop");
  }
  }
 
 
  // set new configuration
  // set new configuration
 
  __neorv32_cpu_pmp_cfg_write(pmpcfg_index, __neorv32_cpu_pmp_cfg_read(pmpcfg_index) | config_int);
 
 
 
  return 0;
 
}
 
 
 
 
 
/**********************************************************************//**
 
 * Internal helper function: Read PMP configuration register 0..15
 
 *
 
 * @warning This function requires the PMP CPU extension.
 
 *
 
 * @param[in] index PMP CFG configuration register ID (0..15).
 
 * @return PMP CFG read data.
 
 **************************************************************************/
 
static uint32_t __neorv32_cpu_pmp_cfg_read(uint32_t index) {
 
 
 
  uint32_t tmp = 0;
  switch(index & 15) {
  switch(index & 15) {
    case 0:  neorv32_cpu_csr_write(CSR_PMPCFG0,  neorv32_cpu_csr_read(CSR_PMPCFG0)  | config_int); break;
    case 0:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG0);  break;
    case 1:  neorv32_cpu_csr_write(CSR_PMPCFG1,  neorv32_cpu_csr_read(CSR_PMPCFG1)  | config_int); break;
    case 1:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG1);  break;
    case 2:  neorv32_cpu_csr_write(CSR_PMPCFG2,  neorv32_cpu_csr_read(CSR_PMPCFG2)  | config_int); break;
    case 2:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG2);  break;
    case 3:  neorv32_cpu_csr_write(CSR_PMPCFG3,  neorv32_cpu_csr_read(CSR_PMPCFG3)  | config_int); break;
    case 3:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG3);  break;
    case 4:  neorv32_cpu_csr_write(CSR_PMPCFG4,  neorv32_cpu_csr_read(CSR_PMPCFG4)  | config_int); break;
    case 4:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG4);  break;
    case 5:  neorv32_cpu_csr_write(CSR_PMPCFG5,  neorv32_cpu_csr_read(CSR_PMPCFG5)  | config_int); break;
    case 5:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG5);  break;
    case 6:  neorv32_cpu_csr_write(CSR_PMPCFG6,  neorv32_cpu_csr_read(CSR_PMPCFG6)  | config_int); break;
    case 6:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG6);  break;
    case 7:  neorv32_cpu_csr_write(CSR_PMPCFG7,  neorv32_cpu_csr_read(CSR_PMPCFG7)  | config_int); break;
    case 7:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG7);  break;
    case 8:  neorv32_cpu_csr_write(CSR_PMPCFG8,  neorv32_cpu_csr_read(CSR_PMPCFG8)  | config_int); break;
    case 8:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG8);  break;
    case 9:  neorv32_cpu_csr_write(CSR_PMPCFG9,  neorv32_cpu_csr_read(CSR_PMPCFG9)  | config_int); break;
    case 9:  tmp = neorv32_cpu_csr_read(CSR_PMPCFG9);  break;
    case 10: neorv32_cpu_csr_write(CSR_PMPCFG10, neorv32_cpu_csr_read(CSR_PMPCFG10) | config_int); break;
    case 10: tmp = neorv32_cpu_csr_read(CSR_PMPCFG10); break;
    case 11: neorv32_cpu_csr_write(CSR_PMPCFG11, neorv32_cpu_csr_read(CSR_PMPCFG11) | config_int); break;
    case 11: tmp = neorv32_cpu_csr_read(CSR_PMPCFG11); break;
    case 12: neorv32_cpu_csr_write(CSR_PMPCFG12, neorv32_cpu_csr_read(CSR_PMPCFG12) | config_int); break;
    case 12: tmp = neorv32_cpu_csr_read(CSR_PMPCFG12); break;
    case 13: neorv32_cpu_csr_write(CSR_PMPCFG13, neorv32_cpu_csr_read(CSR_PMPCFG13) | config_int); break;
    case 13: tmp = neorv32_cpu_csr_read(CSR_PMPCFG13); break;
    case 14: neorv32_cpu_csr_write(CSR_PMPCFG14, neorv32_cpu_csr_read(CSR_PMPCFG14) | config_int); break;
    case 14: tmp = neorv32_cpu_csr_read(CSR_PMPCFG14); break;
    case 15: neorv32_cpu_csr_write(CSR_PMPCFG15, neorv32_cpu_csr_read(CSR_PMPCFG15) | config_int); break;
    case 15: tmp = neorv32_cpu_csr_read(CSR_PMPCFG15); break;
    default: break;
    default: break;
  }
  }
 
 
  return 0;
  return tmp;
 
}
 
 
 
 
 
/**********************************************************************//**
 
 * Internal helper function: Write PMP configuration register 0..15
 
 *
 
 * @warning This function requires the PMP CPU extension.
 
 *
 
 * @param[in] index PMP CFG configuration register ID (0..15).
 
 * @param[in] data PMP CFG write data.
 
 **************************************************************************/
 
static void __neorv32_cpu_pmp_cfg_write(uint32_t index, uint32_t data) {
 
 
 
  switch(index & 15) {
 
    case 0:  neorv32_cpu_csr_write(CSR_PMPCFG0,  data); break;
 
    case 1:  neorv32_cpu_csr_write(CSR_PMPCFG1,  data); break;
 
    case 2:  neorv32_cpu_csr_write(CSR_PMPCFG2,  data); break;
 
    case 3:  neorv32_cpu_csr_write(CSR_PMPCFG3,  data); break;
 
    case 4:  neorv32_cpu_csr_write(CSR_PMPCFG4,  data); break;
 
    case 5:  neorv32_cpu_csr_write(CSR_PMPCFG5,  data); break;
 
    case 6:  neorv32_cpu_csr_write(CSR_PMPCFG6,  data); break;
 
    case 7:  neorv32_cpu_csr_write(CSR_PMPCFG7,  data); break;
 
    case 8:  neorv32_cpu_csr_write(CSR_PMPCFG8,  data); break;
 
    case 9:  neorv32_cpu_csr_write(CSR_PMPCFG9,  data); break;
 
    case 10: neorv32_cpu_csr_write(CSR_PMPCFG10, data); break;
 
    case 11: neorv32_cpu_csr_write(CSR_PMPCFG11, data); break;
 
    case 12: neorv32_cpu_csr_write(CSR_PMPCFG12, data); break;
 
    case 13: neorv32_cpu_csr_write(CSR_PMPCFG13, data); break;
 
    case 14: neorv32_cpu_csr_write(CSR_PMPCFG14, data); break;
 
    case 15: neorv32_cpu_csr_write(CSR_PMPCFG15, data); break;
 
    default: break;
 
  }
}
}
 
 
 
 
/**********************************************************************//**
/**********************************************************************//**
 * Hardware performance monitors (HPM): Get number of available HPM counters.
 * Hardware performance monitors (HPM): Get number of available HPM counters.

powered by: WebSVN 2.1.0

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