Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Saturn dromajo #72

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
77 changes: 76 additions & 1 deletion src/dromajo_cosim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -302,12 +302,19 @@ int dromajo_cosim_step(dromajo_cosim_state_t *state,
}
}

if (r->common.pending_interrupt != -1)
if (r->common.pending_interrupt != -1) {
riscv_cpu_set_mip(s, riscv_cpu_get_mip(s) | 1 << r->common.pending_interrupt);
fprintf(dromajo_stderr, "[DEBUG] Interrupt: MIP <- %d: Now MIP = %x\n", r->common.pending_interrupt, riscv_cpu_get_mip(s));
}

if (riscv_cpu_interp64(s, 1) != 0) {
iregno = riscv_get_most_recently_written_reg(s);
fregno = riscv_get_most_recently_written_fp_reg(s);

//// ABE: I think this is the solution
//r->common.pending_interrupt = -1;
//r->common.pending_exception = -1;

break;
}

Expand Down Expand Up @@ -376,3 +383,71 @@ int dromajo_cosim_step(dromajo_cosim_state_t *state,

return exit_code;
}

/*
* dromajo_cosim_override_mem --
*
* DUT sets Dromajo memory. Used so that other devices (i.e. block device, accelerators, can write to memory).
*/
int dromajo_cosim_override_mem(dromajo_cosim_state_t *state, int hartid, uint64_t dut_paddr, uint64_t dut_val, int size_log2)
{
RISCVMachine *r = (RISCVMachine *)state;
RISCVCPUState *s = r->cpu_state[hartid];

uint8_t *ptr;
target_ulong offset;
PhysMemoryRange *pr = get_phys_mem_range(s->mem_map, dut_paddr);

if (!pr) {
#ifdef DUMP_INVALID_MEM_ACCESS
fprintf(dromajo_stderr, "riscv_cpu_write_memory: invalid physical address 0x%016" PRIx64 "\n", dut_paddr);
#endif
return 1;
} else if (pr->is_ram) {
phys_mem_set_dirty_bit(pr, dut_paddr - pr->addr);
ptr = pr->phys_mem + (uintptr_t)(dut_paddr - pr->addr);
switch (size_log2) {
case 0:
*(uint8_t *)ptr = dut_val;
break;
case 1:
*(uint16_t *)ptr = dut_val;
break;
case 2:
*(uint32_t *)ptr = dut_val;
break;
#if MLEN >= 64
case 3:
*(uint64_t *)ptr = dut_val;
break;
#endif
#if MLEN >= 128
case 4:
*(uint128_t *)ptr = dut_val;
break;
#endif
default:
abort();
}
} else {
offset = dut_paddr - pr->addr;
if (((pr->devio_flags >> size_log2) & 1) != 0) {
pr->write_func(pr->opaque, offset, dut_val, size_log2);
}
#if MLEN >= 64
else if ((pr->devio_flags & DEVIO_SIZE32) && size_log2 == 3) {
/* emulate 64 bit access */
pr->write_func(pr->opaque, offset,
dut_val & 0xffffffff, 2);
pr->write_func(pr->opaque, offset + 4,
(dut_val >> 32) & 0xffffffff, 2);
}
#endif
else {
#ifdef DUMP_INVALID_MEM_ACCESS
fprintf(dromajo_stderr, "unsupported device write access: addr=0x%016" PRIx64 " width=%d bits\n", dut_paddr, 1 << (3 + size_log2));
#endif
}
}
return 0;
}
12 changes: 12 additions & 0 deletions src/dromajo_cosim.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ int dromajo_cosim_step(dromajo_cosim_state_t *state,
void dromajo_cosim_raise_trap(dromajo_cosim_state_t *state,
int hartid,
int64_t cause);

/*
* dromajo_cosim_override_mem --
*
* DUT sets Dromajo memory. Used so that other devices (i.e. block device, accelerators, can write to memory).
*/
int dromajo_cosim_override_mem(dromajo_cosim_state_t *state,
int hartid,
uint64_t dut_paddr,
uint64_t dut_val,
int size_log2);

#ifdef __cplusplus
} // extern C
#endif
Expand Down
22 changes: 16 additions & 6 deletions src/dromajo_main.cpp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changing the semantics of M like this would break existing usage. You could make it accept both 0x-prefixed hex and decimal otherwise.

Original file line number Diff line number Diff line change
Expand Up @@ -609,11 +609,12 @@ static void usage(const char *prog, const char *msg)
" --bootrom load in a bootrom img file (default is dromajo bootrom)\n"
" --dtb load in a dtb file (default is dromajo dtb)\n"
" --compact_bootrom have dtb be directly after bootrom (default 256B after boot base)\n"
" --reset_vector set reset vector (default 0x%lx)\n"
" --reset_vector set reset vector for all cores (default 0x%lx)\n"
" --mmio_range START:END [START,END) mmio range for cosim (overridden by config file)\n"
" --plic START:SIZE set PLIC start address and size (defaults to 0x%lx:0x%lx)\n"
" --clint START:SIZE set CLINT start address and size (defaults to 0x%lx:0x%lx)\n"
" --custom_extension add X extension to isa\n",
" --plic START:SIZE set PLIC start address and size in B (defaults to 0x%lx:0x%lx)\n"
" --clint START:SIZE set CLINT start address and size in B (defaults to 0x%lx:0x%lx)\n"
" --custom_extension add X extension to misa for all cores\n"
" --clear_ids clear mvendorid, marchid, mimpid for all cores\n",
msg,
prog,
(long)BOOT_BASE_ADDR, (long)RAM_BASE_ADDR,
Expand Down Expand Up @@ -671,6 +672,7 @@ RISCVMachine *virt_machine_main(int argc, char **argv)
uint64_t clint_base_addr_override = 0;
uint64_t clint_size_override = 0;
bool custom_extension = false;
bool clear_ids = false;

dromajo_stdout = stdout;
dromajo_stderr = stderr;
Expand Down Expand Up @@ -698,6 +700,7 @@ RISCVMachine *virt_machine_main(int argc, char **argv)
{"plic", required_argument, 0, 'p' }, // CFG
{"clint", required_argument, 0, 'C' }, // CFG
{"custom_extension", no_argument, 0, 'u' }, // CFG
{"clear_ids", no_argument, 0, 'L' }, // CFG
{0, 0, 0, 0 }
};

Expand Down Expand Up @@ -751,7 +754,9 @@ RISCVMachine *virt_machine_main(int argc, char **argv)
break;

case 'M':
memory_size_override = atoi(optarg);
if (optarg[0] != '0' || optarg[1] != 'x')
usage(prog, "--memory_size expects argument to start with 0x... ");
memory_size_override = strtoll(optarg + 2, NULL, 16);
break;

case 'A':
Expand Down Expand Up @@ -837,6 +842,10 @@ RISCVMachine *virt_machine_main(int argc, char **argv)
custom_extension = true;
break;

case 'L':
clear_ids = true;
break;

default:
usage(prog, "I'm not having this argument");
}
Expand Down Expand Up @@ -1000,8 +1009,9 @@ RISCVMachine *virt_machine_main(int argc, char **argv)
if (clint_size_override)
p->clint_size = clint_size_override;

// ISA modifications
// core modifications
p->custom_extension = custom_extension;
p->clear_ids = clear_ids;

