From: "Michael S. Tsirkin" <mst@redhat.com>
To: Alex Williamson <alex.williamson@redhat.com>
Cc: seabios@seabios.org, ddutile@redhat.com, qemu-devel@nongnu.org,
gleb@redhat.com
Subject: Re: [Qemu-devel] [PATCH] seabios: acpi: Add _STA for PCI hotplug slots
Date: Sun, 4 Mar 2012 20:53:00 +0200 [thread overview]
Message-ID: <20120304185225.GB16058@redhat.com> (raw)
In-Reply-To: <20120224231735.17761.31411.stgit@bling.home>
On Fri, Feb 24, 2012 at 04:21:17PM -0700, Alex Williamson wrote:
> When a Status method is provided on a slot, the OSPM evaluates
> _STA in response to the device check notify on the slot. This
> allows some degree of a handshake between the platform and the
> OSPM that the hotplug has been acknowledged.
>
> In order to implement _STA, we need to know which slots have
> devices. A slot with device returns 0x0F, a slot without a
> device returns Zero. We get this information from Qemu using
> the 0xae08 I/O port register. This was previously the read-side
> of the register written to commit a device eject and always
> returned 0 on read. It now returns a bitmap of present slots,
> so we know that reading 0 means we have and old Qemu and
> dynamically modify our SSDT to rename the _STA methods. This
> is necessary to allow backwards compatibility.
Interesting. Isn't the UP register sufficient for _STA?
Assuming we want to implement _STA - for which
the only motivation seems the handshake hack below.
> The _STA method also writes the slot identifier to I/O port
> register 0xae00 as an acknowledgment of the hotplug request.
This part looks a bit like a hack.
_STA is not intended as an acknowledgement - it's a query for state.
ACPI spec 5.0 requires that _STA is called before _INI,
but ACPI 1.0b doesn't. Did you try some 1.0 OSPMs (e.g. XP)
to see what they do?
I also think I see how this can cause a race, see below.
>
> Signed-off-by: Alex Williamson <alex.williamson@redhat.com>
Your description of the qemu patches made me think
that all you really want is detect an OS without
OSPM. If that is the case, I would suggest adding
an _INI method at top level as a simpler and more robust
procedure.
Otherwise, how about implementing _PS0
(and probably _PS3) to manage slot power?
Maybe this what you are really after, and it
seems like a better interface than 'acknowledge'
which does not seem to make sense for real hardware.
> ---
>
> src/acpi-dsdt.dsl | 36 ++-
> src/acpi-dsdt.hex | 124 ++++++----
> src/acpi.c | 27 ++
> src/ssdt-pcihp.dsl | 3
> src/ssdt-pcihp.hex | 658 ++++++++++++++++++++++++++++++++++++++++++++--------
> 5 files changed, 686 insertions(+), 162 deletions(-)
>
> diff --git a/src/acpi-dsdt.dsl b/src/acpi-dsdt.dsl
> index 7082b65..6b87086 100644
> --- a/src/acpi-dsdt.dsl
> +++ b/src/acpi-dsdt.dsl
> @@ -119,17 +119,15 @@ DefinitionBlock (
> prt_slot3(0x001f),
> })
>
> - OperationRegion(PCST, SystemIO, 0xae00, 0x08)
> + OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
> Field (PCST, DWordAcc, NoLock, WriteAsZeros)
> {
> - PCIU, 32,
> - PCID, 32,
> - }
> -
> - OperationRegion(SEJ, SystemIO, 0xae08, 0x04)
> - Field (SEJ, DWordAcc, NoLock, WriteAsZeros)
> - {
> - B0EJ, 32,
> + // PCI Up/ACK
> + PUPA, 32,
> + // PCI Down
> + PDWN, 32,
> + // PCI Present/Eject
> + PPEJ, 32,
Note on the comment: this only affects bus0 not all of PCI.
> }
>
> Name (_CRS, ResourceTemplate ()
> @@ -462,10 +460,20 @@ DefinitionBlock (
> /* Methods called by hotplug devices */
> Method (PCEJ, 1, NotSerialized) {
> // _EJ0 method - eject callback
> - Store(ShiftLeft(1, Arg0), B0EJ)
> + Store(ShiftLeft(1, Arg0), PPEJ)
> Return (0x0)
> }
>
> + Method (PSTA, 1, NotSerialized) {
> + Store(ShiftLeft(1, Arg0), PUPA)
So this looks wrong to me.
Specifically _STA is also called at the end after _EJ0.
If the device is ejected then insterted, you
get a window where _STA is called and hardware
will think insertion was acknowledged, while in fact
ejection was acknowledged.
I also think a request for the OS to rescan the bus
will trigger _STA calls. Same race can get triggered.
> + Store(PPEJ, Local0)
> + If (And(Local0, ShiftLeft(1, Arg0))) {
> + Return(0x0F)
> + } Else {
> + Return(Zero)
> + }
> + }
> +
> /* Hotplug notification method supplied by SSDT */
> External (\_SB.PCI0.PCNT, MethodObj)
>
> @@ -473,12 +481,16 @@ DefinitionBlock (
> Method(PCNF, 0) {
> // Local0 = iterator
> Store (Zero, Local0)
> + // Local1 = slots marked "up"
> + Store (PUPA, Local1)
> + // Local2 = slots marked "down"
> + Store (PDWN, Local2)
> While (LLess(Local0, 31)) {
> Increment(Local0)
> - If (And(PCIU, ShiftLeft(1, Local0))) {
> + If (And(Local1, ShiftLeft(1, Local0))) {
> PCNT(Local0, 1)
> }
> - If (And(PCID, ShiftLeft(1, Local0))) {
> + If (And(Local2, ShiftLeft(1, Local0))) {
> PCNT(Local0, 3)
> }
> }
Nothing wrong here but should be a separate patch?
> diff --git a/src/acpi-dsdt.hex b/src/acpi-dsdt.hex
> index 5dc7bb4..6d99f53 100644
> --- a/src/acpi-dsdt.hex
> +++ b/src/acpi-dsdt.hex
> @@ -3,12 +3,12 @@ static unsigned char AmlCode[] = {
> 0x53,
> 0x44,
> 0x54,
> -0xd3,
> +0xeb,
> 0x10,
> 0x0,
...
I'd rather not see this part on list.
> diff --git a/src/acpi.c b/src/acpi.c
> index 107469f..056270b 100644
> --- a/src/acpi.c
> +++ b/src/acpi.c
> @@ -486,13 +486,14 @@ build_ssdt(void)
>
> #include "ssdt-pcihp.hex"
>
> -#define PCI_RMV_BASE 0xae0c
> +#define PCI_HOTPLUG 0xae0c
> +#define PCI_PRES_EJ 0xae08
>
> extern void link_time_assertion(void);
>
> static void* build_pcihp(void)
> {
> - u32 rmvc_pcrm;
> + u32 hotpluggable, present;
> int i;
>
> u8 *ssdt = malloc_high(sizeof ssdp_pcihp_aml);
> @@ -504,7 +505,7 @@ static void* build_pcihp(void)
> link_time_assertion();
> }
>
> - rmvc_pcrm = inl(PCI_RMV_BASE);
> + hotpluggable = inl(PCI_HOTPLUG);
> for (i = 0; i < ARRAY_SIZE(aml_ej0_name); ++i) {
> /* Slot is in byte 2 in _ADR */
> u8 slot = ssdp_pcihp_aml[aml_adr_dword[i] + 2] & 0x1F;
> @@ -514,11 +515,29 @@ static void* build_pcihp(void)
> free(ssdt);
> return NULL;
> }
> - if (!(rmvc_pcrm & (0x1 << slot))) {
> + if (!(hotpluggable & (0x1 << slot))) {
> memcpy(ssdt + aml_ej0_name[i], "EJ0_", 4);
> }
> }
>
> + /* Runtime patching of STA. If running on system that
> + * doesn't support the Present/Eject field, replace _STA
> + * with STA_ */
> + if (ARRAY_SIZE(aml_sta_name) != ARRAY_SIZE(aml_adr_dword)) {
> + link_time_assertion();
> + }
> +
> + present = inl(PCI_PRES_EJ);
> + for (i = 0; present == 0 && i < ARRAY_SIZE(aml_sta_name); ++i) {
> + /* Sanity check */
> + if (memcmp(ssdp_pcihp_aml + aml_sta_name[i], "_STA", 4)) {
> + warn_internalerror();
> + free(ssdt);
> + return NULL;
> + }
> + memcpy(ssdt + aml_sta_name[i], "STA_", 4);
> + }
> +
> return ssdt;
> }
>
> diff --git a/src/ssdt-pcihp.dsl b/src/ssdt-pcihp.dsl
> index 4b435b8..376476a 100644
> --- a/src/ssdt-pcihp.dsl
> +++ b/src/ssdt-pcihp.dsl
> @@ -10,6 +10,7 @@ DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
> /* Objects supplied by DSDT */
> External (\_SB.PCI0, DeviceObj)
> External (\_SB.PCI0.PCEJ, MethodObj)
> + External (\_SB.PCI0.PSTA, MethodObj)
>
> Scope(\_SB.PCI0) {
> /* Bulk generated PCI hotplug devices */
> @@ -23,6 +24,8 @@ DefinitionBlock ("ssdt-pcihp.aml", "SSDT", 0x01, "BXPC", "BXSSDTPCIHP", 0x1)
> Name (_ADR, 0x##slot##0000) \
> ACPI_EXTRACT_METHOD_STRING aml_ej0_name \
> Method (_EJ0, 1) { Return(PCEJ(0x##slot)) } \
> + ACPI_EXTRACT_METHOD_STRING aml_sta_name \
> + Method (_STA, 0) { Return(PSTA(0x##slot)) } \
> Name (_SUN, 0x##slot) \
> }
>
> diff --git a/src/ssdt-pcihp.hex b/src/ssdt-pcihp.hex
> index b15ad5a..f060c94 100644
> --- a/src/ssdt-pcihp.hex
> +++ b/src/ssdt-pcihp.hex
> @@ -1,80 +1,113 @@
> static unsigned short aml_adr_dword[] = {
> 0x3e,
> -0x62,
> -0x88,
> -0xae,
> -0xd4,
> -0xfa,
....
I'd rather not see this part in the patches on list.
next prev parent reply other threads:[~2012-03-04 18:52 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-24 23:21 [Qemu-devel] [PATCH] seabios: acpi: Add _STA for PCI hotplug slots Alex Williamson
2012-03-04 17:06 ` Kevin O'Connor
2012-03-04 18:53 ` Michael S. Tsirkin [this message]
2012-03-05 3:30 ` Alex Williamson
2012-03-05 5:15 ` Michael S. Tsirkin
2012-03-05 15:38 ` Alex Williamson
2012-03-05 6:26 ` Michael S. Tsirkin
2012-03-05 10:39 ` Gleb Natapov
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=20120304185225.GB16058@redhat.com \
--to=mst@redhat.com \
--cc=alex.williamson@redhat.com \
--cc=ddutile@redhat.com \
--cc=gleb@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=seabios@seabios.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.