diff --git a/hw/char/escc.c b/hw/char/escc.c index 0fce4f6324..8755d8d34f 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -354,6 +354,17 @@ static void escc_reset(DeviceState *d) cs->rregs[j] = 0; cs->wregs[j] = 0; } + + /* + * ...but there is an exception. The "Transmit Interrupts and Transmit + * Buffer Empty Bit" section on page 50 of the ESCC datasheet says of + * the STATUS_TXEMPTY bit in R_STATUS: "After a hardware reset + * (including a hardware reset by software), or a channel reset, this + * bit is set to 1". The Sun PROM checks this bit early on startup and + * gets stuck in an infinite loop if it is not set. + */ + cs->rregs[R_STATUS] |= STATUS_TXEMPTY; + escc_reset_chn(cs); } } @@ -575,6 +586,20 @@ static void escc_mem_write(void *opaque, hwaddr addr, s->wregs[s->reg] = val; break; case W_TXCTRL1: + s->wregs[s->reg] = val; + /* + * The ESCC datasheet states that SPEC_ALLSENT is always set in + * sync mode, and set in async mode when all characters have + * cleared the transmitter. Since writes to SERIAL_DATA use the + * blocking qemu_chr_fe_write_all() function to write each + * character, the guest can never see the state when async data + * is in the process of being transmitted so we can set this bit + * unconditionally regardless of the state of the W_TXCTRL1 mode + * bits. + */ + s->rregs[R_SPEC] |= SPEC_ALLSENT; + escc_update_parameters(s); + break; case W_TXCTRL2: s->wregs[s->reg] = val; escc_update_parameters(s);