Merge remote-tracking branch 'remotes/mwalle/tags/lm32-semihosting/20140524' into staging

* remotes/mwalle/tags/lm32-semihosting/20140524:
  lm32: remove lm32_sys
  test: lm32: use semihosting for testing
  target-lm32: add semihosting support
  test: lm32: make test cases independent

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-05-27 22:11:25 +01:00
commit 2f21ff25c0
22 changed files with 366 additions and 216 deletions

View File

@ -29,7 +29,6 @@ obj-$(CONFIG_NSERIES) += cbus.o
obj-$(CONFIG_ECCMEMCTL) += eccmemctl.o
obj-$(CONFIG_EXYNOS4) += exynos4210_pmu.o
obj-$(CONFIG_IMX) += imx_ccm.o
obj-$(CONFIG_LM32) += lm32_sys.o
obj-$(CONFIG_MILKYMIST) += milkymist-hpdmc.o
obj-$(CONFIG_MILKYMIST) += milkymist-pfpu.o
obj-$(CONFIG_MAINSTONE) += mst_fpga.o

View File

@ -1,179 +0,0 @@
/*
* QEMU model of the LatticeMico32 system control block.
*
* Copyright (c) 2010 Michael Walle <michael@walle.cc>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* This model is mainly intended for testing purposes and doesn't fit to any
* real hardware. On the one hand it provides a control register (R_CTRL) on
* the other hand it supports the lm32 tests.
*
* A write to the control register causes a system shutdown.
* Tests first write the pointer to a test name to the test name register
* (R_TESTNAME) and then write a zero to the pass/fail register (R_PASSFAIL) if
* the test is passed or any non-zero value to it if the test is failed.
*/
#include "hw/hw.h"
#include "hw/sysbus.h"
#include "trace.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
#include "sysemu/sysemu.h"
enum {
R_CTRL = 0,
R_PASSFAIL,
R_TESTNAME,
R_MAX
};
#define MAX_TESTNAME_LEN 32
#define TYPE_LM32_SYS "lm32-sys"
#define LM32_SYS(obj) OBJECT_CHECK(LM32SysState, (obj), TYPE_LM32_SYS)
struct LM32SysState {
SysBusDevice parent_obj;
MemoryRegion iomem;
uint32_t base;
uint32_t regs[R_MAX];
uint8_t testname[MAX_TESTNAME_LEN];
};
typedef struct LM32SysState LM32SysState;
static void copy_testname(LM32SysState *s)
{
cpu_physical_memory_read(s->regs[R_TESTNAME], s->testname,
MAX_TESTNAME_LEN);
s->testname[MAX_TESTNAME_LEN - 1] = '\0';
}
static void sys_write(void *opaque, hwaddr addr,
uint64_t value, unsigned size)
{
LM32SysState *s = opaque;
char *testname;
trace_lm32_sys_memory_write(addr, value);
addr >>= 2;
switch (addr) {
case R_CTRL:
qemu_system_shutdown_request();
break;
case R_PASSFAIL:
s->regs[addr] = value;
testname = (char *)s->testname;
fprintf(stderr, "TC %-*s %s\n", MAX_TESTNAME_LEN,
testname, (value) ? "FAILED" : "OK");
if (value) {
cpu_dump_state(qemu_get_cpu(0), stderr, fprintf, 0);
}
break;
case R_TESTNAME:
s->regs[addr] = value;
copy_testname(s);
break;
default:
error_report("lm32_sys: write access to unknown register 0x"
TARGET_FMT_plx, addr << 2);
break;
}
}
static bool sys_ops_accepts(void *opaque, hwaddr addr,
unsigned size, bool is_write)
{
return is_write && size == 4;
}
static const MemoryRegionOps sys_ops = {
.write = sys_write,
.valid.accepts = sys_ops_accepts,
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void sys_reset(DeviceState *d)
{
LM32SysState *s = LM32_SYS(d);
int i;
for (i = 0; i < R_MAX; i++) {
s->regs[i] = 0;
}
memset(s->testname, 0, MAX_TESTNAME_LEN);
}
static int lm32_sys_init(SysBusDevice *dev)
{
LM32SysState *s = LM32_SYS(dev);
memory_region_init_io(&s->iomem, OBJECT(dev), &sys_ops , s,
"sys", R_MAX * 4);
sysbus_init_mmio(dev, &s->iomem);
/* Note: This device is not created in the board initialization,
* instead it has to be added with the -device parameter. Therefore,
* the device maps itself. */
sysbus_mmio_map(dev, 0, s->base);
return 0;
}
static const VMStateDescription vmstate_lm32_sys = {
.name = "lm32-sys",
.version_id = 1,
.minimum_version_id = 1,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(regs, LM32SysState, R_MAX),
VMSTATE_BUFFER(testname, LM32SysState),
VMSTATE_END_OF_LIST()
}
};
static Property lm32_sys_properties[] = {
DEFINE_PROP_UINT32("base", LM32SysState, base, 0xffff0000),
DEFINE_PROP_END_OF_LIST(),
};
static void lm32_sys_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = lm32_sys_init;
dc->reset = sys_reset;
dc->vmsd = &vmstate_lm32_sys;
dc->props = lm32_sys_properties;
}
static const TypeInfo lm32_sys_info = {
.name = TYPE_LM32_SYS,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(LM32SysState),
.class_init = lm32_sys_class_init,
};
static void lm32_sys_register_types(void)
{
type_register_static(&lm32_sys_info);
}
type_init(lm32_sys_register_types)

