qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Stefan Weil <weil@mail.berlios.de>
Cc: qemu-devel@nongnu.org
Subject: [Qemu-devel] Re: [RFC] API change for pci_set_word and related functions
Date: Mon, 11 Jan 2010 21:40:54 +0200	[thread overview]
Message-ID: <20100111194053.GA15857@redhat.com> (raw)
In-Reply-To: <4B4B7E4D.5010101@mail.berlios.de>

On Mon, Jan 11, 2010 at 08:38:53PM +0100, Stefan Weil wrote:
> Michael S. Tsirkin schrieb:
> > On Thu, Jan 07, 2010 at 04:07:26PM +0100, Stefan Weil wrote:
> >> Michael S. Tsirkin schrieb:
> >>> On Thu, Jan 07, 2010 at 12:15:25PM +0100, Stefan Weil wrote:
> >>> ...
> >>>> ---
> >>>> hw/eepro100.c | 4 +---
> >>>> 1 files changed, 1 insertions(+), 3 deletions(-)
> >>>>
> >>>> diff --git a/hw/eepro100.c b/hw/eepro100.c
> >>>> index 336ca49..a21c984 100644
> >>>> --- a/hw/eepro100.c
> >>>> +++ b/hw/eepro100.c
> >>>> @@ -420,10 +420,8 @@ static void pci_reset(EEPRO100State * s)
> >>>> /* TODO: this is the default, do not override. */
> >>>> PCI_CONFIG_16(PCI_COMMAND, 0x0000);
> >>>> /* PCI Status */
> >>>> - /* TODO: this seems to make no sense. */
> >>>> /* TODO: Value at RST# should be 0. */
> >>> So this second todo can go too. I've removed it in my tree.
> >>>
> >>>> - PCI_CONFIG_16(PCI_STATUS,
> >>>> - PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_SIG_TARGET_ABORT);
> >>>> + PCI_CONFIG_16(PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |
> >>>> PCI_STATUS_FAST_BACK);
> >>>> /* PCI Revision ID */
> >>>> PCI_CONFIG_8(PCI_REVISION_ID, 0x08);
> >>> BTW if you are not afraid of churn, there's no reason
> >>> for PCI_CONFIG_8 and friends anymore, because pci.h
> >>> has much nicer pci_set_byte etc.
> >> Hello Michael,
> >>
> >> I already noticed pci_set_byte, pci_set_word, pci_set_long and
> >> the corresponding pci_get_xxx functions and thought about using them.
> >>
> >> I did not start it because I want to suggest a different API
> >> for use in PCI device emulations:
> >>
> >> instead of
> >>
> >> pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_CAP_LIST);
> >>
> >> or
> >>
> >> pci_set_word(&pci_conf[PCI_STATUS], PCI_STATUS_CAP_LIST);
> >>
> >> it would be better to call
> >>
> >> pci_set_word(pci_conf, PCI_STATUS, PCI_STATUS_CAP_LIST);
> >>
> >>
> >> The prototypes would look like this:
> >>
> >> /* Set PCI config value. */
> >> void pci_set_word(PCIDevice *s, uint8_t offset, uint16_t val);
> >>
> >> /* Set PCI cmask value. */
> >> void pci_set_cmask_word(PCIDevice *s, uint8_t offset, uint16_t val);
> >>
> >> /* Set PCI wmask value. */
> >> void pci_set_wmask_word(PCIDevice *s, uint8_t offset, uint16_t val);
> >>
> >> What are the advantages?
> >> * strict type checking (the old API takes any uint8_t *)
> >
> > So IMO it's easier to make mistakes with your proposed API because if
> > you confuse offset and value compiler does not complain. More
> > importantly, if you want to pass some other uint8_t pointer to e.g.
> > pci_set_word, you can *and nothing unexpected will happen*
> > it will set the word to the given value. So the current
> > API is more type safe than what you propose.
> >
> 
> No. The current API takes any uint8_t pointer to read or write
> a value. This is not safe.

Why isn't it?

> The proposed API only takes a PCIDevice pointer
> and reads or writes only configuration (or cmask or
> wmask) values. Yes, you can take offset for value.
> If you are lucky and value is an uint16_t or uint32_t,
> your compiler will complain.

Such a compiler will also complain over most of qemu code.

> And even if your compiler
> does not complain, it is wrong but still safe, because
> the code will only access the PCI configuration data.
> 

Correct and safe beats wrong and safe every time.

> >> * many other pci_* functions also have a first parameter of type PCIDevice
> >
> > So what would make sense IMO is higer level abstraction,
> > for example similar to what we have with capabilities
> > and msix, I think we could have something like this
> > for e.g. power management.
> >
> > For low-level bit tweaking, the advantages of current API is that same
> > thing can be used to set wmask, cmask, config itself, and whatever else
> > we will come up with.
> 
> The low level API can be used where low level is
> adequate: in pci.c for example.
> 
> To implement emulated PCI devices, a more robust API
> would be better. Think of the number of devices which
> are still missing, think of people who want to write
> a new PCI device emulation for QEMU without being
> a QEMU expert.
> 
> >
> >> * calls look nicer (at least in my opinion)
> >
> > What I value is the fact that it's obvious which
> > data is changed.
> 
> Here there is no difference between current and
> proposed API:
> 
> old: pci_set_word(&pci_conf[PCI_STATUS], PCI_STATUS_CAP_LIST);
> new: pci_set_word(pci_conf, PCI_STATUS, PCI_STATUS_CAP_LIST);
> 
> Every function call hides what happens. If you really wanted
> to see which data is changed, you would have to write
> 
> *(uint16_t *)&pci_conf[PCI_STATUS] = cpu_to_le16(PCI_STATUS_CAP_LIST);

