aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2016-03-01 15:01:29 -0800
committerAndrew Waterman <waterman@cs.berkeley.edu>2016-03-02 12:15:25 -0800
commite6685ad87a7cb5125f745eb6a527c2962deb284d (patch)
tree49c1def3c63c0b51305524efc035594f95b0a8b6
parent5618582e2fdbece0c3125c430fc660faea479b62 (diff)
downloadspike-e6685ad87a7cb5125f745eb6a527c2962deb284d.zip
spike-e6685ad87a7cb5125f745eb6a527c2962deb284d.tar.gz
spike-e6685ad87a7cb5125f745eb6a527c2962deb284d.tar.bz2
Use RV config string rather than FDT
-rw-r--r--riscv/devicetree.h142
-rw-r--r--riscv/sim.cc76
-rw-r--r--riscv/sim.h4
3 files changed, 41 insertions, 181 deletions
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 <stdint.h>
-#include <string.h>
-#include <string>
-#include <map>
-#include <vector>
-#include <arpa/inet.h>
-
-#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<std::string, size_t> strings;
- std::vector<char> 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<uint32_t> 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<char> 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<char> 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<uint32_t>(1, data), sizeof(data));
- }
-
- void add_reg(std::vector<uint64_t> values)
- {
- std::vector<uint32_t> 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<uint32_t> sblock;
- struct fdt_reserve_entry rsvmap[1];
-
- std::vector<uint32_t> s2v(std::string data) {
- std::vector<char> v(data.begin(), data.end());
- do {
- v.push_back(0);
- } while (v.size() % 4);
-
- std::vector<uint32_t> 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<uint32_t> 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 <map>
#include <iostream>
+#include <sstream>
#include <climits>
#include <cstdlib>
#include <cassert>
@@ -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<char> 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<processor_t*> procs;
- std::unique_ptr<rom_device_t> devicetree;
+ std::unique_ptr<rom_device_t> 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();