Re: Loading DSDT table using 'acpi' or some memory write command?

2017-03-29 Thread 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)?

> 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:

Re: Loading DSDT table using 'acpi' or some memory write command?

2017-03-29 Thread Andrei Borzenkov
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)?
> 

Add printing of RSDP address to lsacpi.

___
Grub-devel mailing list
Grub-devel@gnu.org
https://lists.gnu.org/mailman/listinfo/grub-devel