View File

@ -3071,7 +3071,8 @@ STEXI
Set OpenBIOS nvram @var{variable} to given @var{value} (PPC, SPARC only).
ETEXI
DEF("semihosting", 0, QEMU_OPTION_semihosting,
"-semihosting semihosting mode\n", QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA)
"-semihosting semihosting mode\n",
QEMU_ARCH_ARM | QEMU_ARCH_M68K | QEMU_ARCH_XTENSA | QEMU_ARCH_LM32)
STEXI
@item -semihosting
@findex -semihosting

View File

@ -1,3 +1,4 @@
obj-y += translate.o op_helper.o helper.o cpu.o
obj-y += gdbstub.o
obj-y += lm32-semi.o
obj-$(CONFIG_SOFTMMU) += machine.o

View File

@ -16,14 +16,13 @@ This will make serial0 (the lm32_uart) and serial1 (the JTAG UART)
available as virtual consoles.
Programmatically terminate the emulator
----------------------------------------
Originally neither the LatticeMico32 nor its peripherals support a
mechanism to shut down the machine. Emulation aware programs can write to a
to a special register within the system control block to shut down the
virtual machine. For more details see hw/lm32_sys.c. The lm32-evr is the
first BSP which instantiate this model. A (32 bit) write to 0xfff0000
causes a vm shutdown.
Semihosting
-----------
Semihosting on this target is supported. Some system calls like read, write
and exit are executed on the host if semihosting is enabled. See
target/lm32-semi.c for all supported system calls. Emulation aware programs
can use this mechanism to shut down the virtual machine and print to the
host console. See the tcg tests for an example.
Special instructions

View File

@ -217,6 +217,7 @@ void lm32_breakpoint_remove(CPULM32State *env, int index);
void lm32_watchpoint_insert(CPULM32State *env, int index, target_ulong address,
lm32_wp_t wp_type);
void lm32_watchpoint_remove(CPULM32State *env, int index);
bool lm32_cpu_do_semihosting(CPUState *cs);
static inline CPULM32State *cpu_init(const char *cpu_model)
{

View File

@ -1,7 +1,7 @@
/*
* LatticeMico32 helper routines.
*
* Copyright (c) 2010 Michael Walle <michael@walle.cc>
* Copyright (c) 2010-2014 Michael Walle <michael@walle.cc>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -19,6 +19,7 @@
#include "cpu.h"
#include "qemu/host-utils.h"
#include "sysemu/sysemu.h"
int lm32_cpu_handle_mmu_fault(CPUState *cs, vaddr address, int rw,
int mmu_idx)
@ -159,11 +160,20 @@ void lm32_cpu_do_interrupt(CPUState *cs)
"exception at pc=%x type=%x\n", env->pc, cs->exception_index);
switch (cs->exception_index) {
case EXCP_SYSTEMCALL:
if (unlikely(semihosting_enabled)) {
/* do_semicall() returns true if call was handled. Otherwise
* do the normal exception handling. */
if (lm32_cpu_do_semihosting(cs)) {
env->pc += 4;
break;
}
}
/* fall through */
case EXCP_INSN_BUS_ERROR:
case EXCP_DATA_BUS_ERROR:
case EXCP_DIVIDE_BY_ZERO:
case EXCP_IRQ:
case EXCP_SYSTEMCALL:
/* non-debug exceptions */
env->regs[R_EA] = env->pc;
env->ie |= (env->ie & IE_IE) ? IE_EIE : 0;

215
target-lm32/lm32-semi.c Normal file
View File

@ -0,0 +1,215 @@
/*
* Lattice Mico32 semihosting syscall interface
*
* Copyright (c) 2014 Michael Walle <michael@walle.cc>
*
* Based on target-m68k/m68k-semi.c, which is
* Copyright (c) 2005-2007 CodeSourcery.
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*/
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stddef.h>
#include "cpu.h"
#include "helper.h"
#include "qemu/log.h"
#include "exec/softmmu-semi.h"
enum {
TARGET_SYS_exit = 1,
TARGET_SYS_open = 2,
TARGET_SYS_close = 3,
TARGET_SYS_read = 4,
TARGET_SYS_write = 5,
TARGET_SYS_lseek = 6,
TARGET_SYS_fstat = 10,
TARGET_SYS_stat = 15,
};
enum {
NEWLIB_O_RDONLY = 0x0,
NEWLIB_O_WRONLY = 0x1,
NEWLIB_O_RDWR = 0x2,
NEWLIB_O_APPEND = 0x8,
NEWLIB_O_CREAT = 0x200,
NEWLIB_O_TRUNC = 0x400,
NEWLIB_O_EXCL = 0x800,
};
static int translate_openflags(int flags)
{
int hf;
if (flags & NEWLIB_O_WRONLY) {
hf = O_WRONLY;
} else if (flags & NEWLIB_O_RDWR) {
hf = O_RDWR;
} else {
hf = O_RDONLY;
}
if (flags & NEWLIB_O_APPEND) {
hf |= O_APPEND;
}
if (flags & NEWLIB_O_CREAT) {
hf |= O_CREAT;
}
if (flags & NEWLIB_O_TRUNC) {
hf |= O_TRUNC;
}
if (flags & NEWLIB_O_EXCL) {
hf |= O_EXCL;
}
return hf;
}
struct newlib_stat {
int16_t newlib_st_dev; /* device */
uint16_t newlib_st_ino; /* inode */
uint16_t newlib_st_mode; /* protection */
uint16_t newlib_st_nlink; /* number of hard links */
uint16_t newlib_st_uid; /* user ID of owner */
uint16_t newlib_st_gid; /* group ID of owner */
int16_t newlib_st_rdev; /* device type (if inode device) */
int32_t newlib_st_size; /* total size, in bytes */
int32_t newlib_st_atime; /* time of last access */
uint32_t newlib_st_spare1;
int32_t newlib_st_mtime; /* time of last modification */
uint32_t newlib_st_spare2;
int32_t newlib_st_ctime; /* time of last change */
uint32_t newlib_st_spare3;
} QEMU_PACKED;
static int translate_stat(CPULM32State *env, target_ulong addr,
struct stat *s)
{
struct newlib_stat *p;
p = lock_user(VERIFY_WRITE, addr, sizeof(struct newlib_stat), 0);
if (!p) {
return 0;
}
p->newlib_st_dev = cpu_to_be16(s->st_dev);
p->newlib_st_ino = cpu_to_be16(s->st_ino);
p->newlib_st_mode = cpu_to_be16(s->st_mode);
p->newlib_st_nlink = cpu_to_be16(s->st_nlink);
p->newlib_st_uid = cpu_to_be16(s->st_uid);
p->newlib_st_gid = cpu_to_be16(s->st_gid);
p->newlib_st_rdev = cpu_to_be16(s->st_rdev);
p->newlib_st_size = cpu_to_be32(s->st_size);
p->newlib_st_atime = cpu_to_be32(s->st_atime);
p->newlib_st_mtime = cpu_to_be32(s->st_mtime);
p->newlib_st_ctime = cpu_to_be32(s->st_ctime);
unlock_user(p, addr, sizeof(struct newlib_stat));
return 1;
}
bool lm32_cpu_do_semihosting(CPUState *cs)
{
LM32CPU *cpu = LM32_CPU(cs);
CPULM32State *env = &cpu->env;
int ret = -1;
target_ulong nr, arg0, arg1, arg2;
void *p;
struct stat s;
nr = env->regs[R_R8];
arg0 = env->regs[R_R1];
arg1 = env->regs[R_R2];
arg2 = env->regs[R_R3];
switch (nr) {
case TARGET_SYS_exit:
/* void _exit(int rc) */
exit(arg0);
case TARGET_SYS_open:
/* int open(const char *pathname, int flags) */
p = lock_user_string(arg0);
if (!p) {
ret = -1;
} else {
ret = open(p, translate_openflags(arg2));
unlock_user(p, arg0, 0);
}
break;
case TARGET_SYS_read:
/* ssize_t read(int fd, const void *buf, size_t count) */
p = lock_user(VERIFY_WRITE, arg1, arg2, 0);
if (!p) {
ret = -1;
} else {
ret = read(arg0, p, arg2);
unlock_user(p, arg1, arg2);
}
break;
case TARGET_SYS_write:
/* ssize_t write(int fd, const void *buf, size_t count) */
p = lock_user(VERIFY_READ, arg1, arg2, 1);
if (!p) {
ret = -1;
} else {
ret = write(arg0, p, arg2);
unlock_user(p, arg1, 0);
}
break;
case TARGET_SYS_close:
/* int close(int fd) */
/* don't close stdin/stdout/stderr */
if (arg0 > 2) {
ret = close(arg0);
} else {
ret = 0;
}
break;
case TARGET_SYS_lseek:
/* off_t lseek(int fd, off_t offset, int whence */
ret = lseek(arg0, arg1, arg2);
break;
case TARGET_SYS_stat:
/* int stat(const char *path, struct stat *buf) */
p = lock_user_string(arg0);
if (!p) {
ret = -1;
} else {
ret = stat(p, &s);
unlock_user(p, arg0, 0);
if (translate_stat(env, arg1, &s) == 0) {
ret = -1;
}
}
break;
case TARGET_SYS_fstat:
/* int stat(int fd, struct stat *buf) */
ret = fstat(arg0, &s);
if (ret == 0) {
if (translate_stat(env, arg1, &s) == 0) {
ret = -1;
}
}
break;
default:
/* unhandled */
return false;
}
env->regs[R_R1] = ret;
return true;
}

