qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

escc: introduce a selector for the register bit

On Sparc and PowerMac, the bit 0 of the address selects the register
type (control or data) and bit 1 selects the channel (B or A).

On m68k Macintosh and NeXTcube, the bit 0 selects the channel and
bit 1 the register type.

This patch introduces a new parameter (bit_swap) to the device interface
to indicate bits usage must be swapped between registers and channels.

For the moment all the machines use the bit 0, but this change will be
needed to emulate the Quadra 800 or NeXTcube machine.

Signed-off-by: Laurent Vivier <laurent@vivier.eu>
Reviewed-by: Hervé Poussineau <hpoussin@reactos.org>
[thh: added NeXTcube to the patch description]
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-Id: <20190831074519.32613-5-huth@tuxfamily.org>
Signed-off-by: Thomas Huth <huth@tuxfamily.org>

authored by

Laurent Vivier and committed by
Thomas Huth
b43047a2 956a7811

+25 -6
+24 -6
hw/char/escc.c
··· 45 45 * mouse and keyboard ports don't implement all functions and they are 46 46 * only asynchronous. There is no DMA. 47 47 * 48 - * Z85C30 is also used on PowerMacs. There are some small differences 49 - * between Sparc version (sunzilog) and PowerMac (pmac): 48 + * Z85C30 is also used on PowerMacs and m68k Macs. 49 + * 50 + * There are some small differences between Sparc version (sunzilog) 51 + * and PowerMac (pmac): 50 52 * Offset between control and data registers 51 53 * There is some kind of lockup bug, but we can ignore it 52 54 * CTS is inverted 53 55 * DMA on pmac using DBDMA chip 54 56 * pmac can do IRDA and faster rates, sunzilog can only do 38400 55 57 * pmac baud rate generator clock is 3.6864 MHz, sunzilog 4.9152 MHz 58 + * 59 + * Linux driver for m68k Macs is the same as for PowerMac (pmac_zilog), 60 + * but registers are grouped by type and not by channel: 61 + * channel is selected by bit 0 of the address (instead of bit 1) 62 + * and register is selected by bit 1 of the address (instead of bit 0). 56 63 */ 57 64 58 65 /* ··· 172 179 static int serial_can_receive(void *opaque); 173 180 static void serial_receive_byte(ESCCChannelState *s, int ch); 174 181 182 + static int reg_shift(ESCCState *s) 183 + { 184 + return s->bit_swap ? s->it_shift + 1 : s->it_shift; 185 + } 186 + 187 + static int chn_shift(ESCCState *s) 188 + { 189 + return s->bit_swap ? s->it_shift : s->it_shift + 1; 190 + } 191 + 175 192 static void clear_queue(void *opaque) 176 193 { 177 194 ESCCChannelState *s = opaque; ··· 436 453 int newreg, channel; 437 454 438 455 val &= 0xff; 439 - saddr = (addr >> serial->it_shift) & 1; 440 - channel = (addr >> (serial->it_shift + 1)) & 1; 456 + saddr = (addr >> reg_shift(serial)) & 1; 457 + channel = (addr >> chn_shift(serial)) & 1; 441 458 s = &serial->chn[channel]; 442 459 switch (saddr) { 443 460 case SERIAL_CTRL: ··· 547 564 uint32_t ret; 548 565 int channel; 549 566 550 - saddr = (addr >> serial->it_shift) & 1; 551 - channel = (addr >> (serial->it_shift + 1)) & 1; 567 + saddr = (addr >> reg_shift(serial)) & 1; 568 + channel = (addr >> chn_shift(serial)) & 1; 552 569 s = &serial->chn[channel]; 553 570 switch (saddr) { 554 571 case SERIAL_CTRL: ··· 832 849 static Property escc_properties[] = { 833 850 DEFINE_PROP_UINT32("frequency", ESCCState, frequency, 0), 834 851 DEFINE_PROP_UINT32("it_shift", ESCCState, it_shift, 0), 852 + DEFINE_PROP_BOOL("bit_swap", ESCCState, bit_swap, false), 835 853 DEFINE_PROP_UINT32("disabled", ESCCState, disabled, 0), 836 854 DEFINE_PROP_UINT32("chnBtype", ESCCState, chn[0].type, 0), 837 855 DEFINE_PROP_UINT32("chnAtype", ESCCState, chn[1].type, 0),
+1
include/hw/char/escc.h
··· 51 51 52 52 struct ESCCChannelState chn[2]; 53 53 uint32_t it_shift; 54 + bool bit_swap; 54 55 MemoryRegion mmio; 55 56 uint32_t disabled; 56 57 uint32_t frequency;