From: "Michael S. Tsirkin" <mst@redhat.com>
To: khaled saleh <khaled.saleh.req@gmail.com>
Cc: qemu-devel@nongnu.org
Subject: Re: [PATCH] hw/pci/shpc: Enable 66MHz Bus Speed Support
Date: Mon, 18 May 2026 04:46:36 -0400 [thread overview]
Message-ID: <20260518044520-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20260518073714.70571-1-khaled.saleh.req@gmail.com>
On Mon, May 18, 2026 at 09:37:14AM +0200, khaled saleh wrote:
> The Standard Hot-Plug Controller (SHPC) specification (PI=1) defines
> 66MHz conventional PCI as a valid bus speed mode. While QEMU defined
> the relevant constants, it hardcoded the secondary bus speed to 33MHz
> and advertised 0 slots as 66MHz capable.
>
> This patch enables 66MHz support by:
> 1. Allowing SHPC_SEC_BUS_66 in shpc_set_sec_bus_speed().
> 2. Advertising all slots as 66MHz capable in shpc_reset().
> 3. Dynamically checking and reporting a slot's 66MHz capability based
> on the plugged PCI device's Status Register (PCI_STATUS_66MHZ).
>
> PCI-X speeds remain unsupported and will continue to trigger an
> INVALID_MODE command status error.
>
> Signed-off-by: khaled saleh <khaled.saleh.req@gmail.com>
> ---
> hw/pci/shpc.c | 29 ++++++++++++++++++++++++-----
> 1 file changed, 24 insertions(+), 5 deletions(-)
>
> diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c
> index 938602866d..3becde7f10 100644
> --- a/hw/pci/shpc.c
> +++ b/hw/pci/shpc.c
> @@ -12,7 +12,7 @@
>
> /* TODO: model power only and disabled slot states. */
> /* TODO: handle SERR and wakeups */
> -/* TODO: consider enabling 66MHz support */
> +
>
> /* TODO: remove fully only on state DISABLED and LED off.
> * track state to properly record this. */
> @@ -30,7 +30,7 @@
> #define SHPC_PHYS_BUTTON 0x8000
> #define SHPC_SEC_BUS 0x10 /* 2 bytes */
> #define SHPC_SEC_BUS_33 0x0
> -#define SHPC_SEC_BUS_66 0x1 /* Unused */
> +#define SHPC_SEC_BUS_66 0x1
> #define SHPC_SEC_BUS_MASK 0x7
> #define SHPC_MSI_CTL 0x12 /* 1 byte */
> #define SHPC_PROG_IFC 0x13 /* 1 byte */
> @@ -169,6 +169,17 @@ static void shpc_set_status(SHPCDevice *shpc,
> pci_word_test_and_set_mask(status, value << ctz32(msk));
> }
>
> +static bool shpc_device_is_66mhz_capable(SHPCDevice *shpc, int slot)
> +{
> + int pci_slot = SHPC_IDX_TO_PCI(slot);
> + PCIDevice *dev = shpc->sec_bus->devices[PCI_DEVFN(pci_slot, 0)];
> +
> + if (!dev) {
> + return false;
> + }
> + return pci_get_word(dev->config + PCI_STATUS) & PCI_STATUS_66MHZ;
> +}
> +
> static void shpc_interrupt_update(PCIDevice *d)
> {
> SHPCDevice *shpc = d->shpc;
> @@ -203,6 +214,7 @@ static void shpc_set_sec_bus_speed(SHPCDevice *shpc, uint8_t speed)
> {
> switch (speed) {
> case SHPC_SEC_BUS_33:
> + case SHPC_SEC_BUS_66:
> shpc->config[SHPC_SEC_BUS] &= ~SHPC_SEC_BUS_MASK;
> shpc->config[SHPC_SEC_BUS] |= speed;
> break;
> @@ -220,7 +232,7 @@ void shpc_reset(PCIDevice *d)
> memset(shpc->config, 0, SHPC_SIZEOF(d));
> pci_set_byte(shpc->config + SHPC_NSLOTS, nslots);
> pci_set_long(shpc->config + SHPC_SLOTS_33, nslots);
> - pci_set_long(shpc->config + SHPC_SLOTS_66, 0);
> + pci_set_long(shpc->config + SHPC_SLOTS_66, nslots);
> pci_set_byte(shpc->config + SHPC_FIRST_DEV, SHPC_IDX_TO_PCI(0));
> pci_set_word(shpc->config + SHPC_PHYS_SLOT,
> SHPC_IDX_TO_PHYSICAL(0) |
> @@ -256,7 +268,9 @@ void shpc_reset(PCIDevice *d)
> shpc_set_status(shpc, i, SHPC_LED_OFF, SHPC_SLOT_PWR_LED_MASK);
> }
> shpc_set_status(shpc, i, SHPC_LED_OFF, SHPC_SLOT_ATTN_LED_MASK);
> - shpc_set_status(shpc, i, 0, SHPC_SLOT_STATUS_66);
> + shpc_set_status(shpc, i,
> + shpc_device_is_66mhz_capable(shpc, i) ? 1 : 0,
> + SHPC_SLOT_STATUS_66);
> }
> shpc_set_sec_bus_speed(shpc, SHPC_SEC_BUS_33);
> shpc->msi_requested = 0;
> @@ -578,6 +592,9 @@ void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
> shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_MRL_OPEN);
> shpc_set_status(shpc, slot, SHPC_SLOT_STATUS_PRSNT_7_5W,
> SHPC_SLOT_STATUS_PRSNT_MASK);
> + shpc_set_status(shpc, slot,
> + shpc_device_is_66mhz_capable(shpc, slot) ? 1 : 0,
> + SHPC_SLOT_STATUS_66);
> return;
> }
>
> @@ -596,7 +613,9 @@ void shpc_device_plug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,
> shpc->config[SHPC_SLOT_EVENT_LATCH(slot)] |=
> SHPC_SLOT_EVENT_BUTTON;
> }
> - shpc_set_status(shpc, slot, 0, SHPC_SLOT_STATUS_66);
> + shpc_set_status(shpc, slot,
> + shpc_device_is_66mhz_capable(shpc, slot) ? 1 : 0,
> + SHPC_SLOT_STATUS_66);
> shpc_interrupt_update(pci_hotplug_dev);
> }
>
> --
> 2.34.1
This can't be done unconditionally without breaking cross version
migration. You need to add a property (prefixed with "x-" to mark it
not a stable ABI) and then tweak it in the compat machinery.
--
MST
prev parent reply other threads:[~2026-05-18 8:47 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-18 7:37 [PATCH] hw/pci/shpc: Enable 66MHz Bus Speed Support khaled saleh
2026-05-18 8:46 ` Michael S. Tsirkin [this message]
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=20260518044520-mutt-send-email-mst@kernel.org \
--to=mst@redhat.com \
--cc=khaled.saleh.req@gmail.com \
--cc=qemu-devel@nongnu.org \
/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.