From e6685ad87a7cb5125f745eb6a527c2962deb284d Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 1 Mar 2016 15:01:29 -0800 Subject: [PATCH] Use RV config string rather than FDT --- riscv/devicetree.h | 142 --------------------------------------------- riscv/sim.cc | 76 ++++++++++++------------ riscv/sim.h | 4 +- 3 files changed, 41 insertions(+), 181 deletions(-) delete mode 100644 riscv/devicetree.h diff --git a/riscv/devicetree.h b/riscv/devicetree.h deleted file mode 100644 index 5d4a871..0000000 --- a/riscv/devicetree.h +++ /dev/null @@ -1,142 +0,0 @@ -// See LICENSE for license details. - -#ifndef _RISCV_DEVICETREE_H -#define _RISCV_DEVICETREE_H - -#include -#include -#include -#include -#include -#include - -#define FDT_MAGIC 0xd00dfeedU -#define FDT_VERSION 17 -#define FDT_COMP_VERSION 16 -#define FDT_BEGIN_NODE 1 -#define FDT_END_NODE 2 -#define FDT_PROP 3 -#define FDT_END 9 - -struct fdt_header { - uint32_t magic; - uint32_t totalsize; - uint32_t off_dt_struct; - uint32_t off_dt_strings; - uint32_t off_rsvmap; - uint32_t version; - uint32_t last_comp_version; - uint32_t boot_cpuid_phys; - uint32_t size_dt_strings; - uint32_t size_dt_struct; -}; - -struct fdt_reserve_entry { - uint64_t address; - uint64_t size; -}; - -struct string_table { - std::map strings; - std::vector data; - - size_t add(std::string s) { - if (!strings.count(s)) { - strings[s] = data.size(); - data.insert(data.end(), s.begin(), s.end()); - data.push_back(0); - } - return strings[s]; - } -}; - -struct device_tree { - device_tree() { - memset(rsvmap, 0, sizeof(rsvmap)); - } - - void begin_node(std::string s) { - std::vector name = s2v(s); - sblock.push_back(FDT_BEGIN_NODE); - sblock.insert(sblock.end(), name.begin(), name.end()); - } - - void end_node() { - sblock.push_back(FDT_END_NODE); - } - - std::vector finalize() { - sblock.push_back(FDT_END); - - struct fdt_header h; - h.size_dt_struct = sblock.size() * sizeof(sblock[0]); - h.size_dt_strings = strings.data.size(); - h.magic = FDT_MAGIC; - h.off_rsvmap = sizeof(h); - h.off_dt_struct = h.off_rsvmap + sizeof(rsvmap); - h.off_dt_strings = h.off_dt_struct + h.size_dt_struct; - h.totalsize = h.off_dt_strings + h.size_dt_strings; - h.version = FDT_VERSION; - h.last_comp_version = FDT_COMP_VERSION; - h.boot_cpuid_phys = 0; - - for (uint32_t* p = &h.magic; p < &h.magic + sizeof(h)/sizeof(uint32_t); p++) - *p = htonl(*p); - for (uint32_t& p : sblock) - p = htonl(p); - - std::vector res; - res.insert(res.end(), (char*)&h, (char*)&h + sizeof(h)); - res.insert(res.end(), (char*)&rsvmap, (char*)&rsvmap + sizeof(rsvmap)); - res.insert(res.end(), (char*)&sblock[0], - (char*)&sblock[0] + sblock.size() * sizeof(sblock[0])); - res.insert(res.end(), strings.data.begin(), strings.data.end()); - return res; - } - - void add_prop(std::string name, uint32_t data) - { - add_prop(name, std::vector(1, data), sizeof(data)); - } - - void add_reg(std::vector values) - { - std::vector v; - for (auto x : values) { - v.push_back(x >> 32); - v.push_back(x); - } - add_prop("reg", v, v.size() * sizeof(v[0])); - } - - void add_prop(std::string name, std::string data) - { - add_prop(name, s2v(data), data.size()+1); - } - - private: - struct string_table strings; - std::vector sblock; - struct fdt_reserve_entry rsvmap[1]; - - std::vector s2v(std::string data) { - std::vector v(data.begin(), data.end()); - do { - v.push_back(0); - } while (v.size() % 4); - - std::vector words; - for (size_t i = 0; i < v.size(); i += 4) - words.push_back((v[i] << 24) | (v[i+1] << 16) | (v[i+2] << 8) | v[i+3]); - return words; - } - - void add_prop(std::string name, std::vector data, size_t len) { - sblock.push_back(FDT_PROP); - sblock.push_back(len); - sblock.push_back(strings.add(name)); - sblock.insert(sblock.end(), data.begin(), data.end()); - } -}; - -#endif diff --git a/riscv/sim.cc b/riscv/sim.cc index 5de93f2..f32de2b 100644 --- a/riscv/sim.cc +++ b/riscv/sim.cc @@ -2,9 +2,9 @@ #include "sim.h" #include "htif.h" -#include "devicetree.h" #include #include +#include #include #include #include @@ -45,7 +45,7 @@ sim_t::sim_t(const char* isa, size_t nprocs, size_t mem_mb, for (size_t i = 0; i < procs.size(); i++) procs[i] = new processor_t(isa, this, i); - make_device_tree(); + make_config_string(); } sim_t::~sim_t() @@ -155,40 +155,42 @@ bool sim_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes) return bus.store(addr, len, bytes); } -void sim_t::make_device_tree() +void sim_t::make_config_string() { - char buf[32]; - size_t max_devtree_size = procs.size() * 4096; // sloppy upper bound - size_t cpu_size = NCSR * procs[0]->max_xlen / 8; - reg_t cpu_addr = memsz + max_devtree_size; - - device_tree dt; - dt.begin_node(""); - dt.add_prop("#address-cells", 2); - dt.add_prop("#size-cells", 2); - dt.add_prop("model", "Spike"); - dt.begin_node("memory@0"); - dt.add_prop("device_type", "memory"); - dt.add_reg({0, memsz}); - dt.end_node(); - dt.begin_node("cpus"); - dt.add_prop("#address-cells", 2); - dt.add_prop("#size-cells", 2); - for (size_t i = 0; i < procs.size(); i++) { - sprintf(buf, "cpu@%" PRIx64, cpu_addr); - dt.begin_node(buf); - dt.add_prop("device_type", "cpu"); - dt.add_prop("compatible", "riscv"); - dt.add_prop("isa", procs[i]->isa_string); - dt.add_reg({cpu_addr}); - dt.end_node(); - - bus.add_device(cpu_addr, procs[i]); - cpu_addr += cpu_size; - } - dt.end_node(); - dt.end_node(); - - devicetree.reset(new rom_device_t(dt.finalize())); - bus.add_device(memsz, devicetree.get()); + size_t csr_size = NCSR * 16 /* RV128 */; + size_t device_tree_addr = memsz; + size_t cpu_addr = memsz + csr_size; + + std::stringstream s; + s << std::hex << + "platform {\n" + " vendor ucb;\n" + " arch spike;\n" + "};\n" + "ram {\n" + " 0 {\n" + " addr 0;\n" + " size 0x" << memsz << ";\n" + " };\n" + "};\n" + "core {\n"; + for (size_t i = 0; i < procs.size(); i++) { + s << + " " << i << " {\n" + " " << "0 {\n" << // hart 0 on core i + " isa " << procs[i]->isa_string << ";\n" + " addr 0x" << cpu_addr << ";\n" + " };\n" + " };\n"; + bus.add_device(cpu_addr, procs[i]); + cpu_addr += csr_size; + } + s << "};\n"; + + std::string str = s.str(); + std::vector vec(str.begin(), str.end()); + vec.push_back(0); + assert(vec.size() <= csr_size); + config_string.reset(new rom_device_t(vec)); + bus.add_device(memsz, config_string.get()); } diff --git a/riscv/sim.h b/riscv/sim.h index 6ef2c82..6745e75 100644 --- a/riscv/sim.h +++ b/riscv/sim.h @@ -43,7 +43,7 @@ private: size_t memsz; // memory size in bytes mmu_t* debug_mmu; // debug port into main memory std::vector procs; - std::unique_ptr devicetree; + std::unique_ptr config_string; bus_t bus; processor_t* get_core(const std::string& i); @@ -60,7 +60,7 @@ private: // memory-mapped I/O routines 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_device_tree(); + void make_config_string(); // presents a prompt for introspection into the simulation void interactive(); -- 2.30.2