Skip to content

Commit

Permalink
dnomem: allow register dump
Browse files Browse the repository at this point in the history
  • Loading branch information
vhotspur committed Sep 25, 2023
1 parent 47d53c9 commit 14a838f
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 8 deletions.
9 changes: 8 additions & 1 deletion doc/reference/devices.rst
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,9 @@ In ``break`` mode, the simulation is switched to interactive mode after each
access.
And in ``halt`` mode, the simulation is immediately terminated.

It is possible to dump registers of the CPU that caused the violation
automatically by setting ``rd yes``.


Initialization parameters: ``address`` ``size``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -377,6 +380,8 @@ Commands
Print the device information (block address, size and mode)
``mode``
Set device mode (either ``warn``, ``halt`` or ``break``).
``rd``
Whether to dump registers on violation (``yes`` or ``no``).


Examples
Expand All @@ -400,10 +405,12 @@ All attempts to read/write into this memory are reported.
/* <msim> Alert: Ignoring READ (at 0x008000004, 0x4 inside nomem). */
If we configure the device to ``mode`` ``halt``, the simulation is halted upon
reaching the ``lw`` instruction.
reaching the ``lw`` instruction. By using ``nomem rd yes``, registers are
dumped before the machine is halted.

.. code:: msim
[msim] nomem rd yes
[msim] nomem mode halt
[msim]
# la $a0, 0x88000004
Expand Down
55 changes: 49 additions & 6 deletions src/device/dnomem.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@
#include <string.h>
#include <inttypes.h>
#include "dnomem.h"
#include "../assert.h"
#include "../fault.h"
#include "../utils.h"
#include "cpu/general_cpu.h"

/** Access handling. */
typedef struct {
Expand All @@ -29,6 +31,8 @@ typedef struct {
ptr36_t addr;
/** No-memory size. */
uint64_t size;
/** Dump registers of CPU that caused the access. */
bool register_dump;
/** No-memory behavior on access. */
dnomem_access_mode_t *mode;
} dnomem_data_s;
Expand Down Expand Up @@ -103,6 +107,7 @@ static bool dnomem_init(token_t *parm, device_t *dev)
data->addr = start_addr;
data->size = size;
data->mode = &access_mode_warn;
data->register_dump = false;

return true;
}
Expand Down Expand Up @@ -133,6 +138,30 @@ static bool dnomem_setmode(token_t *parm, device_t *dev)
return true;
}

/** rd command implementation.
*
* @param parm Command-line parameters
* @param dev Device instance structure
*
* @return True if successful
*/
static bool dnomem_setrd(token_t *parm, device_t *dev)
{
dnomem_data_s *data = (dnomem_data_s *) dev->data;
const char *const yes_no = parm_str(parm);

if (strcmp(yes_no, "yes") == 0) {
data->register_dump = true;
} else if (strcmp(yes_no, "no") == 0) {
data->register_dump = false;
} else {
error("Unknown register dump mode %s, expecting yes or no.", yes_no);
return false;
}

return true;
}

