X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=riscv%2Fsim.h;h=9a0a10b2569ba4a6aa8190fb5a540108f5a85a72;hb=9d1e10a36e771bf8cfbf515e07e856e021c1007a;hp=d3353a1bbcfd4cebb79abcfddadd11c552b14ea1;hpb=84e1ac19ed5a69224aa8c3f920e3840fbc670771;p=riscv-isa-sim.git diff --git a/riscv/sim.h b/riscv/sim.h index d3353a1..9a0a10b 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -15,12 +15,25 @@ class mmu_t; class remote_bitbang_t; +// this is the interface to the simulator used by the processors and memory +class simif_t +{ +public: + // should return NULL for MMIO addresses + virtual char* addr_to_mem(reg_t addr) = 0; + // used for MMIO addresses + virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0; + virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0; +}; + // this class encapsulates the processors and memory in a RISC-V machine. -class sim_t : public htif_t +class sim_t : public htif_t, public simif_t { public: - sim_t(const char* isa, size_t _nprocs, size_t mem_mb, bool halted, - const std::vector& args); + sim_t(const char* isa, size_t _nprocs, bool halted, reg_t start_pc, + std::vector> mems, + const std::vector& args, const std::vector hartids, + unsigned progsize, unsigned max_bus_master_bits, bool require_authentication); ~sim_t(); // run the simulation to completion @@ -32,17 +45,15 @@ public: void set_remote_bitbang(remote_bitbang_t* remote_bitbang) { this->remote_bitbang = remote_bitbang; } - const char* get_dts() { return dts.c_str(); } + const char* get_dts() { if (dts.empty()) reset(); return dts.c_str(); } processor_t* get_core(size_t i) { return procs.at(i); } unsigned nprocs() const { return procs.size(); } - debug_module_t debug_module; - private: - char* mem; // main memory - size_t memsz; // memory size in bytes + std::vector> mems; mmu_t* debug_mmu; // debug port into main memory std::vector procs; + reg_t start_pc; std::string dts; std::unique_ptr boot_rom; std::unique_ptr clint; @@ -61,11 +72,7 @@ private: remote_bitbang_t* remote_bitbang; // memory-mapped I/O routines - bool addr_is_mem(reg_t addr) { - return addr >= DRAM_BASE && addr < DRAM_BASE + memsz; - } - char* addr_to_mem(reg_t addr) { return mem + addr - DRAM_BASE; } - reg_t mem_to_addr(char* x) { return x - mem + DRAM_BASE; } + char* addr_to_mem(reg_t addr); 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_dtb(); @@ -94,6 +101,7 @@ private: friend class processor_t; friend class mmu_t; + friend class debug_module_t; // htif friend void sim_thread_main(void*); @@ -101,12 +109,18 @@ private: context_t* host; context_t target; - void reset() { } + void reset(); void idle(); void read_chunk(addr_t taddr, size_t len, void* dst); void write_chunk(addr_t taddr, size_t len, const void* src); size_t chunk_align() { return 8; } size_t chunk_max_size() { return 8; } + +public: + // Initialize this after procs, because in debug_module_t::reset() we + // enumerate processors, which segfaults if procs hasn't been initialized + // yet. + debug_module_t debug_module; }; extern volatile bool ctrlc_pressed;