> 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)?
> Again - what address are you updating?
>
> We need to understand why it fails first. GRUB *does* attempt to
> override RSDP if it finds it.
On Tuesday, 28 March 2017, 1:12, Nando Eva wrote:
OK, I found the cause if the problem:
- the ACPI tables specified to the 'acpi' command are loaded to new addresses
and a new RSDT and XSDT created with pointers to them. This can be confirmed by
the 'lsacpi' command.
- the RSDP isn't updated to point to the new RSDT and XSDT.
So when chainload the OS, the original RSDT and XSDT are referenced from the
RSDP.
I'm now manually doing the 'acpi [DSDT]' table load, then a 'lsacpi -2' to find
the new RSDT+XSDT addresses and updating the RSDP via two write_dword memory
writes (though not doing checksum correction).
Can a pach be made for grub2 to correct this behaviour to be automated without
such manual intervention?
Thank you,Nando
On Tuesday, 28 February 2017, 5:21, Nando Eva wrote:
Vladimir 'phcoder' Serbinenko wrote:
I reproduced the bug. I'm investigating
>> Apparently finish_boot_services rewrites acpi tables. It's possible to
>> workaround this, possibly by using acpi table protocol. >> But it's
>> certainely not for 2.02 at this point.
Thank you for investigating the issue. Earlier I did a test to check to see if
UEFI chainloading was altering ACPI tables. I did this by:
1. performing two grub2 "write_dword" console memory commands to enable ASPM in
the ACPI FADT (FACP on my system) table as per
http://smackerelofopinion.blogspot.com.au/2011/03/making-sense-of-pcie-aspm.html
2. then chainloaded from Grub2 to windows: chainloader
/efi/Microsoft/Boot/bootmgfw.efi
The ASPM enabling change was there as found by using r-w everything and
reported by 'powercfg /energy', indicating the UEFI chainloading isn't, at
least for ACPI FADT (FACP), altering the in-memory table.
As the DSDT table is much larger, I can't really write_dword it. Hence asking
for some other memory loading module.
As another lead, I found the mentioned finish_boot_services routine in mm.c,
quoted below. Would you mind pointing out which code is rewriting the ACPI
tables?
Thank you,Nando
---grub_err_t
grub_efi_finish_boot_services (grub_efi_uintn_t *outbuf_size, void *outbuf,
grub_efi_uintn_t *map_key,
grub_efi_uintn_t *efi_desc_size,
grub_efi_uint32_t *efi_desc_version)
{
grub_efi_boot_services_t *b;
grub_efi_status_t status;
#if defined (__i386__) || defined (__x86_64__)
const grub_uint16_t apple[] = { 'A', 'p', 'p', 'l', 'e' };
int is_apple;
is_apple = (grub_memcmp (grub_efi_system_table->firmware_vendor,
apple, sizeof (apple)) == 0);
#endif
while (1)
{
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf,
&finish_key,
&finish_desc_size, &finish_desc_version) < 0)
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
if (outbuf && *outbuf_size < finish_mmap_size)
return grub_error (GRUB_ERR_IO, "memory map buffer is too small");
finish_mmap_buf = grub_malloc (finish_mmap_size);
if (!finish_mmap_buf)
return grub_errno;
if (grub_efi_get_memory_map (&finish_mmap_size, finish_mmap_buf,
&finish_key,
&finish_desc_size, &finish_desc_version) <= 0)
{
grub_free (finish_mmap_buf);
return grub_error (GRUB_ERR_IO, "couldn't retrieve memory map");
}
b = grub_efi_system_table->boot_services;
status = efi_call_2 (b->exit_boot_services, grub_efi_image_handle,
finish_key);
if (status == GRUB_EFI_SUCCESS)
break;
if (status != GRUB_EFI_INVALID_PARAMETER)
{
grub_free (finish_mmap_buf);
return grub_error (GRUB_ERR_IO, "couldn't terminate EFI services");
}
grub_free (finish_mmap_buf);
grub_printf ("Trying to terminate EFI services again\n");
}
grub_efi_is_finished = 1;
if (outbuf_size)
*outbuf_size = finish_mmap_size;
if (outbuf)
grub_memcpy (outbuf, finish_mmap_buf, finish_mmap_size);
if (map_key)
*map_key = finish_key;
if (efi_desc_size)
*efi_desc_size = finish_desc_size;
if (efi_desc_version)
*efi_desc_version = finish_desc_version;
#if defined (__i386__) || defined (__x86_64__)
if (is_apple)
stop_broadcom ();
#endif
return GRUB_ERR_NONE;
}
Nando
On Tuesday, 28 February 2017, 2:13, Nando Eva wrote: