All of lore.kernel.org
 help / color / mirror / Atom feed
* Loading DSDT table using 'acpi' or some memory write command?
       [not found] <1736729449.4676062.1487865639993.ref@mail.yahoo.com>
@ 2017-02-23 16:00 ` Nando Eva
  2017-02-24 16:32   ` Andrei Borzenkov
  2017-02-27 11:29   ` Nando Eva
  0 siblings, 2 replies; 16+ messages in thread
From: Nando Eva @ 2017-02-23 16:00 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 964 bytes --]

Hi grub-devel,
I'm endeavouring to pre-load a modified DSDT table using grub2. The syntax I've tried being as shown below, after which I chainload to Win10. This being done on a Dell E6540 with Win10 and grub 2.02 (or older.. tried many versions, same result).

acpi /efi/dsdt.amlacpi --load-table dsdt /efi/dsdt.amlchainloader /efi/Boot/bootx64.efi
Then I do 'acpidump -b' to peruse the DSDT table. In all cases, it remains the same system BIOS one, not my modified /efi/dsdt.aml one.

I've also set 'set debug=all' and can see grub2 is reading my modified dsdt file and doing memory writes.
So two questions:
1. Is 'acpi' not capable of loading a DSDT table for use with Win10?
2. if that is the case, is there some 'memload' or 'writefromfile' type command where I give a memory address and a file which grub2 can then write? The idea is simply to replace the existing DSDT at it's address with one given by the file of same size or smaller.
Thank you,Nando




[-- Attachment #2: Type: text/html, Size: 2515 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  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
  1 sibling, 0 replies; 16+ messages in thread
From: Andrei Borzenkov @ 2017-02-24 16:32 UTC (permalink / raw)
  To: The development of GNU GRUB

23.02.2017 19:00, Nando Eva пишет:
> Hi grub-devel, I'm endeavouring to pre-load a modified DSDT table 
> using grub2. The syntax I've tried being as shown below, after which 
> I chainload to Win10. This being done on a Dell E6540 with Win10 and 
> grub 2.02 (or older.. tried many versions, same result).
> 
> acpi /efi/dsdt.amlacpi --load-table dsdt /efi/dsdt.amlchainloader 
> /efi/Boot/bootx64.efi Then I do 'acpidump -b' to peruse the DSDT 
> table. In all cases, it remains the same system BIOS one, not my 
> modified /efi/dsdt.aml one.
> 
> I've also set 'set debug=all' and can see grub2 is reading my 
> modified dsdt file and doing memory writes. So two questions: 1. Is 
> 'acpi' not capable of loading a DSDT table for use with Win10?

It is supposed to do it. Could you test with explicit "acpi -(1|2)" to
force either version 1 or version 2 of tables.

> 2. if that is the case, is there some 'memload' or 'writefromfile' 
> type command where I give a memory address and a file which grub2
> can then write? The idea is simply to replace the existing DSDT at
> it's address with one given by the file of same size or smaller.
> Thank you,Nando
> 



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  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     ` Nando Eva
  1 sibling, 2 replies; 16+ messages in thread
From: Nando Eva @ 2017-02-27 11:29 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1862 bytes --]

@Andrei Borzenkov, I've confirmed that any of the following do not alter the Win10 DSDT table across numerous Macbooks and my Dell E6540.

acpi dsdt.amlacpi --load-only dsdt dsdt.amlacpi -2 dsdt.aml
Followed by:
chainloader /efi/Microsoft/Boot/bootmgfw.efi

Clover has a DSDT override function and using it works on my Dell E6540. However it does it by writing to the UEFI firmware volume, which for Macbooks, has had one test instance of bricking the system. 
Any chance of a simple  'load_dsdt [file]' command that acquires the in-memory DSDT table address, checks it's size, then overwrites it with the file name specified if it's the same size or smaller?  

Or some function to write a file to a memory location like 'write_byte'. Maybe 'write_file'?

Thank you,Nando
 

    On Friday, 24 February 2017, 3:00, Nando Eva <nando4eva@ymail.com> wrote:
 

 Hi grub-devel,
I'm endeavouring to pre-load a modified DSDT table using grub2. The syntax I've tried being as shown below, after which I chainload to Win10. This being done on a Dell E6540 with Win10 and grub 2.02 (or older.. tried many versions, same result).

