Skip to content

Commit 160509a

Browse files
committed
escc: implement hard reset as described in the datasheet
The hardware reset differs from a device reset in that it only changes the contents of specific registers. Remove the code that resets all the registers to zero during hardware reset and implement the default values using the existing soft reset code with the additional changes listed in the table in the "Z85C30 Reset" section. Signed-off-by: Mark Cave-Ayland <[email protected]> Reviewed-by: Peter Maydell <[email protected]> Message-Id: <[email protected]> Signed-off-by: Mark Cave-Ayland <[email protected]>
1 parent 1f476e7 commit 160509a

File tree

1 file changed

+13
-28
lines changed

1 file changed

+13
-28
lines changed

hw/char/escc.c

Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@
118118
#define W_SYNC2 7
119119
#define W_TXBUF 8
120120
#define W_MINTR 9
121+
#define MINTR_VIS 0x01
122+
#define MINTR_NV 0x02
121123
#define MINTR_STATUSHI 0x10
122124
#define MINTR_SOFTIACK 0x20
123125
#define MINTR_RST_MASK 0xc0
@@ -347,36 +349,19 @@ static void escc_soft_reset_chn(ESCCChannelState *s)
347349

348350
static void escc_hard_reset_chn(ESCCChannelState *s)
349351
{
350-
int i;
352+
escc_soft_reset_chn(s);
351353

352-
s->reg = 0;
353-
for (i = 0; i < ESCC_SERIAL_REGS; i++) {
354-
s->rregs[i] = 0;
355-
s->wregs[i] = 0;
356-
}
357-
/* 1X divisor, 1 stop bit, no parity */
358-
s->wregs[W_TXCTRL1] = TXCTRL1_1STOP;
359-
s->wregs[W_MINTR] = MINTR_RST_ALL;
360-
/* Synch mode tx clock = TRxC */
354+
/*
355+
* Hard reset is almost identical to soft reset above, except that the
356+
* values of WR9 (W_MINTR), WR10 (W_MISC1), WR11 (W_CLOCK) and WR14
357+
* (W_MISC2) have extra bits forced to 0/1
358+
*/
359+
s->wregs[W_MINTR] &= MINTR_VIS | MINTR_NV;
360+
s->wregs[W_MINTR] |= MINTR_RST_B | MINTR_RST_A;
361+
s->wregs[W_MISC1] = 0;
361362
s->wregs[W_CLOCK] = CLOCK_TRXC;
362-
/* PLL disabled */
363-
s->wregs[W_MISC2] = MISC2_PLLDIS;
364-
/* Enable most interrupts */
365-
s->wregs[W_EXTINT] = EXTINT_DCD | EXTINT_SYNCINT | EXTINT_CTSINT |
366-
EXTINT_TXUNDRN | EXTINT_BRKINT;
367-
if (s->disabled) {
368-
s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_DCD | STATUS_SYNC |
369-
STATUS_CTS | STATUS_TXUNDRN;
370-
} else {
371-
s->rregs[R_STATUS] = STATUS_TXEMPTY | STATUS_TXUNDRN;
372-
}
373-
s->rregs[R_SPEC] = SPEC_BITS8 | SPEC_ALLSENT;
374-
375-
s->rx = s->tx = 0;
376-
s->rxint = s->txint = 0;
377-
s->rxint_under_svc = s->txint_under_svc = 0;
378-
s->e0_mode = s->led_mode = s->caps_lock_mode = s->num_lock_mode = 0;
379-
clear_queue(s);
363+
s->wregs[W_MISC2] &= MISC2_PLLCMD1 | MISC2_PLLCMD2;
364+
s->wregs[W_MISC2] |= MISC2_LCL_LOOP | MISC2_PLLCMD0;
380365
}
381366

382367
static void escc_reset(DeviceState *d)

0 commit comments

Comments
 (0)