+ reg_t rtc_addr = EXT_IO_BASE;
+ bus.add_device(rtc_addr, rtc.get());
+
+ const int align = 0x1000;
+ reg_t cpu_addr = rtc_addr + ((rtc->size() - 1) / align + 1) * align;
+ reg_t cpu_size = align;
+
+ uint32_t reset_vec[8] = {
+ 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
+ };
+ reset_vec[3] = DEFAULT_RSTVEC + sizeof(reset_vec); // config string pointer
+
+ std::vector<char> rom((char*)reset_vec, (char*)reset_vec + sizeof(reset_vec));
+
+ std::stringstream s;
+ s << std::hex <<
+ "platform {\n"
+ " vendor ucb;\n"
+ " arch spike;\n"
+ "};\n"
+ "rtc {\n"
+ " addr 0x" << rtc_addr << ";\n"
+ "};\n"
+ "ram {\n"
+ " 0 {\n"
+ " addr 0x" << DRAM_BASE << ";\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"
+ " timecmp 0x" << (rtc_addr + 8*(1+i)) << ";\n"
+ " ipi 0x" << cpu_addr << ";\n"
+ " };\n"
+ " };\n";
+ bus.add_device(cpu_addr, procs[i]);
+ cpu_addr += cpu_size;
+ }
+ s << "};\n";
+
+ config_string = s.str();
+ rom.insert(rom.end(), config_string.begin(), config_string.end());
+ rom.resize((rom.size() / align + 1) * align);
+
+ boot_rom.reset(new rom_device_t(rom));
+ bus.add_device(DEFAULT_RSTVEC, boot_rom.get());