simio: integrated programmed IO interface with CPU simulator.
This commit is contained in:
parent
1cf7385364
commit
37e7216a19
71
main.c
71
main.c
|
@ -51,75 +51,6 @@
|
|||
#include "olimex.h"
|
||||
#include "rf2500.h"
|
||||
|
||||
static void io_prefix(const char *prefix, uint16_t pc,
|
||||
uint16_t addr, int is_byte)
|
||||
{
|
||||
char name[64];
|
||||
address_t offset;
|
||||
|
||||
if (!stab_nearest(stab_default, pc, name, sizeof(name), &offset)) {
|
||||
printf("%s", name);
|
||||
if (offset)
|
||||
printf("+0x%x", offset);
|
||||
} else {
|
||||
printf("0x%04x", pc);
|
||||
}
|
||||
|
||||
printf(": IO %s.%c: 0x%04x", prefix, is_byte ? 'B' : 'W', addr);
|
||||
if (!stab_nearest(stab_default, addr, name, sizeof(name), &offset)) {
|
||||
printf(" (%s", name);
|
||||
if (offset)
|
||||
printf("+0x%x", offset);
|
||||
printf(")");
|
||||
}
|
||||
}
|
||||
|
||||
static int fetch_io(void *user_data, uint16_t pc,
|
||||
uint16_t addr, int is_byte, uint16_t *data_ret)
|
||||
{
|
||||
io_prefix("READ", pc, addr, is_byte);
|
||||
|
||||
for (;;) {
|
||||
char text[128];
|
||||
int len;
|
||||
address_t data;
|
||||
|
||||
printf("? ");
|
||||
fflush(stdout);
|
||||
if (!fgets(text, sizeof(text), stdin)) {
|
||||
printf("\nAborted IO request\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = strlen(text);
|
||||
while (len && isspace(text[len - 1]))
|
||||
len--;
|
||||
text[len] = 0;
|
||||
|
||||
if (!len)
|
||||
return 0;
|
||||
|
||||
if (!expr_eval(stab_default, text, &data)) {
|
||||
if (data_ret)
|
||||
*data_ret = data;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void store_io(void *user_data, uint16_t pc,
|
||||
uint16_t addr, int is_byte, uint16_t data)
|
||||
{
|
||||
io_prefix("WRITE", pc, addr, is_byte);
|
||||
|
||||
if (is_byte)
|
||||
printf(" => 0x%02x\n", data & 0xff);
|
||||
else
|
||||
printf(" => 0x%04x\n", data);
|
||||
}
|
||||
|
||||
struct cmdline_args {
|
||||
const char *driver_name;
|
||||
const char *serial_device;
|
||||
|
@ -204,7 +135,7 @@ static device_t driver_open_olimex_iso(const struct cmdline_args *args)
|
|||
|
||||
static device_t driver_open_sim(const struct cmdline_args *args)
|
||||
{
|
||||
return sim_open(fetch_io, store_io, NULL);
|
||||
return sim_open();
|
||||
}
|
||||
|
||||
static device_t driver_open_uif(const struct cmdline_args *args)
|
||||
|
|
56
sim.c
56
sim.c
|
@ -25,6 +25,7 @@
|
|||
#include "util.h"
|
||||
#include "output.h"
|
||||
#include "sim.h"
|
||||
#include "simio_cpu.h"
|
||||
|
||||
#define MEM_SIZE 65536
|
||||
#define MEM_IO_END 0x200
|
||||
|
@ -32,10 +33,6 @@
|
|||
struct sim_device {
|
||||
struct device base;
|
||||
|
||||
sim_fetch_func_t fetch_func;
|
||||
sim_store_func_t store_func;
|
||||
void *user_data;
|
||||
|
||||
uint8_t memory[MEM_SIZE];
|
||||
uint16_t regs[DEVICE_NUM_REGS];
|
||||
|
||||
|
@ -123,14 +120,21 @@ static int fetch_operand(struct sim_device *dev,
|
|||
if (data_ret) {
|
||||
*data_ret = MEM_GETW(dev, addr) & mask;
|
||||
|
||||
if (addr < MEM_IO_END && dev->fetch_func) {
|
||||
uint16_t data16 = *data_ret;
|
||||
if (addr < MEM_IO_END) {
|
||||
int ret;
|
||||
|
||||
ret = dev->fetch_func(dev->user_data,
|
||||
dev->current_insn,
|
||||
addr, is_byte, &data16);
|
||||
*data_ret = data16;
|
||||
if (is_byte) {
|
||||
uint8_t x = *data_ret;
|
||||
|
||||
ret = simio_read_b(addr, &x);
|
||||
*data_ret = x;
|
||||
} else {
|
||||
uint16_t x = *data_ret;
|
||||
|
||||
ret = simio_read(addr, &x);
|
||||
*data_ret = x;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +142,7 @@ static int fetch_operand(struct sim_device *dev,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void store_operand(struct sim_device *dev,
|
||||
static int store_operand(struct sim_device *dev,
|
||||
int amode, int reg, int is_byte,
|
||||
uint16_t addr, uint16_t data)
|
||||
{
|
||||
|
@ -149,9 +153,14 @@ static void store_operand(struct sim_device *dev,
|
|||
|
||||
if (amode == MSP430_AMODE_REGISTER)
|
||||
dev->regs[reg] = data;
|
||||
else if (addr < MEM_IO_END && dev->store_func)
|
||||
dev->store_func(dev->user_data, dev->current_insn,
|
||||
addr, is_byte, data);
|
||||
else if (addr < MEM_IO_END) {
|
||||
if (is_byte)
|
||||
return simio_write_b(addr, data);
|
||||
|
||||
return simio_write(addr, data);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ARITH_BITS (MSP430_SR_V | MSP430_SR_N | MSP430_SR_Z | MSP430_SR_C)
|
||||
|
@ -263,9 +272,10 @@ static int step_double(struct sim_device *dev, uint16_t ins)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (opcode != MSP430_OP_CMP && opcode != MSP430_OP_BIT)
|
||||
if (opcode != MSP430_OP_CMP && opcode != MSP430_OP_BIT &&
|
||||
store_operand(dev, amode_dst, dreg, is_byte,
|
||||
dst_addr, res_data);
|
||||
dst_addr, res_data) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -350,8 +360,9 @@ static int step_single(struct sim_device *dev, uint16_t ins)
|
|||
}
|
||||
|
||||
if (opcode != MSP430_OP_PUSH && opcode != MSP430_OP_CALL &&
|
||||
opcode != MSP430_OP_RETI)
|
||||
store_operand(dev, amode, reg, is_byte, src_addr, res_data);
|
||||
opcode != MSP430_OP_RETI &&
|
||||
store_operand(dev, amode, reg, is_byte, src_addr, res_data) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -502,6 +513,7 @@ static int sim_ctl(device_t dev_base, device_ctl_t op)
|
|||
case DEVICE_CTL_RESET:
|
||||
memset(dev->regs, 0, sizeof(dev->regs));
|
||||
dev->regs[MSP430_REG_PC] = MEM_GETW(dev, 0xfffe);
|
||||
simio_reset();
|
||||
return 0;
|
||||
|
||||
case DEVICE_CTL_HALT:
|
||||
|
@ -586,9 +598,7 @@ static device_status_t sim_poll(device_t dev_base)
|
|||
return DEVICE_STATUS_RUNNING;
|
||||
}
|
||||
|
||||
device_t sim_open(sim_fetch_func_t fetch_func,
|
||||
sim_store_func_t store_func,
|
||||
void *user_data)
|
||||
device_t sim_open(void)
|
||||
{
|
||||
struct sim_device *dev = malloc(sizeof(*dev));
|
||||
|
||||
|
@ -609,10 +619,6 @@ device_t sim_open(sim_fetch_func_t fetch_func,
|
|||
dev->base.ctl = sim_ctl;
|
||||
dev->base.poll = sim_poll;
|
||||
|
||||
dev->fetch_func = fetch_func;
|
||||
dev->store_func = store_func;
|
||||
dev->user_data = user_data;
|
||||
|
||||
memset(dev->memory, 0xff, sizeof(dev->memory));
|
||||
memset(dev->regs, 0xff, sizeof(dev->regs));
|
||||
|
||||
|
|
15
sim.h
15
sim.h
|
@ -21,20 +21,7 @@
|
|||
|
||||
#include "device.h"
|
||||
|
||||
/* These function pointers should be supplied in order to allow
|
||||
* the simulator to perform IO operations. If they're left blank, IO
|
||||
* addresses just map to RAM.
|
||||
*/
|
||||
typedef int (*sim_fetch_func_t)(void *user_data,
|
||||
uint16_t pc, uint16_t addr,
|
||||
int is_byte, uint16_t *data);
|
||||
|
||||
typedef void (*sim_store_func_t)(void *user_data,
|
||||
uint16_t pc, uint16_t addr,
|
||||
int is_byte, uint16_t data);
|
||||
|
||||
/* Dummy/simulation implementation. */
|
||||
device_t sim_open(sim_fetch_func_t fetch, sim_store_func_t store,
|
||||
void *user_data);
|
||||
device_t sim_open(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue