#ifndef _RISCV_DEVICES_H #define _RISCV_DEVICES_H #include "decode.h" #include "mmio_plugin.h" #include #include #include #include #include class processor_t; class abstract_device_t { public: virtual bool load(reg_t addr, size_t len, uint8_t* bytes) = 0; virtual bool store(reg_t addr, size_t len, const uint8_t* bytes) = 0; virtual ~abstract_device_t() {} }; class bus_t : public abstract_device_t { public: bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); void add_device(reg_t addr, abstract_device_t* dev); std::pair find_device(reg_t addr); private: std::map devices; }; class rom_device_t : public abstract_device_t { public: rom_device_t(std::vector data); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); const std::vector& contents() { return data; } private: std::vector data; }; class mem_t : public abstract_device_t { public: mem_t(size_t size) : len(size) { if (!size) throw std::runtime_error("zero bytes of target memory requested"); data = (char*)calloc(1, size); if (!data) throw std::runtime_error("couldn't allocate " + std::to_string(size) + " bytes of target memory"); } mem_t(const mem_t& that) = delete; ~mem_t() { free(data); } bool load(reg_t addr, size_t len, uint8_t* bytes) { return false; } bool store(reg_t addr, size_t len, const uint8_t* bytes) { return false; } char* contents() { return data; } size_t size() { return len; } private: char* data; size_t len; }; class clint_t : public abstract_device_t { public: clint_t(std::vector&, uint64_t freq_hz, bool real_time); bool load(reg_t addr, size_t len, uint8_t* bytes); bool store(reg_t addr, size_t len, const uint8_t* bytes); size_t size() { return CLINT_SIZE; } void increment(reg_t inc); private: typedef uint64_t mtime_t; typedef uint64_t mtimecmp_t; typedef uint32_t msip_t; std::vector& procs; uint64_t freq_hz; bool real_time; uint64_t real_time_ref_secs; uint64_t real_time_ref_usecs; mtime_t mtime; std::vector mtimecmp; }; class mmio_plugin_device_t : public abstract_device_t { public: mmio_plugin_device_t(const std::string& name, const std::string& args); virtual ~mmio_plugin_device_t() override; virtual bool load(reg_t addr, size_t len, uint8_t* bytes) override; virtual bool store(reg_t addr, size_t len, const uint8_t* bytes) override; private: mmio_plugin_t plugin; void* user_data; }; #endif