Skip to content

Commit

Permalink
Fix mbus diags
Browse files Browse the repository at this point in the history
  • Loading branch information
Spritetm committed Jun 24, 2024
1 parent 3ab042e commit 5bf7809
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 62 deletions.
24 changes: 16 additions & 8 deletions csr.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ int csr_try_mbus_held(csr_t *csr) {
return 1;
}

void csr_set_access_error(csr_t *csr, int cpu, int type) {
void csr_set_access_error(csr_t *csr, int cpu, int type, int addr, int is_write) {
int v=0;
if (cpu==0) {
if (type&ACCESS_ERROR_U) v|=ERR_UBE_DMA;
Expand All @@ -138,10 +138,18 @@ 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;
if (type&ACCESS_ERROR_MBTO) {
v|=ERR_MBTO;
if (emu_get_mb_diag()) {
emu_raise_int(INT_VECT_MB_IF_ERR, INT_LEVEL_MB_IF_ERR, 1);
csr->reg[CSR_I_MBERR/2]=(addr>>11)&0xfe;
if (!is_write) csr->reg[CSR_I_MBERR/2]|=0x1;
}
}
csr->reg[CSR_I_ERR/2]|=v;
}


void csr_set_parity_error(csr_t *c, int hl) {
c->reg[CSR_I_PERR1/2]&=~((1<<12)|(1<<13));
if (hl&2) c->reg[CSR_I_PERR1/2]|=(1<<12);
Expand All @@ -165,6 +173,8 @@ void csr_write16(void *obj, unsigned int a, unsigned int val) {
emu_enable_mapper(!(val&MISC_ENMAP));
if ((val&MISC_HOLDMBUS)==0) {
val&=~MISC_TBUSY;
} else {
val|=MISC_TBUSY;
}
int v=0;
if ((val&MISC_SCSIDL)==0) v|=SCSI_DIAG_LATCH;
Expand All @@ -177,6 +187,7 @@ void csr_write16(void *obj, unsigned int a, unsigned int val) {
v=0;
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
Expand Down Expand Up @@ -299,12 +310,9 @@ void csr_write16_mmio(void *obj, unsigned int a, unsigned int val) {
}
}

void csr_raise_error(csr_t *c, int error, unsigned int addr) {
if (error==CSR_ERR_MBUS) {
emu_raise_int(INT_VECT_MB_IF_ERR, INT_LEVEL_MB_IF_ERR, 1);
c->reg[CSR_I_MBERR/2]=(addr>>11)&0xfe;
if (addr&EMU_MBUS_ERROR_READ) c->reg[CSR_I_MBERR/2]|=0x1;
}
unsigned int csr_read16_mmio(void *obj, unsigned int a) {
csr_write16_mmio(obj, a, 0);
return 0;
}


Expand Down
7 changes: 2 additions & 5 deletions csr.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,18 @@ void csr_write8(void *obj, unsigned int a, unsigned int val);
void csr_write16(void *obj, unsigned int a, unsigned int val);
void csr_write32(void *obj, unsigned int a, unsigned int val);
void csr_write16_mmio(void *obj, unsigned int a, unsigned int val);
unsigned int csr_read16_mmio(void *obj, unsigned int a);
csr_t *csr_new(scsi_t *scsi);

int csr_cpu_is_reset(csr_t *csr, int cpu);
int csr_get_rtc_int_ena(csr_t *csr, int cpu);
int csr_try_mbus_held(csr_t *csr);


#define CSR_ERR_MBUS 1
void csr_raise_error(csr_t *c, int error, unsigned int addr);

#define ACCESS_ERROR_OK 0
#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);
void csr_set_access_error(csr_t *csr, int cpu, int type, int addr, int is_write);


void csr_set_parity_error(csr_t *c, int hl);
27 changes: 11 additions & 16 deletions emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ static int check_can_access(mem_range_t *m, unsigned int address) {
ret=0;
}
if (!ret) {
csr_set_access_error(csr, cur_cpu, ACCESS_ERROR_A);
csr_set_access_error(csr, cur_cpu, ACCESS_ERROR_A, address, 0);
m68k_pulse_bus_error();
}
return ret;
Expand Down Expand Up @@ -307,17 +307,17 @@ void emu_set_cur_mapid(uint8_t id) {
//thing to actually throw the error.

static int check_mem_access(unsigned int address, int flags) {
static int recursive_error=0;
if (!mapper_enabled) return 1;
if ((fc_bits&3)==2) flags=ACCESS_X;
if (fc_bits&4) flags|=ACCESS_SYSTEM;
int access=mapper_access_allowed(mapper, address, flags);
if (access!=ACCESS_ERROR_OK) {
EMU_LOG_DEBUG("Bus error! Access %x\n", address);
// if (address==0x1000) do_tracefile=1;
dump_cpu_state();
dump_callstack();
csr_set_access_error(csr, cur_cpu, access);
if (log_level_active(LOG_SRC_MAPPER, LOG_DEBUG)) {
EMU_LOG_INFO("Illegal access! Access %x\n", address);
dump_cpu_state();
dump_callstack();
}
csr_set_access_error(csr, cur_cpu, access, address, flags&ACCESS_W);

//note THIS WILL NOT RETURN!
//(m68ki_exception_bus_error ends with a longjmp)
Expand Down Expand Up @@ -455,13 +455,9 @@ int emu_write_byte(int addr, int val) {
}

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

Expand Down Expand Up @@ -537,6 +533,7 @@ csr_t *setup_csr(const char *name, const char *mmio_name, const char *scsi_name)
m->read16=csr_read16;
m->read8=csr_read8;
mm->write16=csr_write16_mmio;
mm->read16=csr_read16_mmio;
return r;
}

Expand Down Expand Up @@ -604,9 +601,7 @@ void setup_mbus(const char *name, const char *ioname) {

//1 if held
int emu_try_mbus_held() {
mem_range_t *r=find_range_by_name("CSR");
csr_t *c=(csr_t*)r->obj;
return csr_try_mbus_held(c);
return csr_try_mbus_held(csr);
}

void setup_nop(const char *name) {
Expand Down
2 changes: 1 addition & 1 deletion emu.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,5 @@ void emu_start(emu_cfg_t *cfg);
void emu_schedule_int_us(int us);

#define EMU_MBUS_ERROR_READ 0x80000000
#define EMU_MBUS_ERROR_TIMEOUT 0x40000000
#define EMU_MBUS_BUSERROR 0x40000000
void emu_mbus_error(unsigned int addr);
4 changes: 4 additions & 0 deletions log.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ void log_set_level(enum log_source source, enum log_level msg_level) {
log_channel_verbose_level[source]=msg_level;
}

int log_level_active(enum log_source source, enum log_level msg_level) {
return log_channel_verbose_level[source] >= msg_level;
}

int log_printf(enum log_source source, enum log_level msg_level, const char *format, ...) {
static_assert(sizeof(log_channel_verbose_level)/sizeof(log_channel_verbose_level[0])==LOG_SRC_MAX,
"log_channel_verbose_level missing an entry");
Expand Down
1 change: 1 addition & 0 deletions log.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ enum log_level {

void log_set_level(enum log_source source, enum log_level msg_level);
int log_printf(enum log_source source, enum log_level msg_level, const char *format, ...);
int log_level_active(enum log_source source, enum log_level msg_level);

#endif
2 changes: 1 addition & 1 deletion mapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ int mapper_access_allowed(mapper_t *m, unsigned int a, int access_flags) {
assert(p<=2048 && "out of range addr");
if (access_flags&ACCESS_SYSTEM) p+=2048;
int r=access_allowed_page(m, p, access_flags);
if (r) {
if (r && log_level_active(LOG_SRC_MAPPER, LOG_DEBUG)) {
MAPPER_LOG_DEBUG("Mapper: Access fault at addr %x page %d. CPU state:\n", a, p);
dump_cpu_state();
dump_callstack();
Expand Down
41 changes: 11 additions & 30 deletions mbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,54 +21,37 @@ but they obvs can't do that for 8-bit writes/reads. So 16-bit writes go through
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");
return 1;
}

static int on_wrong_cpu(int addr) {
int r=emu_get_cur_cpu();
if (r==1) return 0;
MBUS_LOG_NOTICE("Mbus access to %x from wrong CPU\n", addr);
emu_bus_error();
return 1;
}



void mbus_write8(void *obj, unsigned int a, unsigned int val) {
if (on_wrong_cpu(a)) return;
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);
if (r==-1) 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: 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);
r+=emu_write_byte((a+0x780001), val);
if (r<0) emu_mbus_error(a);
}

void mbus_write32(void *obj, unsigned int a, unsigned int val) {
Expand All @@ -77,21 +60,18 @@ 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;
MBUS_LOG_DEBUG("MBUS: rb %x->%x\n", a, a+0x780000);
if (!emu_get_mb_diag()) return 0;
//Mbus in diag modes errors with a MBTO.
emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
emu_mbus_error(a|EMU_MBUS_BUSERROR);
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 (!emu_get_mb_diag()){
return 0;
}
if (!emu_get_mb_diag()) return 0;
//Mbus in diag modes errors with a MBTO.
emu_mbus_error(a|EMU_MBUS_ERROR_TIMEOUT);
emu_mbus_error(a|EMU_MBUS_BUSERROR);
return 0;
}

Expand All @@ -101,13 +81,14 @@ unsigned int mbus_read32(void *obj, unsigned int a) {

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);
MBUS_LOG_DEBUG("mbio wr %x\n", a);
emu_mbus_error(a|EMU_MBUS_BUSERROR);
}

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);
MBUS_LOG_DEBUG("mbio rd %x\n", a);
emu_mbus_error(a|EMU_MBUS_ERROR_READ|EMU_MBUS_BUSERROR);
return 0;
}

Expand Down
3 changes: 2 additions & 1 deletion rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ void rtc_write8(void *obj, unsigned int a, unsigned int val) {
}
handle_irq(r);
if (a!=CALREGC && a!=CALREGD) r->reg[a]=val;
rtc_sanitize_vals(r);
//Sanitize values if clock is running
if (!(r->reg[CALREGB]&0x80)) rtc_sanitize_vals(r);
}

void rtc_write16(void *obj, unsigned int a, unsigned int val) {
Expand Down

0 comments on commit 5bf7809

Please sign in to comment.