Browse Source
This should replace the ROM hack I implemented earlier, but for now both exist together. Back to the point where gdb connects, core jumps to ROM->RAM->ROM.pull/39/head
18 changed files with 259 additions and 58 deletions
@ -0,0 +1,69 @@ |
|||||
|
#include <cassert> |
||||
|
|
||||
|
#include "debug_module.h" |
||||
|
#include "mmu.h" |
||||
|
|
||||
|
#include "debug_rom/debug_rom.h" |
||||
|
|
||||
|
debug_module_t::debug_module_t() |
||||
|
{ |
||||
|
/* Copy Debug ROM into the page. */ |
||||
|
memcpy(raw_page + DEBUG_ROM_START - DEBUG_START, |
||||
|
debug_rom_raw, debug_rom_raw_len); |
||||
|
} |
||||
|
|
||||
|
bool debug_module_t::load(reg_t addr, size_t len, uint8_t* bytes) |
||||
|
{ |
||||
|
addr = DEBUG_START + addr; |
||||
|
|
||||
|
fprintf(stderr, "ERROR: invalid load from debug module: %ld bytes at 0x%lx\n", |
||||
|
len, addr); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
bool debug_module_t::store(reg_t addr, size_t len, const uint8_t* bytes) |
||||
|
{ |
||||
|
addr = DEBUG_START + addr; |
||||
|
|
||||
|
if (addr & (len-1)) { |
||||
|
fprintf(stderr, "ERROR: unaligned store to debug module: %ld bytes at 0x%lx\n", |
||||
|
len, addr); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
if (addr >= DEBUG_RAM_START && addr + len <= DEBUG_RAM_END) { |
||||
|
memcpy(raw_page + addr - DEBUG_START, bytes, len); |
||||
|
return true; |
||||
|
} else if (len == 4 && addr == DEBUG_CLEARDEBINT) { |
||||
|
clear_interrupt(bytes[4] | (bytes[5] << 8) | |
||||
|
(bytes[6] << 16) | (bytes[7] << 24)); |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
fprintf(stderr, "ERROR: invalid store to debug module: %ld bytes at 0x%lx\n", |
||||
|
len, addr); |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
void debug_module_t::ram_write32(unsigned int index, uint32_t value) |
||||
|
{ |
||||
|
char* base = raw_page + DEBUG_RAM_START - DEBUG_START + index * 4; |
||||
|
base[0] = value & 0xff; |
||||
|
base[1] = (value >> 8) & 0xff; |
||||
|
base[2] = (value >> 16) & 0xff; |
||||
|
base[3] = (value >> 24) & 0xff; |
||||
|
} |
||||
|
|
||||
|
char* debug_module_t::page(reg_t paddr) |
||||
|
{ |
||||
|
fprintf(stderr, "dm::page(0x%lx)\n", paddr); |
||||
|
|
||||
|
assert(PGSHIFT == 12); |
||||
|
|
||||
|
if (paddr == (DEBUG_START & PGMASK)) { |
||||
|
return raw_page; |
||||
|
} |
||||
|
|
||||
|
fprintf(stderr, "ERROR: invalid page to debug module at 0x%lx\n", paddr); |
||||
|
return NULL; |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
// See LICENSE for license details.
|
||||
|
#ifndef _RISCV_DEBUG_MODULE_H |
||||
|
#define _RISCV_DEBUG_MODULE_H |
||||
|
|
||||
|
#include <set> |
||||
|
|
||||
|
#include "devices.h" |
||||
|
|
||||
|
class debug_module_t : public abstract_device_t |
||||
|
{ |
||||
|
public: |
||||
|
debug_module_t(); |
||||
|
|
||||
|
bool load(reg_t addr, size_t len, uint8_t* bytes); |
||||
|
bool store(reg_t addr, size_t len, const uint8_t* bytes); |
||||
|
char* page(reg_t paddr); |
||||
|
|
||||
|
void ram_write32(unsigned int index, uint32_t value); |
||||
|
|
||||
|
void set_interrupt(uint32_t hartid) { |
||||
|
interrupt.insert(hartid); |
||||
|
} |
||||
|
void clear_interrupt(uint32_t hartid) { |
||||
|
interrupt.erase(hartid); |
||||
|
} |
||||
|
bool get_interrupt(uint32_t hartid) const { |
||||
|
return interrupt.find(hartid) != interrupt.end(); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
// Track which interrupts from module to debugger are set.
|
||||
|
std::set<uint32_t> interrupt; |
||||
|
// TODO: use PGSIZE, which requires solving some circular include dependencies.
|
||||
|
char raw_page[4096]; |
||||
|
}; |
||||
|
|
||||
|
#endif |
||||
Loading…
Reference in new issue