acpi /efi/dsdt.amlacpi --load-table dsdt /efi/dsdt.amlchainloader /efi/Boot/bootx64.efi
Then I do 'acpidump -b' to peruse the DSDT table. In all cases, it remains the same system BIOS one, not my modified /efi/dsdt.aml one.

I've also set 'set debug=all' and can see grub2 is reading my modified dsdt file and doing memory writes.
So two questions:
1. Is 'acpi' not capable of loading a DSDT table for use with Win10?
2. if that is the case, is there some 'memload' or 'writefromfile' type command where I give a memory address and a file which grub2 can then write? The idea is simply to replace the existing DSDT at it's address with one given by the file of same size or smaller.
Thank you,Nando





   

[-- Attachment #2: Type: text/html, Size: 5240 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  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:13     ` Nando Eva
  1 sibling, 1 reply; 16+ messages in thread
From: Andrei Borzenkov @ 2017-02-27 13:42 UTC (permalink / raw)
  To: The development of GNU GRUB

On Mon, Feb 27, 2017 at 2:29 PM, Nando Eva <nando4eva@ymail.com> wrote:
> @Andrei Borzenkov, I've confirmed that any of the following do not alter the
> Win10 DSDT table across numerous Macbooks and my Dell E6540.
>
> acpi dsdt.aml
> acpi --load-only dsdt dsdt.aml
> acpi -2 dsdt.aml
>
> Followed by:
> chainloader /efi/Microsoft/Boot/bootmgfw.efi
>
> Clover has a DSDT override function and using it works on my Dell E6540.
> However it does it by writing to the UEFI firmware volume, which for
> Macbooks, has had one test instance of bricking the system.
>
> Any chance of a simple  'load_dsdt [file]' command that acquires the
> in-memory DSDT table address, checks it's size, then overwrites it with the
> file name specified if it's the same size or smaller?
>

That's more or less what grub tries to do. We cannot really overwrite
ACPI tables because they may be located in read-only memory, but it
attempts to create EBDA and place new RSDP there and update EBDA
address as well as update RSDP pointer in EFI system table. I would
suggest trying to load something else (like Linux) and check whether
it sees new or old table.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  2017-02-27 13:42     ` Andrei Borzenkov
@ 2017-02-27 15:13       ` Vladimir 'phcoder' Serbinenko
  2017-02-27 15:31         ` Vladimir 'phcoder' Serbinenko
  0 siblings, 1 reply; 16+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2017-02-27 15:13 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 1458 bytes --]

I reproduced the bug. I'm investigating

On Mon, Feb 27, 2017, 05:53 Andrei Borzenkov <arvidjaar@gmail.com> wrote:

> On Mon, Feb 27, 2017 at 2:29 PM, Nando Eva <nando4eva@ymail.com> wrote:
> > @Andrei Borzenkov, I've confirmed that any of the following do not alter
> the
> > Win10 DSDT table across numerous Macbooks and my Dell E6540.
> >
> > acpi dsdt.aml
> > acpi --load-only dsdt dsdt.aml
> > acpi -2 dsdt.aml
> >
> > Followed by:
> > chainloader /efi/Microsoft/Boot/bootmgfw.efi
> >
> > Clover has a DSDT override function and using it works on my Dell E6540.
> > However it does it by writing to the UEFI firmware volume, which for
> > Macbooks, has had one test instance of bricking the system.
> >
> > Any chance of a simple  'load_dsdt [file]' command that acquires the
> > in-memory DSDT table address, checks it's size, then overwrites it with
> the
> > file name specified if it's the same size or smaller?
> >
>
> That's more or less what grub tries to do. We cannot really overwrite
> ACPI tables because they may be located in read-only memory, but it
> attempts to create EBDA and place new RSDP there and update EBDA
> address as well as update RSDP pointer in EFI system table. I would
> suggest trying to load something else (like Linux) and check whether
> it sees new or old table.
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>

[-- Attachment #2: Type: text/html, Size: 2682 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  2017-02-27 11:29   ` Nando Eva
  2017-02-27 13:42     ` Andrei Borzenkov
@ 2017-02-27 15:13     ` Nando Eva
  2017-02-27 18:21       ` Nando Eva
  1 sibling, 1 reply; 16+ messages in thread
From: Nando Eva @ 2017-02-27 15:13 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1541 bytes --]

Andrei Borzenkov wrote:
>> That's more or less what grub tries to do. We cannot really overwrite
>> ACPI tables because they may be located in read-only memory, but it
>> attempts to create EBDA and place new RSDP there and update EBDA
>> address as well as update RSDP pointer in EFI system table. I would
>> suggest trying to load something else (like Linux) and check whether
>> it sees new or old table.

This user had 'acpi' also fail to replace the FACS ACPI table on Linux:
https://bbs.archlinux.org/viewtopic.php?id=190258 

The DSDT I require is for Win10. Win10 has a registry override method to replace a DSDT but requires test signing mode to do it, along with some app restrictions/incompatibilities. 

I require a pre-boot DSDT override method to overcome Win10 test signing mode AND have my required DSDT table loaded. Just need an in-memory DSDT subsitution tool to do it.  

I have been able to accomplish this using MBR boot because the tools exist. For the more popular UEFI,I have yet to find a load-file-into-memory-location tool to make it possible. Only things are the multiboot file encapsulation, hexedit and write_dword. All not the right fit. 

Any chance the grub-devel team can help out here with either a load-file-to-memory-location module/tool (where I need to find the address) or specifically one that does a in-memory DSDT override by overwriting the existing table? Of course, ppl with read-only memory can't use it just like I imagine would be the case with the current 'acpi' method. 

Thank you,
Nando

[-- Attachment #2: Type: text/html, Size: 1932 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  2017-02-27 15:13       ` Vladimir 'phcoder' Serbinenko
@ 2017-02-27 15:31         ` Vladimir 'phcoder' Serbinenko
  0 siblings, 0 replies; 16+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2017-02-27 15:31 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 1730 bytes --]

On Mon, Feb 27, 2017, 07:13 Vladimir 'phcoder' Serbinenko <phcoder@gmail.com>
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.

>
> On Mon, Feb 27, 2017, 05:53 Andrei Borzenkov <arvidjaar@gmail.com> wrote:
>
> On Mon, Feb 27, 2017 at 2:29 PM, Nando Eva <nando4eva@ymail.com> wrote:
> > @Andrei Borzenkov, I've confirmed that any of the following do not alter
> the
> > Win10 DSDT table across numerous Macbooks and my Dell E6540.
> >
> > acpi dsdt.aml
> > acpi --load-only dsdt dsdt.aml
> > acpi -2 dsdt.aml
> >
> > Followed by:
> > chainloader /efi/Microsoft/Boot/bootmgfw.efi
> >
> > Clover has a DSDT override function and using it works on my Dell E6540.
> > However it does it by writing to the UEFI firmware volume, which for
> > Macbooks, has had one test instance of bricking the system.
> >
> > Any chance of a simple  'load_dsdt [file]' command that acquires the
> > in-memory DSDT table address, checks it's size, then overwrites it with
> the
> > file name specified if it's the same size or smaller?
> >
>
> That's more or less what grub tries to do. We cannot really overwrite
> ACPI tables because they may be located in read-only memory, but it
> attempts to create EBDA and place new RSDP there and update EBDA
> address as well as update RSDP pointer in EFI system table. I would
> suggest trying to load something else (like Linux) and check whether
> it sees new or old table.
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
>

[-- Attachment #2: Type: text/html, Size: 3463 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  2017-02-27 15:13     ` Nando Eva
@ 2017-02-27 18:21       ` Nando Eva
  2017-03-27 14:12         ` Nando Eva
  0 siblings, 1 reply; 16+ messages in thread
From: Nando Eva @ 2017-02-27 18:21 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 5390 bytes --]

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 <nando4eva@ymail.com> wrote:
 

 Andrei Borzenkov wrote:
