* [PATCH] hw/i386/acpi-build: Return a pre-computed _PRT table
@ 2024-04-17 13:53 Ricardo Ribalda
2024-05-03 9:09 ` Ricardo Ribalda
0 siblings, 1 reply; 3+ messages in thread
From: Ricardo Ribalda @ 2024-04-17 13:53 UTC (permalink / raw)
To: Michael S. Tsirkin, Igor Mammedov, Ani Sinha, Marcel Apfelbaum,
Paolo Bonzini, Richard Henderson, Eduardo Habkost, qemu-devel
Cc: Ricardo Ribalda
When qemu runs without kvm acceleration the ACPI executions take a great
amount of time. If they take more than the default time (30sec), the
ACPI calls fail and the system might not behave correctly.
Now the _PRT table is computed on the fly. We can drastically reduce the
execution of the _PRT method if we return a pre-computed table.
Without this patch:
[ 51.343484] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
[ 51.527032] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
[ 51.530049] virtio-pci 0000:00:02.0: can't derive routing for PCI INT A
[ 51.530797] virtio-pci 0000:00:02.0: PCI INT A: no GSI
[ 81.922901] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
[ 82.103534] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
[ 82.106088] virtio-pci 0000:00:04.0: can't derive routing for PCI INT A
[ 82.106761] virtio-pci 0000:00:04.0: PCI INT A: no GSI
[ 112.192568] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
[ 112.486687] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
[ 112.489554] virtio-pci 0000:00:05.0: can't derive routing for PCI INT A
[ 112.490027] virtio-pci 0000:00:05.0: PCI INT A: no GSI
[ 142.559448] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
[ 142.718596] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
[ 142.722889] virtio-pci 0000:00:06.0: can't derive routing for PCI INT A
[ 142.724578] virtio-pci 0000:00:06.0: PCI INT A: no GSI
With this patch:
[ 22.938076] ACPI: \_SB_.LNKB: Enabled at IRQ 10
[ 24.214002] ACPI: \_SB_.LNKD: Enabled at IRQ 11
[ 25.465170] ACPI: \_SB_.LNKA: Enabled at IRQ 10
[ 27.944920] ACPI: \_SB_.LNKC: Enabled at IRQ 11
ACPI disassembly:
Scope (PCI0)
{
Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
{
Return (Package (0x80)
{
Package (0x04)
{
0xFFFF,
Zero,
LNKD,
Zero
},
Package (0x04)
{
0xFFFF,
One,
LNKA,
Zero
},
Package (0x04)
{
0xFFFF,
0x02,
LNKB,
Zero
},
Package (0x04)
{
0xFFFF,
0x03,
LNKC,
Zero
},
Package (0x04)
{
0x0001FFFF,
Zero,
LNKS,
Zero
},
Context: https://lore.kernel.org/virtualization/20240417145544.38d7b482@imammedo.users.ipa.redhat.com/T/#t
Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
---
hw/i386/acpi-build.c | 118 ++++++++-----------------------------------
1 file changed, 21 insertions(+), 97 deletions(-)
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 53f804ac16..4c14d39173 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -725,40 +725,7 @@ static Aml *aml_pci_pdsm(void)
return method;
}
-/**
- * build_prt_entry:
- * @link_name: link name for PCI route entry
- *
- * build AML package containing a PCI route entry for @link_name
- */
-static Aml *build_prt_entry(const char *link_name)
-{
- Aml *a_zero = aml_int(0);
- Aml *pkg = aml_package(4);
- aml_append(pkg, a_zero);
- aml_append(pkg, a_zero);
- aml_append(pkg, aml_name("%s", link_name));
- aml_append(pkg, a_zero);
- return pkg;
-}
-
-/*
- * initialize_route - Initialize the interrupt routing rule
- * through a specific LINK:
- * if (lnk_idx == idx)
- * route using link 'link_name'
- */
-static Aml *initialize_route(Aml *route, const char *link_name,
- Aml *lnk_idx, int idx)
-{
- Aml *if_ctx = aml_if(aml_equal(lnk_idx, aml_int(idx)));
- Aml *pkg = build_prt_entry(link_name);
-
- aml_append(if_ctx, aml_store(pkg, route));
-
- return if_ctx;
-}
-
+#define N_ROUTES 128
/*
* build_prt - Define interrupt rounting rules
*
@@ -771,74 +738,31 @@ static Aml *initialize_route(Aml *route, const char *link_name,
*/
static Aml *build_prt(bool is_pci0_prt)
{
- Aml *method, *while_ctx, *pin, *res;
+ Aml *rt_pkg, *method;
+ const char link_name[][2] = {"D", "A", "B", "C"};
+ int i;
method = aml_method("_PRT", 0, AML_NOTSERIALIZED);
- res = aml_local(0);
- pin = aml_local(1);
- aml_append(method, aml_store(aml_package(128), res));
- aml_append(method, aml_store(aml_int(0), pin));
+ rt_pkg = aml_varpackage(N_ROUTES);
- /* while (pin < 128) */
- while_ctx = aml_while(aml_lless(pin, aml_int(128)));
- {
- Aml *slot = aml_local(2);
- Aml *lnk_idx = aml_local(3);
- Aml *route = aml_local(4);
-
- /* slot = pin >> 2 */
- aml_append(while_ctx,
- aml_store(aml_shiftright(pin, aml_int(2), NULL), slot));
- /* lnk_idx = (slot + pin) & 3 */
- aml_append(while_ctx,
- aml_store(aml_and(aml_add(pin, slot, NULL), aml_int(3), NULL),
- lnk_idx));
-
- /* route[2] = "LNK[D|A|B|C]", selection based on pin % 3 */
- aml_append(while_ctx, initialize_route(route, "LNKD", lnk_idx, 0));
- if (is_pci0_prt) {
- Aml *if_device_1, *if_pin_4, *else_pin_4;
-
- /* device 1 is the power-management device, needs SCI */
- if_device_1 = aml_if(aml_equal(lnk_idx, aml_int(1)));
- {
- if_pin_4 = aml_if(aml_equal(pin, aml_int(4)));
- {
- aml_append(if_pin_4,
- aml_store(build_prt_entry("LNKS"), route));
- }
- aml_append(if_device_1, if_pin_4);
- else_pin_4 = aml_else();
- {
- aml_append(else_pin_4,
- aml_store(build_prt_entry("LNKA"), route));
- }
- aml_append(if_device_1, else_pin_4);
- }
- aml_append(while_ctx, if_device_1);
- } else {
- aml_append(while_ctx, initialize_route(route, "LNKA", lnk_idx, 1));
+ for (i = 0; i < N_ROUTES; i++) {
+ Aml *pkg = aml_package(4);
+ const char *name;
+
+ name = link_name[((i >> 2) + i) & 3];
+
+ if (is_pci0_prt && i == 4) {
+ name = "S";
}
- aml_append(while_ctx, initialize_route(route, "LNKB", lnk_idx, 2));
- aml_append(while_ctx, initialize_route(route, "LNKC", lnk_idx, 3));
-
- /* route[0] = 0x[slot]FFFF */
- aml_append(while_ctx,
- aml_store(aml_or(aml_shiftleft(slot, aml_int(16)), aml_int(0xFFFF),
- NULL),
- aml_index(route, aml_int(0))));
- /* route[1] = pin & 3 */
- aml_append(while_ctx,
- aml_store(aml_and(pin, aml_int(3), NULL),
- aml_index(route, aml_int(1))));
- /* res[pin] = route */
- aml_append(while_ctx, aml_store(route, aml_index(res, pin)));
- /* pin++ */
- aml_append(while_ctx, aml_increment(pin));
+
+ aml_append(pkg, aml_int((i << 14) | 0xFFFF));
+ aml_append(pkg, aml_int(i & 3));
+ aml_append(pkg, aml_name("LNK%s", name));
+ aml_append(pkg, aml_int(0));
+ aml_append(rt_pkg, pkg);
}
- aml_append(method, while_ctx);
- /* return res*/
- aml_append(method, aml_return(res));
+
+ aml_append(method, aml_return(rt_pkg));
return method;
}
--
2.44.0.683.g7961c838ac-goog
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] hw/i386/acpi-build: Return a pre-computed _PRT table
2024-04-17 13:53 [PATCH] hw/i386/acpi-build: Return a pre-computed _PRT table Ricardo Ribalda
@ 2024-05-03 9:09 ` Ricardo Ribalda
2024-05-30 13:50 ` Igor Mammedov
0 siblings, 1 reply; 3+ messages in thread
From: Ricardo Ribalda @ 2024-05-03 9:09 UTC (permalink / raw)
To: Michael S. Tsirkin, Igor Mammedov, Ani Sinha, Marcel Apfelbaum,
Paolo Bonzini, Richard Henderson, Eduardo Habkost, qemu-devel,
Andrea Righi
Friendly ping
On Wed, 17 Apr 2024 at 15:56, Ricardo Ribalda <ribalda@chromium.org> wrote:
>
> When qemu runs without kvm acceleration the ACPI executions take a great
> amount of time. If they take more than the default time (30sec), the
> ACPI calls fail and the system might not behave correctly.
>
> Now the _PRT table is computed on the fly. We can drastically reduce the
> execution of the _PRT method if we return a pre-computed table.
>
> Without this patch:
> [ 51.343484] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> [ 51.527032] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> [ 51.530049] virtio-pci 0000:00:02.0: can't derive routing for PCI INT A
> [ 51.530797] virtio-pci 0000:00:02.0: PCI INT A: no GSI
> [ 81.922901] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> [ 82.103534] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> [ 82.106088] virtio-pci 0000:00:04.0: can't derive routing for PCI INT A
> [ 82.106761] virtio-pci 0000:00:04.0: PCI INT A: no GSI
> [ 112.192568] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> [ 112.486687] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> [ 112.489554] virtio-pci 0000:00:05.0: can't derive routing for PCI INT A
> [ 112.490027] virtio-pci 0000:00:05.0: PCI INT A: no GSI
> [ 142.559448] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> [ 142.718596] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> [ 142.722889] virtio-pci 0000:00:06.0: can't derive routing for PCI INT A
> [ 142.724578] virtio-pci 0000:00:06.0: PCI INT A: no GSI
>
> With this patch:
> [ 22.938076] ACPI: \_SB_.LNKB: Enabled at IRQ 10
> [ 24.214002] ACPI: \_SB_.LNKD: Enabled at IRQ 11
> [ 25.465170] ACPI: \_SB_.LNKA: Enabled at IRQ 10
> [ 27.944920] ACPI: \_SB_.LNKC: Enabled at IRQ 11
>
> ACPI disassembly:
> Scope (PCI0)
> {
> Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
> {
> Return (Package (0x80)
> {
> Package (0x04)
> {
> 0xFFFF,
> Zero,
> LNKD,
> Zero
> },
>
> Package (0x04)
> {
> 0xFFFF,
> One,
> LNKA,
> Zero
> },
>
> Package (0x04)
> {
> 0xFFFF,
> 0x02,
> LNKB,
> Zero
> },
>
> Package (0x04)
> {
> 0xFFFF,
> 0x03,
> LNKC,
> Zero
> },
>
> Package (0x04)
> {
> 0x0001FFFF,
> Zero,
> LNKS,
> Zero
> },
> Context: https://lore.kernel.org/virtualization/20240417145544.38d7b482@imammedo.users.ipa.redhat.com/T/#t
>
> Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> ---
> hw/i386/acpi-build.c | 118 ++++++++-----------------------------------
> 1 file changed, 21 insertions(+), 97 deletions(-)
>
> diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> index 53f804ac16..4c14d39173 100644
> --- a/hw/i386/acpi-build.c
> +++ b/hw/i386/acpi-build.c
> @@ -725,40 +725,7 @@ static Aml *aml_pci_pdsm(void)
> return method;
> }
>
> -/**
> - * build_prt_entry:
> - * @link_name: link name for PCI route entry
> - *
> - * build AML package containing a PCI route entry for @link_name
> - */
> -static Aml *build_prt_entry(const char *link_name)
> -{
> - Aml *a_zero = aml_int(0);
> - Aml *pkg = aml_package(4);
> - aml_append(pkg, a_zero);
> - aml_append(pkg, a_zero);
> - aml_append(pkg, aml_name("%s", link_name));
> - aml_append(pkg, a_zero);
> - return pkg;
> -}
> -
> -/*
> - * initialize_route - Initialize the interrupt routing rule
> - * through a specific LINK:
> - * if (lnk_idx == idx)
> - * route using link 'link_name'
> - */
> -static Aml *initialize_route(Aml *route, const char *link_name,
> - Aml *lnk_idx, int idx)
> -{
> - Aml *if_ctx = aml_if(aml_equal(lnk_idx, aml_int(idx)));
> - Aml *pkg = build_prt_entry(link_name);
> -
> - aml_append(if_ctx, aml_store(pkg, route));
> -
> - return if_ctx;
> -}
> -
> +#define N_ROUTES 128
> /*
> * build_prt - Define interrupt rounting rules
> *
> @@ -771,74 +738,31 @@ static Aml *initialize_route(Aml *route, const char *link_name,
> */
> static Aml *build_prt(bool is_pci0_prt)
> {
> - Aml *method, *while_ctx, *pin, *res;
> + Aml *rt_pkg, *method;
> + const char link_name[][2] = {"D", "A", "B", "C"};
> + int i;
>
> method = aml_method("_PRT", 0, AML_NOTSERIALIZED);
> - res = aml_local(0);
> - pin = aml_local(1);
> - aml_append(method, aml_store(aml_package(128), res));
> - aml_append(method, aml_store(aml_int(0), pin));
> + rt_pkg = aml_varpackage(N_ROUTES);
>
> - /* while (pin < 128) */
> - while_ctx = aml_while(aml_lless(pin, aml_int(128)));
> - {
> - Aml *slot = aml_local(2);
> - Aml *lnk_idx = aml_local(3);
> - Aml *route = aml_local(4);
> -
> - /* slot = pin >> 2 */
> - aml_append(while_ctx,
> - aml_store(aml_shiftright(pin, aml_int(2), NULL), slot));
> - /* lnk_idx = (slot + pin) & 3 */
> - aml_append(while_ctx,
> - aml_store(aml_and(aml_add(pin, slot, NULL), aml_int(3), NULL),
> - lnk_idx));
> -
> - /* route[2] = "LNK[D|A|B|C]", selection based on pin % 3 */
> - aml_append(while_ctx, initialize_route(route, "LNKD", lnk_idx, 0));
> - if (is_pci0_prt) {
> - Aml *if_device_1, *if_pin_4, *else_pin_4;
> -
> - /* device 1 is the power-management device, needs SCI */
> - if_device_1 = aml_if(aml_equal(lnk_idx, aml_int(1)));
> - {
> - if_pin_4 = aml_if(aml_equal(pin, aml_int(4)));
> - {
> - aml_append(if_pin_4,
> - aml_store(build_prt_entry("LNKS"), route));
> - }
> - aml_append(if_device_1, if_pin_4);
> - else_pin_4 = aml_else();
> - {
> - aml_append(else_pin_4,
> - aml_store(build_prt_entry("LNKA"), route));
> - }
> - aml_append(if_device_1, else_pin_4);
> - }
> - aml_append(while_ctx, if_device_1);
> - } else {
> - aml_append(while_ctx, initialize_route(route, "LNKA", lnk_idx, 1));
> + for (i = 0; i < N_ROUTES; i++) {
> + Aml *pkg = aml_package(4);
> + const char *name;
> +
> + name = link_name[((i >> 2) + i) & 3];
> +
> + if (is_pci0_prt && i == 4) {
> + name = "S";
> }
> - aml_append(while_ctx, initialize_route(route, "LNKB", lnk_idx, 2));
> - aml_append(while_ctx, initialize_route(route, "LNKC", lnk_idx, 3));
> -
> - /* route[0] = 0x[slot]FFFF */
> - aml_append(while_ctx,
> - aml_store(aml_or(aml_shiftleft(slot, aml_int(16)), aml_int(0xFFFF),
> - NULL),
> - aml_index(route, aml_int(0))));
> - /* route[1] = pin & 3 */
> - aml_append(while_ctx,
> - aml_store(aml_and(pin, aml_int(3), NULL),
> - aml_index(route, aml_int(1))));
> - /* res[pin] = route */
> - aml_append(while_ctx, aml_store(route, aml_index(res, pin)));
> - /* pin++ */
> - aml_append(while_ctx, aml_increment(pin));
> +
> + aml_append(pkg, aml_int((i << 14) | 0xFFFF));
> + aml_append(pkg, aml_int(i & 3));
> + aml_append(pkg, aml_name("LNK%s", name));
> + aml_append(pkg, aml_int(0));
> + aml_append(rt_pkg, pkg);
> }
> - aml_append(method, while_ctx);
> - /* return res*/
> - aml_append(method, aml_return(res));
> +
> + aml_append(method, aml_return(rt_pkg));
>
> return method;
> }
> --
> 2.44.0.683.g7961c838ac-goog
>
--
Ricardo Ribalda
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] hw/i386/acpi-build: Return a pre-computed _PRT table
2024-05-03 9:09 ` Ricardo Ribalda
@ 2024-05-30 13:50 ` Igor Mammedov
0 siblings, 0 replies; 3+ messages in thread
From: Igor Mammedov @ 2024-05-30 13:50 UTC (permalink / raw)
To: Ricardo Ribalda
Cc: Michael S. Tsirkin, Ani Sinha, Marcel Apfelbaum, Paolo Bonzini,
Richard Henderson, Eduardo Habkost, qemu-devel, Andrea Righi
On Fri, 3 May 2024 11:09:47 +0200
Ricardo Ribalda <ribalda@chromium.org> wrote:
> Friendly ping
>
> On Wed, 17 Apr 2024 at 15:56, Ricardo Ribalda <ribalda@chromium.org> wrote:
> >
> > When qemu runs without kvm acceleration the ACPI executions take a great
> > amount of time. If they take more than the default time (30sec), the
> > ACPI calls fail and the system might not behave correctly.
> >
> > Now the _PRT table is computed on the fly. We can drastically reduce the
> > execution of the _PRT method if we return a pre-computed table.
It's heavily depends on used hw or resources if it's running inside VM,
one can always find a slow enough environment where above stated limit
will not be sufficient regardless of what QEMU does.
Correct approach would be to fix guest OS timeout issue so it won't
timeout if there is a progress.
As for the patch, question is what DSDT size difference is between
static _PRT version and the current dynamic one?
(if it shrinks _PRT, I'm all for it)
Also see tests/qtest/bios-tables-test.c
In the top of process to follow when one touches ACPI tables
to avoid breaking tests.
> > Without this patch:
> > [ 51.343484] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> > [ 51.527032] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> > [ 51.530049] virtio-pci 0000:00:02.0: can't derive routing for PCI INT A
> > [ 51.530797] virtio-pci 0000:00:02.0: PCI INT A: no GSI
> > [ 81.922901] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> > [ 82.103534] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> > [ 82.106088] virtio-pci 0000:00:04.0: can't derive routing for PCI INT A
> > [ 82.106761] virtio-pci 0000:00:04.0: PCI INT A: no GSI
> > [ 112.192568] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> > [ 112.486687] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> > [ 112.489554] virtio-pci 0000:00:05.0: can't derive routing for PCI INT A
> > [ 112.490027] virtio-pci 0000:00:05.0: PCI INT A: no GSI
> > [ 142.559448] ACPI Error: Aborting method \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/psparse-529)
> > [ 142.718596] ACPI Error: Method execution failed \_SB.PCI0._PRT due to previous error (AE_AML_LOOP_TIMEOUT) (20230628/uteval-68)
> > [ 142.722889] virtio-pci 0000:00:06.0: can't derive routing for PCI INT A
> > [ 142.724578] virtio-pci 0000:00:06.0: PCI INT A: no GSI
> >
> > With this patch:
> > [ 22.938076] ACPI: \_SB_.LNKB: Enabled at IRQ 10
> > [ 24.214002] ACPI: \_SB_.LNKD: Enabled at IRQ 11
> > [ 25.465170] ACPI: \_SB_.LNKA: Enabled at IRQ 10
> > [ 27.944920] ACPI: \_SB_.LNKC: Enabled at IRQ 11
> >
> > ACPI disassembly:
> > Scope (PCI0)
> > {
> > Method (_PRT, 0, NotSerialized) // _PRT: PCI Routing Table
> > {
> > Return (Package (0x80)
> > {
> > Package (0x04)
> > {
> > 0xFFFF,
> > Zero,
> > LNKD,
> > Zero
> > },
> >
> > Package (0x04)
> > {
> > 0xFFFF,
> > One,
> > LNKA,
> > Zero
> > },
> >
> > Package (0x04)
> > {
> > 0xFFFF,
> > 0x02,
> > LNKB,
> > Zero
> > },
> >
> > Package (0x04)
> > {
> > 0xFFFF,
> > 0x03,
> > LNKC,
> > Zero
> > },
> >
> > Package (0x04)
> > {
> > 0x0001FFFF,
> > Zero,
> > LNKS,
> > Zero
> > },
> > Context: https://lore.kernel.org/virtualization/20240417145544.38d7b482@imammedo.users.ipa.redhat.com/T/#t
> >
> > Signed-off-by: Ricardo Ribalda <ribalda@chromium.org>
> > ---
> > hw/i386/acpi-build.c | 118 ++++++++-----------------------------------
> > 1 file changed, 21 insertions(+), 97 deletions(-)
> >
> > diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
> > index 53f804ac16..4c14d39173 100644
> > --- a/hw/i386/acpi-build.c
> > +++ b/hw/i386/acpi-build.c
> > @@ -725,40 +725,7 @@ static Aml *aml_pci_pdsm(void)
> > return method;
> > }
> >
> > -/**
> > - * build_prt_entry:
> > - * @link_name: link name for PCI route entry
> > - *
> > - * build AML package containing a PCI route entry for @link_name
> > - */
> > -static Aml *build_prt_entry(const char *link_name)
> > -{
> > - Aml *a_zero = aml_int(0);
> > - Aml *pkg = aml_package(4);
> > - aml_append(pkg, a_zero);
> > - aml_append(pkg, a_zero);
> > - aml_append(pkg, aml_name("%s", link_name));
> > - aml_append(pkg, a_zero);
> > - return pkg;
> > -}
> > -
> > -/*
> > - * initialize_route - Initialize the interrupt routing rule
> > - * through a specific LINK:
> > - * if (lnk_idx == idx)
> > - * route using link 'link_name'
> > - */
> > -static Aml *initialize_route(Aml *route, const char *link_name,
> > - Aml *lnk_idx, int idx)
> > -{
> > - Aml *if_ctx = aml_if(aml_equal(lnk_idx, aml_int(idx)));
> > - Aml *pkg = build_prt_entry(link_name);
> > -
> > - aml_append(if_ctx, aml_store(pkg, route));
> > -
> > - return if_ctx;
> > -}
> > -
> > +#define N_ROUTES 128
> > /*
> > * build_prt - Define interrupt rounting rules
> > *
> > @@ -771,74 +738,31 @@ static Aml *initialize_route(Aml *route, const char *link_name,
> > */
> > static Aml *build_prt(bool is_pci0_prt)
> > {
> > - Aml *method, *while_ctx, *pin, *res;
> > + Aml *rt_pkg, *method;
> > + const char link_name[][2] = {"D", "A", "B", "C"};
> > + int i;
> >
> > method = aml_method("_PRT", 0, AML_NOTSERIALIZED);
> > - res = aml_local(0);
> > - pin = aml_local(1);
> > - aml_append(method, aml_store(aml_package(128), res));
> > - aml_append(method, aml_store(aml_int(0), pin));
> > + rt_pkg = aml_varpackage(N_ROUTES);
> >
> > - /* while (pin < 128) */
> > - while_ctx = aml_while(aml_lless(pin, aml_int(128)));
> > - {
> > - Aml *slot = aml_local(2);
> > - Aml *lnk_idx = aml_local(3);
> > - Aml *route = aml_local(4);
> > -
> > - /* slot = pin >> 2 */
> > - aml_append(while_ctx,
> > - aml_store(aml_shiftright(pin, aml_int(2), NULL), slot));
> > - /* lnk_idx = (slot + pin) & 3 */
> > - aml_append(while_ctx,
> > - aml_store(aml_and(aml_add(pin, slot, NULL), aml_int(3), NULL),
> > - lnk_idx));
> > -
> > - /* route[2] = "LNK[D|A|B|C]", selection based on pin % 3 */
> > - aml_append(while_ctx, initialize_route(route, "LNKD", lnk_idx, 0));
> > - if (is_pci0_prt) {
> > - Aml *if_device_1, *if_pin_4, *else_pin_4;
> > -
> > - /* device 1 is the power-management device, needs SCI */
> > - if_device_1 = aml_if(aml_equal(lnk_idx, aml_int(1)));
> > - {
> > - if_pin_4 = aml_if(aml_equal(pin, aml_int(4)));
> > - {
> > - aml_append(if_pin_4,
> > - aml_store(build_prt_entry("LNKS"), route));
> > - }
> > - aml_append(if_device_1, if_pin_4);
> > - else_pin_4 = aml_else();
> > - {
> > - aml_append(else_pin_4,
> > - aml_store(build_prt_entry("LNKA"), route));
> > - }
> > - aml_append(if_device_1, else_pin_4);
> > - }
> > - aml_append(while_ctx, if_device_1);
> > - } else {
> > - aml_append(while_ctx, initialize_route(route, "LNKA", lnk_idx, 1));
> > + for (i = 0; i < N_ROUTES; i++) {
> > + Aml *pkg = aml_package(4);
> > + const char *name;
> > +
> > + name = link_name[((i >> 2) + i) & 3];
> > +
> > + if (is_pci0_prt && i == 4) {
> > + name = "S";
> > }
> > - aml_append(while_ctx, initialize_route(route, "LNKB", lnk_idx, 2));
> > - aml_append(while_ctx, initialize_route(route, "LNKC", lnk_idx, 3));
> > -
> > - /* route[0] = 0x[slot]FFFF */
> > - aml_append(while_ctx,
> > - aml_store(aml_or(aml_shiftleft(slot, aml_int(16)), aml_int(0xFFFF),
> > - NULL),
> > - aml_index(route, aml_int(0))));
> > - /* route[1] = pin & 3 */
> > - aml_append(while_ctx,
> > - aml_store(aml_and(pin, aml_int(3), NULL),
> > - aml_index(route, aml_int(1))));
> > - /* res[pin] = route */
> > - aml_append(while_ctx, aml_store(route, aml_index(res, pin)));
> > - /* pin++ */
> > - aml_append(while_ctx, aml_increment(pin));
> > +
> > + aml_append(pkg, aml_int((i << 14) | 0xFFFF));
> > + aml_append(pkg, aml_int(i & 3));
> > + aml_append(pkg, aml_name("LNK%s", name));
> > + aml_append(pkg, aml_int(0));
> > + aml_append(rt_pkg, pkg);
> > }
> > - aml_append(method, while_ctx);
> > - /* return res*/
> > - aml_append(method, aml_return(res));
> > +
> > + aml_append(method, aml_return(rt_pkg));
> >
> > return method;
> > }
> > --
> > 2.44.0.683.g7961c838ac-goog
> >
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-05-30 13:51 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-17 13:53 [PATCH] hw/i386/acpi-build: Return a pre-computed _PRT table Ricardo Ribalda
2024-05-03 9:09 ` Ricardo Ribalda
2024-05-30 13:50 ` Igor Mammedov
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).