RISCVMachine *s = virt_machine_init(p);
if (!s)
Expand Down
3 changes: 3 additions & 0 deletions src/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ typedef struct {
/* Add to misa custom extensions */
bool custom_extension;

/* Clear mimpid, marchid, mvendorid */
bool clear_ids;

uint64_t physical_addr_len;

char *logfile; // If non-zero, all output goes here, stderr and stdout
Expand Down
60 changes: 53 additions & 7 deletions src/riscv_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1628,14 +1628,14 @@ static void raise_exception2(RISCVCPUState *s, uint64_t cause,
};

if (cause & CAUSE_INTERRUPT)
fprintf(dromajo_stderr, "hartid=%d: exception interrupt #%d, epc 0x%016jx\n",
fprintf(dromajo_stderr, "hartid=%d: exception interrupt #%ld, epc 0x%016jx\n",
(int)s->mhartid, cause & 63, (uintmax_t)s->pc);
else if (cause <= CAUSE_STORE_PAGE_FAULT) {
fprintf(dromajo_stderr, "hartid=%d priv: %d exception %s, epc 0x%016jx\n",
(int)s->mhartid, s->priv, cause_s[cause], (uintmax_t)s->pc);
fprintf(dromajo_stderr, "hartid=%d0 tval 0x%016jx\n", (int)s->mhartid, (uintmax_t)tval);
} else {
fprintf(dromajo_stderr, "hartid=%d: exception %d, epc 0x%016jx\n",
fprintf(dromajo_stderr, "hartid=%d: exception %ld, epc 0x%016jx\n",
(int)s->mhartid, cause, (uintmax_t)s->pc);
fprintf(dromajo_stderr, "hartid=%d: tval 0x%016jx\n", (int)s->mhartid, (uintmax_t)tval);
}
Expand Down Expand Up @@ -1739,6 +1739,12 @@ static inline uint32_t get_pending_irq_mask(RISCVCPUState *s)
{
uint32_t pending_ints, enabled_ints;

#ifdef DUMP_INTERRUPTS
fprintf(dromajo_stderr,
"get_irq_mask: mip=0x%x mie=0x%x mideleg=0x%x\n",
s->mip, s->mie, s->mideleg);
#endif

pending_ints = s->mip & s->mie;
if (pending_ints == 0)
return 0;
Expand All @@ -1762,6 +1768,39 @@ static inline uint32_t get_pending_irq_mask(RISCVCPUState *s)
return pending_ints & enabled_ints;
}

static inline int8_t get_irq_platspecific(uint32_t mask) {
uint32_t local_ints = mask & ((-1) << 12);

// get irq number from plat specific section (priority to MSB)
for (int8_t i = 31; i > 0; --i) {
if ( (local_ints >> i) & 0x1 ) {
return i;
}
}

// unknown value (expected a valid mask in the region)
return -1;
}

// matches how rocket-chip determines interrupt priorities
static inline int8_t get_irq_num(uint32_t mask) {
// check if the int. is in the plat. specific region
if (mask >= (1 << 12)) {
return get_irq_platspecific(mask);
}
else {
// get int. from the other priorities
uint8_t priorities[] = {11, 3, 7, 10, 2, 6, 9, 1, 5, 8, 0, 4};
for (uint8_t i = 0; i < 12; ++i) {
if ( (mask >> priorities[i]) & 0x1 ) {
return priorities[i];
}
}
// should match by now
return -1;
}
}

static __exception int raise_interrupt(RISCVCPUState *s)
{
uint32_t mask;
Expand All @@ -1770,7 +1809,8 @@ static __exception int raise_interrupt(RISCVCPUState *s)
mask = get_pending_irq_mask(s);
if (mask == 0)
return 0;
irq_num = ctz32(mask);

irq_num = get_irq_num(mask);
#ifdef DUMP_INTERRUPTS
fprintf(dromajo_stderr,
"raise_interrupt: irq=%d priv=%d pc=%llx hartid=%d\n",
Expand Down Expand Up @@ -1898,10 +1938,16 @@ RISCVCPUState *riscv_cpu_init(RISCVMachine *machine, int hartid)
if (machine->custom_extension)
s->misa |= MCPUID_X;

s->mvendorid = 11 * 128 + 101; // Esperanto JEDEC number 101 in bank 11 (Change for your own)
s->marchid = (1ULL << 63) | 2;
s->mimpid = 1;
s->mhartid = hartid;
if (machine->clear_ids) {
s->mvendorid = 0;
s->marchid = 0;
s->mimpid = 0;
} else {
s->mvendorid = 11 * 128 + 101; // Esperanto JEDEC number 101 in bank 11 (Change for your own)
s->marchid = (1ULL << 63) | 2;
s->mimpid = 1;
}
s->mhartid = hartid;

s->tselect = 0;
for (int i = 0; i < MAX_TRIGGERS; ++i) {
Expand Down
8 changes: 4 additions & 4 deletions src/riscv_cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@

#define DUMP_INVALID_MEM_ACCESS
#define DUMP_MMU_EXCEPTIONS
//#define DUMP_INTERRUPTS
#define DUMP_INTERRUPTS
#define DUMP_INVALID_CSR
//#define DUMP_ILLEGAL_INSTRUCTION
//#define DUMP_EXCEPTIONS
//#define DUMP_CSR
#define DUMP_ILLEGAL_INSTRUCTION
#define DUMP_EXCEPTIONS
#define DUMP_CSR
#define CONFIG_LOGFILE
#define CONFIG_SW_MANAGED_A_AND_D 1
#define CONFIG_ALLOW_MISALIGNED_ACCESS 0
Expand Down
2 changes: 2 additions & 0 deletions src/riscv_machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,8 @@ RISCVMachine *virt_machine_init(const VirtMachineParams *p)
/* add custom extension bit to misa */
s->custom_extension = p->custom_extension;

/* clear mimpid, marchid, mvendorid */
s->clear_ids = p->clear_ids;
s->plic_base_addr = p->plic_base_addr;
s->plic_size = p->plic_size;
s->clint_base_addr = p->clint_base_addr;
Expand Down
3 changes: 3 additions & 0 deletions src/riscv_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ struct RISCVMachine {
/* Append to misa custom extensions */
bool custom_extension;

/* Clear mimpid, marchid, mvendorid */
bool clear_ids;

/* Extension state, not used by Dromajo itself */
void *ext_state;
};
Expand Down