From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: "Philippe Mathieu-Daudé" <philmd@linaro.org>
Cc: "Thomas Huth" <thuth@redhat.com>,
"Peter Maydell" <peter.maydell@linaro.org>,
"Richard Henderson" <richard.henderson@linaro.org>,
"Hervé Poussineau" <hpoussin@reactos.org>,
"Fabrice Bellard" <fabrice@bellard.org>,
"Michael Tokarev" <mjt@tls.msk.ru>,
"Michael S. Tsirkin" <mst@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Daniel P. Berrangé" <berrange@redhat.com>,
"Mark Cave-Ayland" <mark.cave-ayland@ilande.co.uk>,
"Bin Meng" <bmeng.cn@gmail.com>,
"Bernhard Beschow" <shentey@gmail.com>,
"Gerd Hoffmann" <kraxel@redhat.com>,
"BALATON Zoltan" <balaton@eik.bme.hu>,
"QEMU Developers" <qemu-devel@nongnu.org>
Subject: Re: Thoughts on removing the TARGET_I386 part of hw/display/vga/vbe_portio_list[]
Date: Tue, 6 Dec 2022 12:30:40 +0000 [thread overview]
Message-ID: <Y4818KfGO7Y9Tsn/@work-vm> (raw)
In-Reply-To: <fb95bd97-8d5f-b0eb-008b-47a96808a74f@linaro.org>
* Philippe Mathieu-Daudé (philmd@linaro.org) wrote:
> Hi,
>
> I'm trying to understand the x86 architecture-specific code in
> hw/display/vga.c:
>
> const MemoryRegionPortio vbe_portio_list[] = {
> { 0, 1, 2, .read = vbe_ioport_read_index,
> .write = vbe_ioport_write_index },
> # ifdef TARGET_I386
> { 1, 1, 2, .read = vbe_ioport_read_data,
> .write = vbe_ioport_write_data },
> # endif
> { 2, 1, 2, .read = vbe_ioport_read_data,
> .write = vbe_ioport_write_data },
> PORTIO_END_OF_LIST(),
> };
>
> Having:
>
> typedef struct MemoryRegionPortio {
> uint32_t offset;
> uint32_t len;
> unsigned size;
> uint32_t (*read)(...);
> void (*write)(...);
> ...
> } MemoryRegionPortio;
>
> So on x86 we can have 16-bit I/O accesses unaligned to 8-bit boundary?
Yes, like most things in x86 the requirement for alignment is a 'should'
followed by a description of what might happen if you don't:
From intel arch manual 19.3:
'..16-bit ports should be aligned to even addresses (0, 2, 4, ...) so that all 16 bits can be transferred in a
single bus cycle. Likewise, 32-bit ports should be aligned to addresses that are multiples of four (0, 4, 8, ...). The
processor supports data transfers to unaligned ports, but there is a performance penalty because one or more
extra bus cycle must be used.'
I think I've even seen it suggested that a 32bit access to ffff might be
defined - although I'm not sure if that's legal.
I don't know that bit of qemu well enough to know whether the cpu part
of qemu should be splitting the unaligned accesses or not.
Dave
> Looking at git-blame we have:
>
> [1] 0a039dc700 ("vga: Convert to isa_register_portio_list")
> [2] 09a79b4974 ("partial big endian fixes - change VESA VBE ports for non
> i386 targets to avoid unaligned accesses")
> [3] 4fa0f5d292 ("added bochs VBE support")
>
>
> [3] added:
>
> #ifdef CONFIG_BOCHS_VBE
> s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
> register_ioport_read(0x1ce, 1, vbe_ioport_read, 2);
> register_ioport_read(0x1cf, 1, vbe_ioport_read, 2);
>
> register_ioport_write(0x1ce, 1, vbe_ioport_write, 2);
> register_ioport_write(0x1cf, 1, vbe_ioport_write, 2);
> #endif
>
> Back then, register_ioport_read() was:
>
> /* size is the word size in byte */
> int register_ioport_read(int start, int length,
> IOPortReadFunc *func, int size)
> {
> int i, bsize;
>
> if (size == 1)
> bsize = 0;
> else if (size == 2)
> bsize = 1;
> else if (size == 4)
> bsize = 2;
> else
> return -1;
> for(i = start; i < start + length; i += size)
> ioport_read_table[bsize][i] = func;
> return 0;
> }
>
> Indeed registering a 16-bit handler at the 8-bit aligned 0x1cf I/O address.
>
> I wonder if this wasn't a typo, and we wanted to register two 8-bit
> VBE handlers at offsets +0 and +1. IOW the code would have been:
>
> #ifdef CONFIG_BOCHS_VBE
> s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0;
> register_ioport_read(0x1ce, 1, vbe_ioport_read, 2);
> register_ioport_read(0x1ce, 2, vbe_ioport_read, 1);
>
> register_ioport_write(0x1ce, 1, vbe_ioport_write, 2);
> register_ioport_write(0x1ce, 2, vbe_ioport_write, 1);
> #endif
>
> Because in that case, along with the code added in commit [2]:
>
> static uint32_t vga_mem_readw(target_phys_addr_t addr)
> {
> uint32_t v;
> +#ifdef TARGET_WORDS_BIGENDIAN
> + v = vga_mem_readb(addr) << 8;
> + v |= vga_mem_readb(addr + 1);
> +#else
> v = vga_mem_readb(addr);
> v |= vga_mem_readb(addr + 1) << 8;
> +#endif
> return v;
> }
>
> The 'ifdef TARGET_I386' (still from [2], converted in [1])
> wouldn't have been necessary.
>
> So I _think_ today we should be good with removing the x86 line:
>
> -- >8 --
> static const MemoryRegionPortio vbe_portio_list[] = {
> { 0, 1, 2, .read = vbe_ioport_read_index, .write =
> vbe_ioport_write_index },
> -# ifdef TARGET_I386
> - { 1, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data
> },
> -# endif
> { 2, 1, 2, .read = vbe_ioport_read_data, .write = vbe_ioport_write_data
> },
> PORTIO_END_OF_LIST(),
> };
> ---
>
> *Except* if there is some hidden magic logic on the ISA bus...
> Not per the ISA spec, but manufacturer/hardware specific.
>
> I.e. the Jazz machines use a RC4030 which bridge ISA to the main
> bus, and transparently handles misaligned CPU/DMA accesses to the
> ISA address space.
>
> This ISA topic was already mentioned before, see:
>
> [a]
> https://lore.kernel.org/qemu-devel/20200720185758.21280-1-f4bug@amsat.org/
> [b]
> https://lore.kernel.org/qemu-devel/20210305235414.2358144-1-f4bug@amsat.org/
>
> Thoughts?
>
> Thanks,
>
> Phil.
>
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
next prev parent reply other threads:[~2022-12-06 12:31 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-12-06 11:56 Thoughts on removing the TARGET_I386 part of hw/display/vga/vbe_portio_list[] Philippe Mathieu-Daudé
2022-12-06 12:30 ` Dr. David Alan Gilbert [this message]
2022-12-06 15:56 ` Philippe Mathieu-Daudé
2022-12-06 16:02 ` Peter Maydell
2022-12-06 16:23 ` Richard Henderson
2022-12-07 14:59 ` Mark Cave-Ayland
2022-12-06 17:31 ` Warner Losh
2022-12-06 14:38 ` Gerd Hoffmann
2022-12-06 16:09 ` Philippe Mathieu-Daudé
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Y4818KfGO7Y9Tsn/@work-vm \
--to=dgilbert@redhat.com \
--cc=balaton@eik.bme.hu \
--cc=berrange@redhat.com \
--cc=bmeng.cn@gmail.com \
--cc=fabrice@bellard.org \
--cc=hpoussin@reactos.org \
--cc=kraxel@redhat.com \
--cc=mark.cave-ayland@ilande.co.uk \
--cc=mjt@tls.msk.ru \
--cc=mst@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=richard.henderson@linaro.org \
--cc=shentey@gmail.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.