/** Info command implementation
*
* @param parm Command-line parameters
Expand All @@ -145,9 +174,9 @@ static bool dnomem_info(token_t *parm, device_t *dev)
{
dnomem_data_s *data = (dnomem_data_s *) dev->data;

printf("[address ] [size ] [mode]\n"
"%#011" PRIx64 " %#011" PRIx64 " %s\n",
data->addr, data->size, data->mode->name);
printf("[address ] [size ] [mode ] [regdump]\n"
"%#011" PRIx64 " %#011" PRIx64 " %-8s %s\n",
data->addr, data->size, data->mode->name, data->register_dump ? "yes" : "no");

return true;
}
Expand All @@ -162,14 +191,19 @@ static void dnomem_done(device_t *dev) {
safe_free(dev->data);
}

static void dnomem_access32(const char *operation_name, device_t *dev, ptr36_t addr)
static void dnomem_access32(const char *operation_name, unsigned int procno, device_t *dev, ptr36_t addr)
{
dnomem_data_s *data = (dnomem_data_s *) dev->data;
ptr36_t offset = addr - data->addr;
if (offset >= data->size) {
return;
}

if (data->register_dump) {
general_cpu_t* causing_cpu = get_cpu(procno);
ASSERT((causing_cpu != NULL) && "CPU that causes illegal access to dnomem not found");
cpu_reg_dump(causing_cpu);
}
data->mode->access32(operation_name, dev, addr, offset);
}

Expand All @@ -183,7 +217,7 @@ static void dnomem_access32(const char *operation_name, device_t *dev, ptr36_t a
static void dnomem_read32(unsigned int procno, device_t *dev, ptr36_t addr,
uint32_t *val)
{
dnomem_access32("READ", dev, addr);
dnomem_access32("READ", procno, dev, addr);
}

/** Write command implementation
Expand All @@ -196,7 +230,7 @@ static void dnomem_read32(unsigned int procno, device_t *dev, ptr36_t addr,
static void dnomem_write32(unsigned int procno, device_t *dev, ptr36_t addr,
uint32_t val)
{
dnomem_access32("WRITE", dev, addr);
dnomem_access32("WRITE", procno, dev, addr);
}


Expand All @@ -221,6 +255,15 @@ cmd_t dnomem_cmds[] = {
"Set mode",
REQ STR "mode/Mode name (warn, break, halt)" END
},
{
"rd",
(fcmd_t) dnomem_setrd,
DEFAULT,
DEFAULT,
"Whether to dump registers on access",
"Whether to dump registers on access",
REQ STR "rd/Dump registers on access (yes, no)" END
},
{
"help",
(fcmd_t) dev_generic_help,
Expand Down
1 change: 1 addition & 0 deletions tests/system/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ MIPS32_TOOLCHAIN_DIR =
MIPS32_TESTS = \
dnomem-break \
dnomem-halt \
dnomem-rd \
dnomem-warn \
dval \
hello \
Expand Down
Binary file modified tests/system/mips32-dnomem-break/boot.bin
Binary file not shown.
Binary file modified tests/system/mips32-dnomem-halt/boot.bin
Binary file not shown.
Binary file added tests/system/mips32-dnomem-rd/boot.bin
Binary file not shown.
1 change: 1 addition & 0 deletions tests/system/mips32-dnomem-rd/guest.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
read
11 changes: 11 additions & 0 deletions tests/system/mips32-dnomem-rd/host.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
processor 0
0 0 at 0 v0 0 v1 0 a0 ffffffff90000000
a1 a a2 ffffffff88000004 a3 0 t0 0 t1 0
t2 0 t3 0 t4 0 t5 0 t6 0
t7 0 s0 0 s1 0 s2 0 s3 0
s4 0 s5 0 s6 0 s7 0 t8 0
t9 0 k0 0 k1 0 gp 0 sp 0
fp 0 ra 0 pc ffffffffbfc00038 lo 0 hi 0
<msim> Alert: Halting after forbidden READ (at 0x008000004, 0x4 inside nomem).

Cycles: 15
1 change: 1 addition & 0 deletions tests/system/mips32-dnomem-rd/main.S
8 changes: 8 additions & 0 deletions tests/system/mips32-dnomem-rd/msim.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
add dr4kcpu cpu0
add rom boot 0x1FC00000
boot generic 4K
boot load "boot.bin"
add dprinter printer 0x10000000
add dnomem nomem 0x08000000 0x1000
nomem rd yes
nomem mode halt
Binary file modified tests/system/mips32-dnomem-warn/boot.bin
Binary file not shown.
2 changes: 1 addition & 1 deletion tests/system/mips32-dnomem-warn/host.expected
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
<msim> Alert: Ignoring WRITE (at 0x008000004, 0x4 inside nomem).
<msim> Alert: XHLT: Machine halt

Cycles: 29
Cycles: 31
4 changes: 4 additions & 0 deletions tests/system/mips32.bats
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ load "common"
msim_run_code "mips32-dnomem-halt"
}

@test "MIPS32: dnomem device in halt mode with register dump" {
msim_run_code "mips32-dnomem-rd"
}

@test "MIPS32: XINT instruction" {
msim_run_code "mips32-xint"
}
Expand Down

0 comments on commit 14a838f

Please # to comment.