That's what we used to have, and it's not all bad, but very verbose and
ugly.

> >
> >> * strict range checking (offset is limited to 0...255, additional
> >>   assertions possible - the old API is unsafe because it just takes
> >>   a pointer)
> >
> > I don't think we want to add return status, so there wouldn't
> > be a benefit to range checking as we can't act on it.
> > Anyway, it's very unusual to use anything but a constant
> > as an offset, so range errors are very uncommon.
> 
> There is an implicit range checking in the proposed
> API because the offset is uint8_t, so it cannot
> exceed the range which is valid for configuration
> offsets.

Oh, btw, this is wrong on pci express.

> A more elaborated check could require that
> configuration byte values are only addressed
> using pci_set_byte (not pci_set_long)
> and raise a fatal runtime error otherwise.
> 
> Runtime checks without return values
> are well established in QEMU's code,
> and they are very useful for code writers.
> 
> >
> >> The functions are inline, so the resulting code won't differ.
> >>
> >> Instead of _byte, _word and _long I personally prefer something
> >> like _8, _16, _32 because _word and _long need interpretation.
> >> But this is only a matter of taste - the API change is more important.
> >>
> >>
> >> Regards,
> >>
> >> Stefan Weil
> 
> 

  reply	other threads:[~2010-01-11 19:44 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1260466626.git.mst@redhat.com>
2009-12-10 18:09 ` [Qemu-devel] [PATCH 01/17] e1000: switch to symbolic names for pci registers Michael S. Tsirkin
2009-12-10 18:09 ` [Qemu-devel] [PATCH 02/17] ne2000: " Michael S. Tsirkin
2009-12-10 18:09 ` [Qemu-devel] [PATCH 03/17] rtl: " Michael S. Tsirkin
2009-12-10 18:10 ` [Qemu-devel] [PATCH 04/17] pcnet: " Michael S. Tsirkin
2009-12-10 18:10 ` [Qemu-devel] [PATCH 05/17] pci: add more status bits Michael S. Tsirkin
2009-12-10 18:10 ` [Qemu-devel] [PATCH 06/17] eepro100: symbolic names for pci registers Michael S. Tsirkin
2010-01-07 11:14   ` Stefan Weil
2010-01-07 11:15     ` [Qemu-devel] [PATCH] eepro100: Fix initial value for PCI_STATUS Stefan Weil
2010-01-07 12:34       ` [Qemu-devel] " Michael S. Tsirkin
2010-01-07 15:07         ` [Qemu-devel] [RFC] API change for pci_set_word and related functions (was Re: [PATCH] eepro100: Fix initial value for PCI_STATUS) Stefan Weil
2010-01-11 18:34           ` [Qemu-devel] " Michael S. Tsirkin
2010-01-11 19:38             ` [Qemu-devel] Re: [RFC] API change for pci_set_word and related functions Stefan Weil
2010-01-11 19:40               ` Michael S. Tsirkin [this message]
2010-01-11 20:18                 ` Stefan Weil
2010-01-11 20:30                   ` Michael S. Tsirkin
2010-01-11 21:51                     ` Anthony Liguori
2010-01-11 22:10                       ` Stefan Weil
2010-01-11 23:12                         ` Anthony Liguori
2010-01-07 12:51     ` [Qemu-devel] [PATCH 06/17] eepro100: symbolic names for pci registers Michael S. Tsirkin
2010-01-07 13:41       ` Anthony Liguori
2010-01-07 13:32     ` Anthony Liguori
2010-01-07 14:26       ` Stefan Weil
2009-12-10 18:10 ` [Qemu-devel] [PATCH 07/17] piix: symbolic constants Michael S. Tsirkin
2009-12-10 18:10 ` [Qemu-devel] [PATCH 08/17] cmd646: symbolic names for pci registers Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 09/17] vmware_vga: " Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 10/17] lsi: " Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 11/17] pci: add another devsel macro Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 12/17] es1370: symbolic names for pci registers Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 13/17] wdt_i6300esb: " Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 14/17] ac97: " Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 15/17] usb-uhci: " Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 16/17] " Michael S. Tsirkin
     [not found]   ` <m3my1okxnw.fsf@neno.neno>
2009-12-12 20:34     ` [Qemu-devel] " Michael S. Tsirkin
2009-12-10 18:11 ` [Qemu-devel] [PATCH 17/17] pci: remove unused macro Michael S. Tsirkin

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=20100111194053.GA15857@redhat.com \
    --to=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=weil@mail.berlios.de \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).