From: Andrei Borzenkov <arvidjaar@gmail.com>
To: The development of GNU GRUB <grub-devel@gnu.org>
Subject: Re: Loading DSDT table using 'acpi' or some memory write command?
Date: Sat, 1 Apr 2017 12:09:16 +0300 [thread overview]
Message-ID: <d042fbf2-a614-a405-815b-73c7fe37af28@gmail.com> (raw)
In-Reply-To: <1390664917.8322220.1490809510437@mail.yahoo.com>
[-- Attachment #1: Type: text/plain, Size: 1078 bytes --]
29.03.2017 20:45, Nando Eva пишет:
>> How exactly do you find RSDP? On EFI RSDP should be retrieved from EFI
>> Configuration Table, which grub tries to update. Please give as much
>> details as possible.
>
> Good point. I can get the RSDP from tools like 'ru.efi' or even with 'r-w everything'.
> However, 'lsacpi' won't tell me the new RSDP address after doing a 'acpi dsdt.aml'.
>
> Is there anyway of finding it out using the grub shell, or chainloading EFI shell (or chainload grubx64.efi from EFI shell and exiting in case grub's chainloading is restoring the ACPI tables)?
>
Please test attached patch. It adds printing of table addresses as well
as "lsacpi --scan" option that forces fetching RSDP from firmware.
It looks like on EFI our call to InstallConfigurationTable does not
work; after "acpi ..." "lsacpi --scan" still displays old RSDP and
tables (although grub itself would use new one).
I also have rather weird issue that after "acpi dsdt.aml" I lose
partitions (only hard disk itself is visible). This is on real hardware
(Dell Latitude E5450).
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: lsapi.patch --]
[-- Type: text/x-patch; name="lsapi.patch", Size: 12819 bytes --]
From: Andrei Borzenkov <arvidjaar@gmail.com>
Subject: [PATCH] lsacpi: print table address and allow bypassing stored pointers
1. Print memory address for each table, similat to what Linux kernel does.
2. Add "--scan" option to ignore stored RSDP address (after acpi command)
and use normal platform-specific way to search for it.
This provides for better debugging results of replacing tables with acpi.
---
grub-core/commands/acpi.c | 34 ++++++++------
grub-core/commands/acpihalt.c | 4 +-
grub-core/commands/lsacpi.c | 86 ++++++++++++++++++++++++++++++------
grub-core/efiemu/i386/pc/cfgtables.c | 4 +-
grub-core/loader/multiboot_mbi2.c | 6 +--
include/grub/acpi.h | 12 ++++-
6 files changed, 109 insertions(+), 37 deletions(-)
diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index b5c2f27..4163a78 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -100,22 +100,28 @@ static grub_size_t dsdt_size = 0;
static grub_uint32_t facs_addr = 0;
struct grub_acpi_rsdp_v20 *
-grub_acpi_get_rsdpv2 (void)
+grub_acpi_get_rsdpv2 (int scan)
{
- if (rsdpv2_new)
- return rsdpv2_new;
- if (rsdpv1_new)
- return 0;
+ if (!scan)
+ {
+ if (rsdpv2_new)
+ return rsdpv2_new;
+ if (rsdpv1_new)
+ return 0;
+ }
return grub_machine_acpi_get_rsdpv2 ();
}
struct grub_acpi_rsdp_v10 *
-grub_acpi_get_rsdpv1 (void)
+grub_acpi_get_rsdpv1 (int scan)
{
- if (rsdpv1_new)
- return rsdpv1_new;
- if (rsdpv2_new)
- return 0;
+ if (!scan)
+ {
+ if (rsdpv1_new)
+ return rsdpv1_new;
+ if (rsdpv2_new)
+ return 0;
+ }
return grub_machine_acpi_get_rsdpv1 ();
}
@@ -198,8 +204,8 @@ grub_acpi_create_ebda (void)
*((grub_uint16_t *) targetebda) = ebda_kb_len + 1;
target = targetebda;
- v1 = grub_acpi_get_rsdpv1 ();
- v2 = grub_acpi_get_rsdpv2 ();
+ v1 = grub_acpi_get_rsdpv1 (0);
+ v2 = grub_acpi_get_rsdpv2 (0);
if (v2 && v2->length > 40)
v2 = 0;
@@ -762,9 +768,9 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
struct grub_efi_guid acpi20 = GRUB_EFI_ACPI_20_TABLE_GUID;
grub_efi_system_table->boot_services->install_configuration_table
- (&acpi20, grub_acpi_get_rsdpv2 ());
+ (&acpi20, grub_acpi_get_rsdpv2 (0));
grub_efi_system_table->boot_services->install_configuration_table
- (&acpi, grub_acpi_get_rsdpv1 ());
+ (&acpi, grub_acpi_get_rsdpv1 (0));
}
#endif
diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c
index 9cc7f18..d7c51e1 100644
--- a/grub-core/commands/acpihalt.c
+++ b/grub-core/commands/acpihalt.c
@@ -395,11 +395,11 @@ grub_acpi_halt (void)
grub_uint32_t port = 0;
int sleep_type = -1;
- rsdp2 = grub_acpi_get_rsdpv2 ();
+ rsdp2 = grub_acpi_get_rsdpv2 (0);
if (rsdp2)
rsdp1 = &(rsdp2->rsdpv1);
else
- rsdp1 = grub_acpi_get_rsdpv1 ();
+ rsdp1 = grub_acpi_get_rsdpv1 (0);
grub_dprintf ("acpi", "rsdp1=%p\n", rsdp1);
if (!rsdp1)
return;
diff --git a/grub-core/commands/lsacpi.c b/grub-core/commands/lsacpi.c
index 0824914..34c1220 100644
--- a/grub-core/commands/lsacpi.c
+++ b/grub-core/commands/lsacpi.c
@@ -43,6 +43,7 @@ print_strn (grub_uint8_t *str, grub_size_t len)
static void
disp_acpi_table (struct grub_acpi_table_header *t)
{
+ grub_printf ("%p: ", t);
print_field (t->signature);
grub_printf ("%4" PRIuGRUB_UINT32_T "B rev=%u chksum=0x%02x (%s) OEM=", t->length, t->revision, t->checksum,
grub_byte_checksum (t, t->length) == 0 ? "valid" : "invalid");
@@ -59,7 +60,6 @@ disp_madt_table (struct grub_acpi_madt *t)
struct grub_acpi_madt_entry_header *d;
grub_uint32_t len;
- disp_acpi_table (&t->hdr);
grub_printf ("Local APIC=%08" PRIxGRUB_UINT32_T " Flags=%08"
PRIxGRUB_UINT32_T "\n",
t->lapic_addr, t->flags);
@@ -174,6 +174,61 @@ disp_madt_table (struct grub_acpi_madt *t)
}
static void
+disp_facs_header (struct grub_acpi_facs_header *t)
+{
+ grub_printf ("%p: ", t);
+ print_field (t->signature);
+ grub_printf ("%4" PRIuGRUB_UINT32_T "B", t->length);
+ grub_printf ("\n");
+}
+
+static void
+disp_fadt_table (struct grub_acpi_fadt *t)
+{
+ struct grub_acpi_facs_header *facs = NULL;
+ struct grub_acpi_table_header *dsdt = NULL;
+
+ if (t->hdr.revision >= 3)
+ {
+ if (t->facs_xaddr)
+ {
+ if (t->facs_addr)
+ grub_printf (" Ignoring FACS 0x08%" PRIxGRUB_UINT32_T "\n", t->facs_addr);
+
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+ if (t->facs_xaddr >= (1ULL << 32))
+ grub_printf (" Unreachable FACS 0x%016" PRIxGRUB_UINT64_T "\n", t->facs_xaddr);
+ else
+#endif
+ facs = (struct grub_acpi_facs_header *) (grub_addr_t) t->dsdt_xaddr;
+ }
+
+ if (t->dsdt_xaddr)
+ {
+ if (t->dsdt_addr)
+ grub_printf (" Ignoring DSDT 0x08%" PRIxGRUB_UINT32_T "\n", t->dsdt_addr);
+
+#if GRUB_CPU_SIZEOF_VOID_P == 4
+ if (t->dsdt_xaddr >= (1ULL << 32))
+ grub_printf (" Unreachable DSDT 0x%016" PRIxGRUB_UINT64_T "\n", t->dsdt_xaddr);
+ else
+#endif
+ dsdt = (struct grub_acpi_table_header *) (grub_addr_t) t->dsdt_xaddr;
+ }
+ }
+ else
+ {
+ facs = (struct grub_acpi_facs_header *) (grub_addr_t) t->facs_addr;
+ dsdt = (struct grub_acpi_table_header *) (grub_addr_t) t->dsdt_addr;
+ }
+
+ if (facs)
+ disp_facs_header (facs);
+ if (dsdt)
+ disp_acpi_table (dsdt);
+}
+
+static void
disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
{
grub_uint32_t len;
@@ -187,7 +242,7 @@ disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
#if GRUB_CPU_SIZEOF_VOID_P == 4
if (*desc >= (1ULL << 32))
{
- grub_printf ("Unreachable table\n");
+ grub_printf (" Unreachable table 0x%016" PRIxGRUB_UINT64_T "\n", *desc);
continue;
}
#endif
@@ -196,11 +251,13 @@ disp_acpi_xsdt_table (struct grub_acpi_table_header *t)
if (t == NULL)
continue;
+ disp_acpi_table (t);
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
sizeof (t->signature)) == 0)
disp_madt_table ((struct grub_acpi_madt *) t);
- else
- disp_acpi_table (t);
+ else if (grub_memcmp (t->signature, GRUB_ACPI_FADT_SIGNATURE,
+ sizeof (t->signature)) == 0)
+ disp_fadt_table ((struct grub_acpi_fadt *) t);
}
}
@@ -220,11 +277,13 @@ disp_acpi_rsdt_table (struct grub_acpi_table_header *t)
if (t == NULL)
continue;
+ disp_acpi_table (t);
if (grub_memcmp (t->signature, GRUB_ACPI_MADT_SIGNATURE,
sizeof (t->signature)) == 0)
disp_madt_table ((struct grub_acpi_madt *) t);
- else
- disp_acpi_table (t);
+ else if (grub_memcmp (t->signature, GRUB_ACPI_FADT_SIGNATURE,
+ sizeof (t->signature)) == 0)
+ disp_fadt_table ((struct grub_acpi_fadt *) t);
}
}
@@ -235,15 +294,13 @@ disp_acpi_rsdpv1 (struct grub_acpi_rsdp_v10 *rsdp)
grub_printf ("chksum:%02x (%s), OEM-ID: ", rsdp->checksum, grub_byte_checksum (rsdp, sizeof (*rsdp)) == 0 ? "valid" : "invalid");
print_field (rsdp->oemid);
grub_printf ("rev=%d\n", rsdp->revision);
- grub_printf ("RSDT=%08" PRIxGRUB_UINT32_T "\n", rsdp->rsdt_addr);
}
static void
disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
{
disp_acpi_rsdpv1 (&rsdp->rsdpv1);
- grub_printf ("len=%d chksum=%02x (%s) XSDT=%016" PRIxGRUB_UINT64_T "\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid",
- rsdp->xsdt_addr);
+ grub_printf ("len=%d chksum=%02x (%s)\n", rsdp->length, rsdp->checksum, grub_byte_checksum (rsdp, rsdp->length) == 0 ? "valid" : "invalid");
if (rsdp->length != sizeof (*rsdp))
grub_printf (" length mismatch %d != %d\n", rsdp->length,
(int) sizeof (*rsdp));
@@ -254,6 +311,7 @@ disp_acpi_rsdpv2 (struct grub_acpi_rsdp_v20 *rsdp)
static const struct grub_arg_option options[] = {
{"v1", '1', 0, N_("Show version 1 tables only."), 0, ARG_TYPE_NONE},
{"v2", '2', 0, N_("Show version 2 and version 3 tables only."), 0, ARG_TYPE_NONE},
+ {"scan", 0, 0, N_("Ignore cached RSDP pointers and rescan."), 0, ARG_TYPE_NONE},
{0, 0, 0, 0, 0, 0}
};
@@ -264,12 +322,12 @@ grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
{
if (!ctxt->state[1].set)
{
- struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 ();
+ struct grub_acpi_rsdp_v10 *rsdp1 = grub_acpi_get_rsdpv1 (ctxt->state[2].set);
if (!rsdp1)
grub_printf ("No RSDPv1\n");
else
{
- grub_printf ("RSDPv1 signature:");
+ grub_printf ("%p: RSDPv1 signature:", rsdp1);
disp_acpi_rsdpv1 (rsdp1);
disp_acpi_rsdt_table ((void *) (grub_addr_t) rsdp1->rsdt_addr);
}
@@ -277,7 +335,7 @@ grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
if (!ctxt->state[0].set)
{
- struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 ();
+ struct grub_acpi_rsdp_v20 *rsdp2 = grub_acpi_get_rsdpv2 (ctxt->state[2].set);
if (!rsdp2)
grub_printf ("No RSDPv2\n");
else
@@ -288,7 +346,7 @@ grub_cmd_lsacpi (struct grub_extcmd_context *ctxt,
else
#endif
{
- grub_printf ("RSDPv2 signature:");
+ grub_printf ("%p: RSDPv2 signature:", rsdp2);
disp_acpi_rsdpv2 (rsdp2);
disp_acpi_xsdt_table ((void *) (grub_addr_t) rsdp2->xsdt_addr);
grub_printf ("\n");
@@ -302,7 +360,7 @@ static grub_extcmd_t cmd;
GRUB_MOD_INIT(lsapi)
{
- cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, "[-1|-2]",
+ cmd = grub_register_extcmd ("lsacpi", grub_cmd_lsacpi, 0, "[-1|-2] [--scan]",
N_("Show ACPI information."), options);
}
diff --git a/grub-core/efiemu/i386/pc/cfgtables.c b/grub-core/efiemu/i386/pc/cfgtables.c
index 492c07c..99a9228 100644
--- a/grub-core/efiemu/i386/pc/cfgtables.c
+++ b/grub-core/efiemu/i386/pc/cfgtables.c
@@ -43,14 +43,14 @@ grub_machine_efiemu_init_tables (void)
if (err)
return err;
- table = grub_acpi_get_rsdpv1 ();
+ table = grub_acpi_get_rsdpv1 (0);
if (table)
{
err = grub_efiemu_register_configuration_table (acpi, 0, 0, table);
if (err)
return err;
}
- table = grub_acpi_get_rsdpv2 ();
+ table = grub_acpi_get_rsdpv2 (0);
if (table)
{
err = grub_efiemu_register_configuration_table (acpi20, 0, 0, table);
diff --git a/grub-core/loader/multiboot_mbi2.c b/grub-core/loader/multiboot_mbi2.c
index b0679a9..640a8de 100644
--- a/grub-core/loader/multiboot_mbi2.c
+++ b/grub-core/loader/multiboot_mbi2.c
@@ -391,7 +391,7 @@ static grub_size_t
acpiv2_size (void)
{
#if GRUB_MACHINE_HAS_ACPI
- struct grub_acpi_rsdp_v20 *p = grub_acpi_get_rsdpv2 ();
+ struct grub_acpi_rsdp_v20 *p = grub_acpi_get_rsdpv2 (0);
if (!p)
return 0;
@@ -938,7 +938,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
{
struct multiboot_tag_old_acpi *tag = (struct multiboot_tag_old_acpi *)
ptrorig;
- struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 ();
+ struct grub_acpi_rsdp_v10 *a = grub_acpi_get_rsdpv1 (0);
if (a)
{
tag->type = MULTIBOOT_TAG_TYPE_ACPI_OLD;
@@ -952,7 +952,7 @@ grub_multiboot_make_mbi (grub_uint32_t *target)
{
struct multiboot_tag_new_acpi *tag = (struct multiboot_tag_new_acpi *)
ptrorig;
- struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 ();
+ struct grub_acpi_rsdp_v20 *a = grub_acpi_get_rsdpv2 (0);
if (a)
{
tag->type = MULTIBOOT_TAG_TYPE_ACPI_NEW;
diff --git a/include/grub/acpi.h b/include/grub/acpi.h
index 66148f6..f00e1d6 100644
--- a/include/grub/acpi.h
+++ b/include/grub/acpi.h
@@ -60,6 +60,14 @@ struct grub_acpi_table_header
grub_uint32_t creator_rev;
} GRUB_PACKED;
+#define GRUB_ACPI_FACS_SIGNATURE "FACS"
+
+struct grub_acpi_facs_header
+{
+ grub_uint8_t signature[4];
+ grub_uint32_t length;
+} GRUB_PACKED;
+
#define GRUB_ACPI_FADT_SIGNATURE "FACP"
struct grub_acpi_fadt
@@ -180,8 +188,8 @@ enum
};
#ifndef GRUB_DSDT_TEST
-struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (void);
-struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (void);
+struct grub_acpi_rsdp_v10 *grub_acpi_get_rsdpv1 (int scan);
+struct grub_acpi_rsdp_v20 *grub_acpi_get_rsdpv2 (int scan);
struct grub_acpi_rsdp_v10 *EXPORT_FUNC(grub_machine_acpi_get_rsdpv1) (void);
struct grub_acpi_rsdp_v20 *EXPORT_FUNC(grub_machine_acpi_get_rsdpv2) (void);
grub_uint8_t EXPORT_FUNC(grub_byte_checksum) (void *base, grub_size_t size);
--
tg: (17cb997..) u/lsacpi/print-table-address (depends on: u/lsacpi/printf-pointer-align)
next prev parent reply other threads:[~2017-04-01 9:09 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1736729449.4676062.1487865639993.ref@mail.yahoo.com>
2017-02-23 16:00 ` Loading DSDT table using 'acpi' or some memory write command? Nando Eva
2017-02-24 16:32 ` Andrei Borzenkov
2017-02-27 11:29 ` Nando Eva
2017-02-27 13:42 ` Andrei Borzenkov
2017-02-27 15:13 ` Vladimir 'phcoder' Serbinenko
2017-02-27 15:31 ` Vladimir 'phcoder' Serbinenko
2017-02-27 15:13 ` Nando Eva
2017-02-27 18:21 ` Nando Eva
2017-03-27 14:12 ` Nando Eva
2017-03-27 16:55 ` Andrei Borzenkov
2017-03-29 17:45 ` Nando Eva
2017-03-30 4:03 ` Andrei Borzenkov
2017-04-01 9:09 ` Andrei Borzenkov [this message]
2017-04-01 15:24 ` [PATCH] acpi: add missing efi_call wrapper to acpi command Andrei Borzenkov
2017-04-02 8:27 ` Vladimir 'phcoder' Serbinenko
2017-04-04 18:18 ` [PATCH] acpi: do not attempt to create EBDA on EFI (was: Loading DSDT table using 'acpi' or some memory write command?) Andrei Borzenkov
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=d042fbf2-a614-a405-815b-73c7fe37af28@gmail.com \
--to=arvidjaar@gmail.com \
--cc=grub-devel@gnu.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 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).