#define IRQ_COP 12
#define IRQ_HOST 13
-#define DEFAULT_RSTVEC 0x1000
-#define DEFAULT_NMIVEC 0x1004
-#define CFGSTRING_ADDR 0x100C
-#define DEFAULT_MTVEC 0x1010
-#define IO_BASE 0x40000000
-#define MEM_BASE 0x80000000
+#define DEFAULT_RSTVEC 0x00001000
+#define DEFAULT_NMIVEC 0x00001004
+#define DEFAULT_MTVEC 0x00001010
+#define CONFIG_STRING_ADDR 0x0000100C
+#define EXT_IO_BASE 0x40000000
+#define DRAM_BASE 0x80000000
// page table entry (PTE) fields
#define PTE_V 0x001 // Valid
#define CSR_MSTIME_DELTA 0x705
#define CSR_MSINSTRET_DELTA 0x706
#define CSR_MCYCLE 0xf00
+#define CSR_MTIME 0xf01
#define CSR_MINSTRET 0xf02
#define CSR_MISA 0xf10
#define CSR_MVENDORID 0xf11
#define CSR_MARCHID 0xf12
#define CSR_MIMPID 0xf13
-#define CSR_MCFGADDR 0xf14
-#define CSR_MHARTID 0xf15
+#define CSR_MHARTID 0xf14
#define CSR_MTOHOST 0x7c0
#define CSR_MFROMHOST 0x7c1
#define CSR_MRESET 0x7c2
#define CSR_MSTIME_DELTAH 0x785
#define CSR_MSINSTRET_DELTAH 0x786
#define CSR_MCYCLEH 0xf80
+#define CSR_MTIMEH 0xf81
#define CSR_MINSTRETH 0xf82
#define CAUSE_MISALIGNED_FETCH 0x0
#define CAUSE_FAULT_FETCH 0x1
DECLARE_CSR(mstime_delta, CSR_MSTIME_DELTA)
DECLARE_CSR(msinstret_delta, CSR_MSINSTRET_DELTA)
DECLARE_CSR(mcycle, CSR_MCYCLE)
+DECLARE_CSR(mtime, CSR_MTIME)
DECLARE_CSR(minstret, CSR_MINSTRET)
DECLARE_CSR(misa, CSR_MISA)
DECLARE_CSR(mvendorid, CSR_MVENDORID)
DECLARE_CSR(marchid, CSR_MARCHID)
DECLARE_CSR(mimpid, CSR_MIMPID)
-DECLARE_CSR(mcfgaddr, CSR_MCFGADDR)
DECLARE_CSR(mhartid, CSR_MHARTID)
DECLARE_CSR(mtohost, CSR_MTOHOST)
DECLARE_CSR(mfromhost, CSR_MFROMHOST)
DECLARE_CSR(mstime_deltah, CSR_MSTIME_DELTAH)
DECLARE_CSR(msinstret_deltah, CSR_MSINSTRET_DELTAH)
DECLARE_CSR(mcycleh, CSR_MCYCLEH)
+DECLARE_CSR(mtimeh, CSR_MTIMEH)
DECLARE_CSR(minstreth, CSR_MINSTRETH)
#endif
#ifdef DECLARE_CAUSE
packet_header_t ack(HTIF_CMD_ACK, seqno, 1, 0);
send(&ack, sizeof(ack));
- if (coreid == 0xFFFFF) // system control register space
- {
- uint64_t scr = sim->get_scr(regno);
- send(&scr, sizeof(scr));
- break;
- }
-
processor_t* proc = sim->get_core(coreid);
bool write = hdr.cmd == HTIF_CMD_WRITE_CONTROL_REG;
if (write)
case CSR_MFROMHOST:
sim->get_htif()->tick(); // not necessary, but faster
return state.fromhost;
- case CSR_MCFGADDR: return sim->config_string_addr;
}
throw trap_illegal_instruction();
}
free(mem);
}
-reg_t sim_t::get_scr(int which)
-{
- switch (which)
- {
- case 0: return procs.size();
- case 1: return memsz >> 20;
- default: return -1;
- }
-}
-
int sim_t::run()
{
if (!debug && log)
void sim_t::make_config_string()
{
- reg_t rtc_addr = IO_BASE;
+ reg_t boot_rom_addr = DEFAULT_RSTVEC;
+ reg_t boot_rom_size = 0x2000;
+ reg_t rtc_addr = boot_rom_addr + boot_rom_size;
bus.add_device(rtc_addr, rtc.get());
uint32_t reset_vec[8] = {
- 0x297 + MEM_BASE - DEFAULT_RSTVEC, // reset vector
- 0x00028067, // jump straight to MEM_BASE
- 0x00000000, // reserved
- 0, // pointer to configuration string
- 0, 0, 0, 0 // trap vector
+ 0x297 + DRAM_BASE - DEFAULT_RSTVEC, // reset vector
+ 0x00028067, // jump straight to DRAM_BASE
+ 0x00000000, // reserved
+ 0, // config string pointer
+ 0, 0, 0, 0 // trap vector
};
- config_string_addr = DEFAULT_RSTVEC + sizeof(reset_vec);
- reset_vec[3] = config_string_addr;
+ reset_vec[3] = boot_rom_addr + sizeof(reset_vec); // config string pointer
std::vector<char> rom((char*)reset_vec, (char*)reset_vec + sizeof(reset_vec));
"};\n"
"ram {\n"
" 0 {\n"
- " addr 0x" << MEM_BASE << ";\n"
- " size 0x" << (MEM_BASE + memsz) << ";\n"
+ " addr 0x" << DRAM_BASE << ";\n"
+ " size 0x" << memsz << ";\n"
" };\n"
"};\n"
"core {\n";
config_string = s.str();
rom.insert(rom.end(), config_string.begin(), config_string.end());
- rom.push_back(0);
+ assert(rom.size() < boot_rom_size);
+ rom.resize(boot_rom_size);
+
boot_rom.reset(new rom_device_t(rom));
- bus.add_device(DEFAULT_RSTVEC, boot_rom.get());
+ bus.add_device(boot_rom_addr, boot_rom.get());
}
size_t num_cores() { return procs.size(); }
processor_t* get_core(size_t i) { return procs.at(i); }
- // read one of the system control registers
- reg_t get_scr(int which);
-
private:
std::unique_ptr<htif_isasim_t> htif;
char* mem; // main memory
std::string config_string;
std::unique_ptr<rom_device_t> boot_rom;
std::unique_ptr<rtc_t> rtc;
- reg_t config_string_addr;
bus_t bus;
processor_t* get_core(const std::string& i);
// memory-mapped I/O routines
bool addr_is_mem(reg_t addr) {
- return addr >= MEM_BASE && addr < MEM_BASE + memsz;
+ return addr >= DRAM_BASE && addr < DRAM_BASE + memsz;
}
- char* addr_to_mem(reg_t addr) { return mem + addr - MEM_BASE; }
- reg_t mem_to_addr(char* x) { return x - mem + MEM_BASE; }
+ char* addr_to_mem(reg_t addr) { return mem + addr - DRAM_BASE; }
+ reg_t mem_to_addr(char* x) { return x - mem + DRAM_BASE; }
bool mmio_load(reg_t addr, size_t len, uint8_t* bytes);
bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes);
void make_config_string();