Skip to content

Commit

Permalink
Fix remaining mbus error
Browse files Browse the repository at this point in the history
  • Loading branch information
Spritetm committed Jun 20, 2024
1 parent 87ee2c4 commit 26f22ce
Show file tree
Hide file tree
Showing 7 changed files with 115 additions and 35 deletions.
3 changes: 2 additions & 1 deletion csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ void csr_set_access_error(csr_t *csr, int cpu, int type) {
if (type&ACCESS_ERROR_U) v|=ERR_UBE_JOB;
if (type&ACCESS_ERROR_A) v|=ERR_ABE_JOB;
}
if (type&ACCESS_ERROR_MBTO) v|=ERR_MBTO;
csr->reg[CSR_I_ERR/2]|=v;
}

Expand Down Expand Up @@ -177,6 +178,7 @@ void csr_write16(void *obj, unsigned int a, unsigned int val) {
if (val&MISC_DIAGPL) v|=1;
if (val&MISC_DIAGPH) v|=2;
emu_set_force_parity_error(v);
emu_set_mb_diag(val&MISC_DIAGMB);
} else if (a==CSR_O_KILL) { //kill
CSR_LOG_DEBUG("csr write16 0x%X (kill) val 0x%X\n", a, val);
assert((val&0x40)==0); //we don't support this bit yet but sw doesn't seem to use it
Expand Down Expand Up @@ -210,7 +212,6 @@ void csr_write8(void *obj, unsigned int a, unsigned int val) {


unsigned int csr_read16(void *obj, unsigned int a) {
if (a>=2 && a<4) CSR_LOG_WARN("Read from unknown reg %x\n", a);
csr_t *c=(csr_t*)obj;
int b=scsi_get_bytecount(c->scsi);
c->reg[CSR_O_SC_C/2]=b>>16;
Expand Down
1 change: 1 addition & 0 deletions csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ void csr_raise_error(csr_t *c, int error, unsigned int addr);

#define ACCESS_ERROR_U 1
#define ACCESS_ERROR_A 2
#define ACCESS_ERROR_MBTO 3
void csr_set_access_error(csr_t *csr, int cpu, int type);


Expand Down
89 changes: 68 additions & 21 deletions emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,23 @@ int do_tracefile=0;

int insn_id=0;

int cur_cpu;
int cur_cpu=0;

unsigned int fc_bits=0;

mapper_t *mapper;
csr_t *csr;

int32_t callstack[2][8192];
int callstack_ptr[2]={0};

#define FLAG_USR_OK 1

struct mem_range_t {
const char *name;
uint32_t offset;
uint32_t size;
int flags;
void *obj;
read_cb read8;
read_cb read16;
Expand All @@ -54,8 +59,8 @@ struct mem_range_t {
};

static mem_range_t memory[]={
// {.name="RAM", .offset=0, .size=0x200000}, //only 2MiB of RAM
{.name="RAM", .offset=0, .size=0x800000}, //fully decked out with 8MiB of RAM
// {.name="RAM", .offset=0, .size=0x200000, .flags=FLAG_USR_OK}, //only 2MiB of RAM
{.name="RAM", .offset=0, .size=0x800000, .flags=FLAG_USR_OK}, //fully decked out with 8MiB of RAM
{.name="MAPRAM", .offset=0, .size=0}, //MMU-mapped RAM
{.name="U17", .offset=0x800000, .size=0x8000}, //used to be U19
{.name="U15", .offset=0x808000, .size=0x8000}, //used to be U17
Expand Down Expand Up @@ -125,6 +130,14 @@ static mem_range_t *find_range_by_addr(unsigned int addr) {
return NULL;
}


unsigned int nop_read(void *obj, unsigned int a) {
return 0;
}

void nop_write(void *obj, unsigned int a, unsigned int val) {
}

void setup_ram(const char *name) {
mem_range_t *m=find_range_by_name(name);
assert(m);
Expand All @@ -146,17 +159,33 @@ void setup_rom(const char *name, const char *filename) {
m->read8=ram_read8;
m->read16=ram_read16;
m->read32=ram_read32;
m->write8=nop_write;
m->write16=nop_write;
m->write32=nop_write;
EMU_LOG_INFO("Loaded ROM '%s' into section '%s' at addr %x\n", filename, name, m->offset);
}

static int check_can_access(mem_range_t *m, unsigned int address) {
int ret=1;
if (cur_cpu==1 && ((fc_bits&4)==0) && ((m->flags&FLAG_USR_OK)==0)) {
EMU_LOG_INFO("Faulting CPU %d for accessing non-RAM address %X in user mode (fc=%x)\n", cur_cpu, address, fc_bits);
ret=0;
}
if (!ret) {
csr_set_access_error(csr, cur_cpu, ACCESS_ERROR_A);
m68k_pulse_bus_error();
}
return ret;
}

#define PRINT_MEMREAD 0

static unsigned int read_memory_32(unsigned int address) {
if (address==0) EMU_LOG_DEBUG("read addr 0\n");
mem_range_t *m=find_range_by_addr(address);
//HACK! If this is set, diags get more verbose
if (address==0xC00644) return 1;
if (address==0xC006de) return 1;
// if (address==0xC00644) return 1;
// if (address==0xC006de) return 1;
if (!m) {
EMU_LOG_INFO("Read32 from unmapped addr %08X\n", address);
dump_cpu_state();
Expand All @@ -170,6 +199,7 @@ static unsigned int read_memory_32(unsigned int address) {
#if PRINT_MEMREAD
EMU_LOG_INFO("read32 %s %x -> %x\n", m->name, address, m->read32(m->obj, address - m->offset));
#endif
if (!check_can_access(m, address)) return 0;
return m->read32(m->obj, address - m->offset);
}

Expand All @@ -188,6 +218,7 @@ static unsigned int read_memory_16(unsigned int address) {
#if PRINT_MEMREAD
EMU_LOG_INFO("read16 %s %x -> %x\n", m->name, address, m->read16(m->obj, address - m->offset));
#endif
if (!check_can_access(m, address)) return 0;
return m->read16(m->obj, address - m->offset);
}

Expand All @@ -206,6 +237,7 @@ static unsigned int read_memory_8(unsigned int address) {
#if PRINT_MEMREAD
EMU_LOG_INFO("read8 %s %x -> %x\n", m->name, address, m->read8(m->obj, address - m->offset));
#endif
if (!check_can_access(m, address)) return 0;
return m->read8(m->obj, address - m->offset);
}

Expand All @@ -221,6 +253,7 @@ static void write_memory_8(unsigned int address, unsigned int value) {
EMU_LOG_INFO("No write8 implementation for %s, addr 0x%08X, data 0x%X\n", m->name, address, value);
return;
}
if (!check_can_access(m, address)) return;
m->write8(m->obj, address - m->offset, value);
}

Expand All @@ -237,6 +270,7 @@ static void write_memory_16(unsigned int address, unsigned int value) {
dump_cpu_state();
return;
}
if (!check_can_access(m, address)) return;
m->write16(m->obj, address - m->offset, value);
}

Expand All @@ -253,11 +287,10 @@ static void write_memory_32(unsigned int address, unsigned int value) {
dump_cpu_state();
return;
}
if (!check_can_access(m, address)) return;
m->write32(m->obj, address - m->offset, value);
}

unsigned int fc_bits=0;

void emu_set_cur_mapid(uint8_t id) {
mapper_set_mapid(mapper, id);
}
Expand Down Expand Up @@ -404,16 +437,32 @@ int emu_read_byte(int addr) {
}

int emu_write_byte(int addr, int val) {
int access_flags=ACCESS_R|ACCESS_SYSTEM;
int access_flags=ACCESS_W|ACCESS_SYSTEM;
if (!mapper_access_allowed(mapper, addr, access_flags)) return 0;
write_memory_8(addr, val);
return -1;
}

void emu_mbus_error(unsigned int addr) {
mem_range_t *r=find_range_by_name("CSR");
csr_t *c=(csr_t*)r->obj;
csr_raise_error(c, CSR_ERR_MBUS, addr);
if (addr&EMU_MBUS_ERROR_TIMEOUT) {
csr_set_access_error(csr, 1, ACCESS_ERROR_MBTO);
emu_bus_error();
} else {
csr_t *c=(csr_t*)r->obj;
csr_raise_error(c, CSR_ERR_MBUS, addr);
}
}

int mbus_diag_en=0;

void emu_set_mb_diag(int ena) {
if (mbus_diag_en!=ena) EMU_LOG_DEBUG("MB DIAG %d\n", ena);
mbus_diag_en=ena;
}

int emu_get_mb_diag() {
return mbus_diag_en;
}

uart_t *setup_uart(const char *name, int is_console) {
Expand All @@ -425,13 +474,6 @@ uart_t *setup_uart(const char *name, int is_console) {
return u;
}

unsigned int nop_read(void *obj, unsigned int a) {
return 0;
}

void nop_write(void *obj, unsigned int a, unsigned int val) {
}

void setup_scsi(const char *name) {
mem_range_t *m=find_range_by_name(name);
m->obj=scsi_new();
Expand Down Expand Up @@ -510,16 +552,22 @@ void emu_enable_mapper(int do_enable) {
}
}

//Note this does not work as mbus accesses go through the mapper.
void setup_mbus(const char *name) {
void setup_mbus(const char *name, const char *ioname) {
mem_range_t *m=find_range_by_name(name);
mem_range_t *io=find_range_by_name(ioname);
//note mbus needs no obj
m->read8=mbus_read8;
m->read16=mbus_read16;
m->read32=mbus_read32;
m->write8=mbus_write8;
m->write16=mbus_write16;
m->write32=mbus_write32;
io->read8=mbus_io_read;
io->read16=mbus_io_read;
io->read32=mbus_io_read;
io->write8=mbus_io_write;
io->write16=mbus_io_write;
io->write32=mbus_io_write;
}


Expand Down Expand Up @@ -651,8 +699,7 @@ void emu_start(emu_cfg_t *cfg) {
setup_scsi("SCSIBUF");
csr=setup_csr("CSR", "MMIO_WR", "SCSIBUF");
mapper=setup_mapper("MAPPER", "MAPRAM", "RAM");
setup_nop("MBUSIO");
setup_mbus("MBUSMEM");
setup_mbus("MBUSMEM", "MBUSIO");
rtc_t *rtc=setup_rtc("RTC");

void *cpuctx[2];
Expand Down
3 changes: 3 additions & 0 deletions emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ void emu_bus_error();
void emu_set_cur_mapid(uint8_t mapid);
void emu_set_force_a23(int val);
void emu_set_force_parity_error(int val);
void emu_set_mb_diag(int ena);
int emu_get_mb_diag();

typedef struct {
const char *u15_rom;
Expand All @@ -28,4 +30,5 @@ typedef struct {
void emu_start(emu_cfg_t *cfg);

#define EMU_MBUS_ERROR_READ 0x80000000
#define EMU_MBUS_ERROR_TIMEOUT 0x40000000
void emu_mbus_error(unsigned int addr);
1 change: 0 additions & 1 deletion mapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ static int access_allowed_page(mapper_t *m, unsigned int page, int access_flags)
assert(page<4096);
unsigned int ac=(m->desc[page].w1<<16)+m->desc[page].w0;
int fault=(ac&access_flags)&(ACCESS_R|ACCESS_W|ACCESS_X);
//todo: also check uid properly
int uid=(ac>>W0_UID_SHIFT)&W0_UID_MASK;
if (uid != m->cur_id) fault=(uid<<8|0xff);
if (fault) MAPPER_LOG_DEBUG("Mapper: Access fault at page %d, page addr %x, fault %x (page ent %x req %x)\n", page, (page&2047)<<12, fault, ac, access_flags);
Expand Down
51 changes: 39 additions & 12 deletions mbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ transparently, but a write/read to 8-bit address x happens to x^1 :X
*/




static int mbus_held() {
if (!emu_try_mbus_held()) return 0;
MBUS_LOG_DEBUG("Blocking op: bus held\n");
Expand All @@ -36,24 +38,34 @@ static int on_wrong_cpu(int addr) {
return 1;
}



void mbus_write8(void *obj, unsigned int a, unsigned int val) {
if (on_wrong_cpu(a)) return;
MBUS_LOG_DEBUG("MBUS: w %x->%x %x\n", a, a+0x780000, val);
MBUS_LOG_DEBUG("MBUS: wb %x->%x %x\n", a, a+0x780000, val);
if (mbus_held()) {
MBUS_LOG_NOTICE("MBUS: ^^ write held.\n");
return;
}
if (!emu_get_mb_diag()){
// emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
return;
}
int r=emu_write_byte((a+0x780000)^1, val);
if (!r) emu_mbus_error(a);
}

void mbus_write16(void *obj, unsigned int a, unsigned int val) {
if (on_wrong_cpu(a)) return;
MBUS_LOG_DEBUG("MBUS: w %x->%x %x\n", a, a+0x780000, val);
MBUS_LOG_DEBUG("MBUS: ww %x->%x %x\n", a, a+0x780000, val);
if (mbus_held()) {
MBUS_LOG_NOTICE("MBUS: ^^ write held.\n");
return;
}
if (!emu_get_mb_diag()){
// emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
return;
}
int r=emu_write_byte((a+0x780000), val>>8);
r&=emu_write_byte((a+0x780001), val);
if (!r) emu_mbus_error(a);
Expand All @@ -66,24 +78,26 @@ void mbus_write32(void *obj, unsigned int a, unsigned int val) {

unsigned int mbus_read8(void *obj, unsigned int a) {
if (on_wrong_cpu(a)) return 0;
if (mbus_held()) {
MBUS_LOG_DEBUG("MBUS: Held read 0x%X\n", a);
return 0;
}
int r=emu_read_byte((a+0x780000)^1);
if (r==-1) {
emu_mbus_error(a|EMU_MBUS_ERROR_READ);
r=0;
}
return r;
MBUS_LOG_DEBUG("MBUS: rb %x->%x\n", a, a+0x780000);

//This sounds silly, but the mbus probably doesn't support reading bytes. The
//only place in the diags that does that, expects a bus error afterwards.

emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
return 0;
}

unsigned int mbus_read16(void *obj, unsigned int a) {
if (on_wrong_cpu(a)) return 0;
MBUS_LOG_DEBUG("MBUS: rw %x->%x\n", a, a+0x780000);
if (mbus_held()) {
MBUS_LOG_DEBUG("MBUS: Held read 0x%X\n", a);
return 0;
}
if (!emu_get_mb_diag()){
// emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
return 0;
}
int r1=emu_read_byte((a+0x780000));
int r2=emu_read_byte((a+0x780001));
if (r1==-1 || r2==-1) {
Expand All @@ -98,3 +112,16 @@ unsigned int mbus_read32(void *obj, unsigned int a) {
return (mbus_read16(obj, a)<<16)|mbus_read16(obj, a+2);
}

void mbus_io_write(void *obj, unsigned int a, unsigned int val) {
if (emu_get_mb_diag()) return;
// printf("mbio wr %x\n", a);
emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
}

unsigned int mbus_io_read(void *obj, unsigned int a) {
if (emu_get_mb_diag()) return 0;
emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
return 0;
}


2 changes: 2 additions & 0 deletions mbus.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ void mbus_write32(void *obj, unsigned int a, unsigned int val);
unsigned int mbus_read8(void *obj, unsigned int a);
unsigned int mbus_read16(void *obj, unsigned int a);
unsigned int mbus_read32(void *obj, unsigned int a);
void mbus_io_write(void *obj, unsigned int a, unsigned int val);
unsigned int mbus_io_read(void *obj, unsigned int a);

0 comments on commit 26f22ce

Please sign in to comment.