>> That's more or less what grub tries to do. We cannot really overwrite
>> ACPI tables because they may be located in read-only memory, but it
>> attempts to create EBDA and place new RSDP there and update EBDA
>> address as well as update RSDP pointer in EFI system table. I would
>> suggest trying to load something else (like Linux) and check whether
>> it sees new or old table.

This user had 'acpi' also fail to replace the FACS ACPI table on Linux:
https://bbs.archlinux.org/viewtopic.php?id=190258 

The DSDT I require is for Win10. Win10 has a registry override method to replace a DSDT but requires test signing mode to do it, along with some app restrictions/incompatibilities. 

I require a pre-boot DSDT override method to overcome Win10 test signing mode AND have my required DSDT table loaded. Just need an in-memory DSDT subsitution tool to do it.  

I have been able to accomplish this using MBR boot because the tools exist. For the more popular UEFI,I have yet to find a load-file-into-memory-location tool to make it possible. Only things are the multiboot file encapsulation, hexedit and write_dword. All not the right fit. 

Any chance the grub-devel team can help out here with either a load-file-to-memory-location module/tool (where I need to find the address) or specifically one that does a in-memory DSDT override by overwriting the existing table? Of course, ppl with read-only memory can't use it just like I imagine would be the case with the current 'acpi' method. 

Thank you,
Nando


   

[-- Attachment #2: Type: text/html, Size: 12528 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  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
  0 siblings, 2 replies; 16+ messages in thread
From: Nando Eva @ 2017-03-27 14:12 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 6185 bytes --]

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 <nando4eva@ymail.com> 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 <nando4eva@ymail.com> wrote:
 

 Andrei Borzenkov wrote:
>> That's more or less what grub tries to do. We cannot really overwrite
>> ACPI tables because they may be located in read-only memory, but it
>> attempts to create EBDA and place new RSDP there and update EBDA
>> address as well as update RSDP pointer in EFI system table. I would
>> suggest trying to load something else (like Linux) and check whether
>> it sees new or old table.

This user had 'acpi' also fail to replace the FACS ACPI table on Linux:
https://bbs.archlinux.org/viewtopic.php?id=190258 

The DSDT I require is for Win10. Win10 has a registry override method to replace a DSDT but requires test signing mode to do it, along with some app restrictions/incompatibilities. 

I require a pre-boot DSDT override method to overcome Win10 test signing mode AND have my required DSDT table loaded. Just need an in-memory DSDT subsitution tool to do it.  

I have been able to accomplish this using MBR boot because the tools exist. For the more popular UEFI,I have yet to find a load-file-into-memory-location tool to make it possible. Only things are the multiboot file encapsulation, hexedit and write_dword. All not the right fit. 

Any chance the grub-devel team can help out here with either a load-file-to-memory-location module/tool (where I need to find the address) or specifically one that does a in-memory DSDT override by overwriting the existing table? Of course, ppl with read-only memory can't use it just like I imagine would be the case with the current 'acpi' method. 

Thank you,
Nando


   

   

[-- Attachment #2: Type: text/html, Size: 18082 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  2017-03-27 14:12         ` Nando Eva
@ 2017-03-27 16:55           ` Andrei Borzenkov
  2017-03-29 17:45           ` Nando Eva
  1 sibling, 0 replies; 16+ messages in thread
From: Andrei Borzenkov @ 2017-03-27 16:55 UTC (permalink / raw)
  To: The development of GNU GRUB

27.03.2017 17:12, Nando Eva пишет:
> 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. 
> 

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.

> 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).

Again - what address are you updating?

> Can a pach be made for grub2 to correct this behaviour to be automated without such manual intervention? 

We need to understand why it fails first. GRUB *does* attempt to
override RSDP if it finds it.

> Thank you,Nando 
> 
>     On Tuesday, 28 February 2017, 5:21, Nando Eva <nando4eva@ymail.com> 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?

The whole ACPI tables mangling happens in grub-core/commands/acpi.c



^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  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
  1 sibling, 2 replies; 16+ messages in thread
From: Nando Eva @ 2017-03-29 17:45 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 6971 bytes --]

> 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 <nando4eva@ymail.com> 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 <nando4eva@ymail.com> 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 <nando4eva@ymail.com> wrote:
 

 Andrei Borzenkov wrote:
>> That's more or less what grub tries to do. We cannot really overwrite
>> ACPI tables because they may be located in read-only memory, but it
>> attempts to create EBDA and place new RSDP there and update EBDA
>> address as well as update RSDP pointer in EFI system table. I would
>> suggest trying to load something else (like Linux) and check whether
>> it sees new or old table.

This user had 'acpi' also fail to replace the FACS ACPI table on Linux:
https://bbs.archlinux.org/viewtopic.php?id=190258 

The DSDT I require is for Win10. Win10 has a registry override method to replace a DSDT but requires test signing mode to do it, along with some app restrictions/incompatibilities. 

I require a pre-boot DSDT override method to overcome Win10 test signing mode AND have my required DSDT table loaded. Just need an in-memory DSDT subsitution tool to do it.  

I have been able to accomplish this using MBR boot because the tools exist. For the more popular UEFI,I have yet to find a load-file-into-memory-location tool to make it possible. Only things are the multiboot file encapsulation, hexedit and write_dword. All not the right fit. 

Any chance the grub-devel team can help out here with either a load-file-to-memory-location module/tool (where I need to find the address) or specifically one that does a in-memory DSDT override by overwriting the existing table? Of course, ppl with read-only memory can't use it just like I imagine would be the case with the current 'acpi' method. 

Thank you,
Nando


   

   

   

[-- Attachment #2: Type: text/html, Size: 20248 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  2017-03-29 17:45           ` Nando Eva
@ 2017-03-30  4:03             ` Andrei Borzenkov
  2017-04-01  9:09             ` Andrei Borzenkov
  1 sibling, 0 replies; 16+ messages in thread
From: Andrei Borzenkov @ 2017-03-30  4:03 UTC (permalink / raw)
  To: grub-devel

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.


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: Loading DSDT table using 'acpi' or some memory write command?
  2017-03-29 17:45           ` Nando Eva
  2017-03-30  4:03             ` Andrei Borzenkov
@ 2017-04-01  9:09             ` Andrei Borzenkov
  2017-04-01 15:24               ` [PATCH] acpi: add missing efi_call wrapper to acpi command Andrei Borzenkov
  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
  1 sibling, 2 replies; 16+ messages in thread
From: Andrei Borzenkov @ 2017-04-01  9:09 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- 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)

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH] acpi: add missing efi_call wrapper to acpi command
  2017-04-01  9:09             ` Andrei Borzenkov
@ 2017-04-01 15:24               ` 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
  1 sibling, 1 reply; 16+ messages in thread
From: Andrei Borzenkov @ 2017-04-01 15:24 UTC (permalink / raw)
  To: grub-devel; +Cc: Nando Eva, Vladimir 'phcoder' Serbinenko

Fixed loading of ACPI tables on EFI (side effect was apparent memory
corruption ranging from unpredictable behavior to system reset).

Reported by Nando Eva <nando4eva@ymail.com>

---

@Nando: please test this patch. It fixed loading for me at least on
QEMU/OVMF. It conflicts with lsacpi patch, but you can actually
verify that RSDP was updated by using "lsefisystab" in grub.

@Vladimir: this looks like 2.02 material as it was obviously wrong.
It does not fix weird behavior on physical system (loss of partitions
afetr loading table using "acpi"); unfortunately, I cannot reproduce
it in QEMU which makes it rather hard to debug. This smells like yet
another meory corruption.

Also our ACPI table mangling code is not clean (e.g. Linux reports
FACS two times). Note that ACPI says normal and extended addresses
(i.e. DSDT/XDSDT and FACS/XFACS) are mutually exclusive, while we
set both to non-zero. This strictly speaking violates specs.

 grub-core/commands/acpi.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index b5c2f27..9f02f22 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -761,10 +761,10 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
     struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
     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 ());
-    grub_efi_system_table->boot_services->install_configuration_table
-      (&acpi, grub_acpi_get_rsdpv1 ());
+    efi_call_2 (grub_efi_system_table->boot_services->install_configuration_table,
+      &acpi20, grub_acpi_get_rsdpv2 ());
+    efi_call_2 (grub_efi_system_table->boot_services->install_configuration_table,
+      &acpi, grub_acpi_get_rsdpv1 ());
   }
 #endif
 
-- 
tg: (8014b7b..) u/acpi-efi_call (depends on: master)


^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH] acpi: add missing efi_call wrapper to acpi command
  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
  0 siblings, 0 replies; 16+ messages in thread
From: Vladimir 'phcoder' Serbinenko @ 2017-04-02  8:27 UTC (permalink / raw)
  To: Andrey Borzenkov, The development of GRUB 2; +Cc: Nando Eva