View File

@ -3,7 +3,7 @@
CROSS=lm32-elf-
SIM = qemu-system-lm32
SIMFLAGS = -M lm32-evr -nographic -device lm32-sys -net none -kernel
SIMFLAGS = -M lm32-evr -nographic -semihosting -net none -kernel
CC = $(CROSS)gcc
AS = $(CROSS)as
@ -18,6 +18,7 @@ LDFLAGS = -T$(TSRC_PATH)/linker.ld
ASFLAGS += -Wa,-I,$(TSRC_PATH)/
CRT = crt.o
HELPER = helper.o
TESTCASES += test_add.tst
TESTCASES += test_addi.tst
TESTCASES += test_and.tst
@ -91,15 +92,15 @@ all: build
%.o: $(TSRC_PATH)/%.S
$(AS) $(ASFLAGS) -c $< -o $@
%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT)
$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $< -o $@
%.tst: %.o $(TSRC_PATH)/macros.inc $(CRT) $(HELPER)
$(LD) $(LDFLAGS) $(NOSTDFLAGS) $(CRT) $(HELPER) $< -o $@
build: $(CRT) $(TESTCASES)
build: $(TESTCASES)
check: $(TESTCASES:test_%.tst=check_%)
check_%: test_%.tst $(CRT) $(SYS)
$(SIM) $(SIMFLAGS) $<
check_%: test_%.tst
@$(SIM) $(SIMFLAGS) $<
clean:
$(RM) -fr $(TESTCASES) $(CRT)
$(RM) -fr $(TESTCASES) $(CRT) $(HELPER)

View File

@ -8,9 +8,9 @@ _reset_handler:
ori r1, r1, lo(_start)
wcsr eba, r1
wcsr deba, r1
mvhi sp, hi(_fstack)
ori sp, sp, lo(_fstack)
bi _main
nop
nop
_breakpoint_handler:
ori r25, r25, 1

65
tests/tcg/lm32/helper.S Normal file
View File

@ -0,0 +1,65 @@
.text
.global _start, _write, _exit
.global _tc_fail, _tc_pass
_write:
addi sp, sp, -4
sw (sp+4), r8
mvi r8, 5
scall
lw r8, (sp+4)
addi sp, sp, 4
ret
_exit:
mvi r8, 1
scall
1:
bi 1b
_tc_pass:
.data
1:
.ascii "OK\n"
2:
.text
addi sp, sp, -16
sw (sp+4), ra
sw (sp+8), r1
sw (sp+12), r2
sw (sp+16), r3
mvi r1, 1
mvhi r2, hi(1b)
ori r2, r2, lo(1b)
mvi r3, (2b - 1b)
calli _write
lw r3, (sp+16)
lw r2, (sp+12)
lw r1, (sp+8)
lw ra, (sp+4)
addi sp, sp, 16
ret
_tc_fail:
.data
1:
.ascii "FAILED\n"
2:
.text
addi sp, sp, -16
sw (sp+4), ra
sw (sp+8), r1
sw (sp+12), r2
sw (sp+16), r3
sw (sp+4), ra
mvi r1, 1
mvhi r2, hi(1b)
ori r2, r2, lo(1b)
mvi r3, (2b - 1b)
calli _write
lw r3, (sp+16)
lw r2, (sp+12)
lw r1, (sp+8)
lw ra, (sp+4)
addi sp, sp, 16
ret

View File

@ -1,12 +1,26 @@
.equ MAX_TESTNAME_LEN, 32
.macro test_name name
.data
tn_\name:
.asciz "\name"
.ascii "\name"
.space MAX_TESTNAME_LEN - (. - tn_\name), ' '
.text
mvhi r13, hi(tn_\name)
ori r13, r13, lo(tn_\name)
sw (r12+8), r13
.global \name
\name:
addi sp, sp, -12
sw (sp+4), r1
sw (sp+8), r2
sw (sp+12), r3
mvi r1, 1
mvhi r2, hi(tn_\name)
ori r2, r2, lo(tn_\name)
mvi r3, MAX_TESTNAME_LEN
calli _write
lw r3, (sp+12)
lw r2, (sp+8)
lw r1, (sp+4)
addi sp, sp, 12
.endm
.macro load reg val
@ -15,13 +29,12 @@ tn_\name:
.endm
.macro tc_pass
mvi r13, 0
sw (r12+4), r13
calli _tc_pass
.endm
.macro tc_fail
mvi r13, 1
sw (r12+4), r13
addi r12, r12, 1
calli _tc_fail
.endm
.macro check_r3 val
@ -63,14 +76,12 @@ tn_\name:
.global _main
.text
_main:
mvhi r12, hi(0xffff0000) # base address of test block
ori r12, r12, lo(0xffff0000)
mvi r12, 0
.endm
.macro end
sw (r12+0), r0
1:
bi 1b
mv r1, r12
calli _exit
.endm
# base +

View File

@ -8,10 +8,12 @@ lb r3, (r1+0)
check_r3 0x7e
test_name LB_2
load r1 data
lb r3, (r1+1)
check_r3 0x7f
test_name LB_3
load r1 data
lb r3, (r1+-1)
check_r3 0x7d
@ -21,10 +23,12 @@ lb r3, (r1+0)
check_r3 0xfffffffe
test_name LB_5
load r1 data_msb
lb r3, (r1+1)
check_r3 0xffffffff
test_name LB_6
load r1 data_msb
lb r3, (r1+-1)
check_r3 0xfffffffd

View File

@ -8,10 +8,12 @@ lbu r3, (r1+0)
check_r3 0x7e
test_name LBU_2
load r1 data
lbu r3, (r1+1)
check_r3 0x7f
test_name LBU_3
load r1 data
lbu r3, (r1+-1)
check_r3 0x7d
@ -21,10 +23,12 @@ lbu r3, (r1+0)
check_r3 0xfe
test_name LBU_5
load r1 data_msb
lbu r3, (r1+1)
check_r3 0xff
test_name LBU_6
load r1 data_msb
lbu r3, (r1+-1)
check_r3 0xfd

View File

@ -8,10 +8,12 @@ lh r3, (r1+0)
check_r3 0x7e7f
test_name LH_2
load r1 data
lh r3, (r1+2)
check_r3 0x7071
test_name LH_3
load r1 data
lh r3, (r1+-2)
check_r3 0x7c7d
@ -21,10 +23,12 @@ lh r3, (r1+0)
check_r3 0xfffffeff
test_name LH_5
load r1 data_msb
lh r3, (r1+2)
check_r3 0xfffff0f1
test_name LH_6
load r1 data_msb
lh r3, (r1+-2)
check_r3 0xfffffcfd

View File

@ -8,10 +8,12 @@ lhu r3, (r1+0)
check_r3 0x7e7f
test_name LHU_2
load r1 data
lhu r3, (r1+2)
check_r3 0x7071
test_name LHU_3
load r1 data
lhu r3, (r1+-2)
check_r3 0x7c7d
@ -21,10 +23,12 @@ lhu r3, (r1+0)
check_r3 0xfeff
test_name LHU_5
load r1 data_msb
lhu r3, (r1+2)
check_r3 0xf0f1
test_name LHU_6
load r1 data_msb
lhu r3, (r1+-2)
check_r3 0xfcfd

View File

@ -8,10 +8,12 @@ lw r3, (r1+0)
check_r3 0x7e7f7071
test_name LW_2
load r1 data
lw r3, (r1+4)
check_r3 0x72737475
test_name LW_3
load r1 data
lw r3, (r1+-4)
check_r3 0x7a7b7c7d

View File

@ -9,11 +9,13 @@ sb (r1+0), r2
check_mem data 0xaa000000
test_name SB_2
load r1 data
load r2 0xf0f1f2bb
sb (r1+1), r2
check_mem data 0xaabb0000
test_name SB_3
load r1 data
load r2 0xf0f1f2cc
sb (r1+-1), r2
check_mem data0 0x000000cc

View File

@ -5,6 +5,10 @@ start
test_name SCALL_1
mvi r1, 1
wcsr IE, r1
# we are running in a semi hosted environment
# therefore we have to set r8 to some unused system
# call
mvi r8, 0
insn:
scall
check_excp 64

View File

@ -9,11 +9,13 @@ sh (r1+0), r2
check_mem data 0xaaaa0000
test_name SH_2
load r1 data
load r2 0xf0f1bbbb
sh (r1+2), r2
check_mem data 0xaaaabbbb
test_name SH_3
load r1 data
load r2 0xf0f1cccc
sh (r1+-2), r2
check_mem data0 0x0000cccc

View File

@ -9,16 +9,19 @@ sw (r1+0), r2
check_mem data 0xaabbccdd
test_name SW_2
load r1 data
load r2 0x00112233
sw (r1+4), r2
check_mem data1 0x00112233
test_name SW_3
load r1 data
load r2 0x44556677
sw (r1+-4), r2
check_mem data0 0x44556677
test_name SW_4
load r1 data
sw (r1+0), r1
lw r3, (r1+0)
check_r3 data

View File

@ -627,9 +627,6 @@ lm32_uart_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
lm32_uart_memory_read(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
lm32_uart_irq_state(int level) "irq state %d"
# hw/misc/lm32_sys.c
lm32_sys_memory_write(uint32_t addr, uint32_t value) "addr 0x%08x value 0x%08x"
# hw/scsi/megasas.c
megasas_init_firmware(uint64_t pa) "pa %" PRIx64 " "
megasas_init_queue(uint64_t queue_pa, int queue_len, uint64_t head, uint64_t tail, uint32_t flags) "queue at %" PRIx64 " len %d head %" PRIx64 " tail %" PRIx64 " flags %x"