[-- Attachment #1: Type: text/plain, Size: 2145 bytes --]

On Sat, Apr 1, 2017, 05:24 Andrei Borzenkov <arvidjaar@gmail.com> wrote:

> Fixed loading of ACPI tables on EFI (side effect was apparent memory
> corruption ranging from unpredictable behavior to system reset).
>
> Reported by Nando Eva <nando4eva@ymail.com>
>
> ---
>
> @Nando: please test this patch. It fixed loading for me at least on
> QEMU/OVMF. It conflicts with lsacpi patch, but you can actually
> verify that RSDP was updated by using "lsefisystab" in grub.
>
> @Vladimir: this looks like 2.02 material as it was obviously wrong.
>
Agreed, go ahead.

> It does not fix weird behavior on physical system (loss of partitions
> afetr loading table using "acpi"); unfortunately, I cannot reproduce
> it in QEMU which makes it rather hard to debug. This smells like yet
> another meory corruption.
>
> Also our ACPI table mangling code is not clean (e.g. Linux reports
> FACS two times). Note that ACPI says normal and extended addresses
> (i.e. DSDT/XDSDT and FACS/XFACS) are mutually exclusive, while we
> set both to non-zero. This strictly speaking violates specs.
>
>  grub-core/commands/acpi.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
> index b5c2f27..9f02f22 100644
> --- a/grub-core/commands/acpi.c
> +++ b/grub-core/commands/acpi.c
> @@ -761,10 +761,10 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int
> argc, char **args)
>      struct grub_efi_guid acpi = GRUB_EFI_ACPI_TABLE_GUID;
>      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 ());
> -    grub_efi_system_table->boot_services->install_configuration_table
> -      (&acpi, grub_acpi_get_rsdpv1 ());
> +    efi_call_2
> (grub_efi_system_table->boot_services->install_configuration_table,
> +      &acpi20, grub_acpi_get_rsdpv2 ());
> +    efi_call_2
> (grub_efi_system_table->boot_services->install_configuration_table,
> +      &acpi, grub_acpi_get_rsdpv1 ());
>    }
>  #endif
>
> --
> tg: (8014b7b..) u/acpi-efi_call (depends on: master)
>

[-- Attachment #2: Type: text/html, Size: 3663 bytes --]

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH] acpi: do not attempt to create EBDA on EFI (was: Loading DSDT table using 'acpi' or some memory write command?)
  2017-04-01  9:09             ` Andrei Borzenkov
  2017-04-01 15:24               ` [PATCH] acpi: add missing efi_call wrapper to acpi command Andrei Borzenkov
@ 2017-04-04 18:18               ` Andrei Borzenkov
  1 sibling, 0 replies; 16+ messages in thread
From: Andrei Borzenkov @ 2017-04-04 18:18 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 321 bytes --]

01.04.2017 12:09, Andrei Borzenkov пишет:
> 
> 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).
> 
> 

Anyone knows why we attempt to write to some arbitrary memory location
on EFI in the first place?

[-- Attachment #2: acpi-no-ebda-on-efi.patch --]
[-- Type: text/x-patch, Size: 1170 bytes --]

From: Andrei Borzenkov <arvidjaar@gmail.com>
Subject: [PATCH] acpi: do not attempt to create EBDA on EFI

There is no gurantee that BDA or EBDA on EFI exists; blindly writing
into memory will likely corrupt it. This fixed problem on Dell Latitude
E5450, where after loading ACPI table GRUB "lost" all disk partitions.

---
 grub-core/commands/acpi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c
index 9f02f22..a395d74 100644
--- a/grub-core/commands/acpi.c
+++ b/grub-core/commands/acpi.c
@@ -119,7 +119,7 @@ grub_acpi_get_rsdpv1 (void)
   return grub_machine_acpi_get_rsdpv1 ();
 }
 
-#if defined (__i386__) || defined (__x86_64__)
+#if defined (__i386__) && !defined (GRUB_MACHINE_EFI)
 
 static inline int
 iszero (grub_uint8_t *reg, int size)
@@ -741,7 +741,7 @@ grub_cmd_acpi (struct grub_extcmd_context *ctxt, int argc, char **args)
     }
   acpi_tables = 0;
 
-#if defined (__i386__) || defined (__x86_64__)
+#if defined (__i386__) && !defined (GRUB_MACHINE_EFI)
   if (! state[9].set)
     {
       grub_err_t err;
-- 
tg: (007f0b4..) u/acpi-skip-ebda-on-efi (depends on: master)

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2017-04-04 18:18 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [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
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

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.