From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1XdLwt-0005bI-Vb for mharc-grub-devel@gnu.org; Sun, 12 Oct 2014 12:24:47 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57610) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XdLwm-0005Zs-Tx for grub-devel@gnu.org; Sun, 12 Oct 2014 12:24:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XdLwh-0006dP-Gf for grub-devel@gnu.org; Sun, 12 Oct 2014 12:24:40 -0400 Received: from mail-la0-x236.google.com ([2a00:1450:4010:c03::236]:35924) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XdLwg-0006d7-Sr for grub-devel@gnu.org; Sun, 12 Oct 2014 12:24:35 -0400 Received: by mail-la0-f54.google.com with SMTP id gm9so5420244lab.41 for ; Sun, 12 Oct 2014 09:24:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=date:from:to:cc:subject:message-id:in-reply-to:references :mime-version:content-type; bh=1fsIq4bLzA/Au13Yj9y0T6CP5jvm6/YJyuDVG9lQuV8=; b=g+iVKpekgKhX5UM5ZjjvLll7FKCwurJYuNcRd5yS+iFArbhKvrk9Tg/o3JJc+Y98sy XMTvH92wU/diUXQAUq3TytKninZbGNhqa1HneLEtMZacHgfcUK3HBIFKoEEtD9mVk8eJ e/LbU4E0eEDliZseka9wk84CTf0hzyzLs9kFflcJaB8TFycgTmV8wZUb2APZFii2To5u O33Ab1YjfbEqG0Myl82jF6P33azH4pFKeZoNsopTwhIQWncvjze1VWYlJJM/uWLM4Qom N9GEP5ckRuN5aAe7xPs0PQEGqjYfCbHqDsRJKY2XqYQ9ix2UcL6qbM/BfxsEV1tjJgEm IVrA== X-Received: by 10.112.62.200 with SMTP id a8mr18339306lbs.34.1413131073362; Sun, 12 Oct 2014 09:24:33 -0700 (PDT) Received: from opensuse.site (ppp94-29-94-89.pppoe.spdop.ru. [94.29.94.89]) by mx.google.com with ESMTPSA id h1sm3109272lam.5.2014.10.12.09.24.27 for (version=SSLv3 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Sun, 12 Oct 2014 09:24:32 -0700 (PDT) Date: Sun, 12 Oct 2014 20:24:25 +0400 From: Andrei Borzenkov To: Andrei Borzenkov Subject: Re: How can I submit patch for bug #42944 ? Message-ID: <20141012202425.1f4673e0@opensuse.site> In-Reply-To: <20141011125829.1c9f737d@opensuse.site> References: <1695065850.111988.1412959479763.JavaMail.yahoo@jws100192.mail.ne1.yahoo.com> <20141010212345.GA23552@riva.ucam.org> <5438EDE4.9070502@gmail.com> <20141011125829.1c9f737d@opensuse.site> X-Mailer: Claws Mail 3.9.2 (GTK+ 2.24.23; x86_64-suse-linux-gnu) Mime-Version: 1.0 Content-Type: multipart/signed; micalg=PGP-SHA1; boundary="Sig_/NqDav+DoBcBLe9xwBax4Zwx"; protocol="application/pgp-signature" X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4010:c03::236 Cc: The development of GNU GRUB , phcoder@gmail.com X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Oct 2014 16:24:45 -0000 --Sig_/NqDav+DoBcBLe9xwBax4Zwx Content-Type: multipart/mixed; boundary="MP_/TqKBXY1pT2P04aik=lhzV=X" --MP_/TqKBXY1pT2P04aik=lhzV=X Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline =D0=92 Sat, 11 Oct 2014 12:58:29 +0400 Andrei Borzenkov =D0=BF=D0=B8=D1=88=D0=B5=D1=82: > =D0=92 Sat, 11 Oct 2014 10:44:20 +0200 > Vladimir '=CF=86-coder/phcoder' Serbinenko =D0=BF=D0= =B8=D1=88=D0=B5=D1=82: >=20 > > On 10.10.2014 23:23, Colin Watson wrote: > > > On Fri, Oct 10, 2014 at 04:44:39PM +0000, Rigoberto Corujo wrote: > > >> I attached a patch to bug #42944 and would like to know how I would = go about getting it committed to the source tree? > > >> https://savannah.gnu.org/bugs/?42944 > > >=20 > > > I'd suggest attaching the patch to a mail here (not encased in a zip > > > file). It's usually easier to get public review that way. > > >=20 > > I don't like to use EFI timers if we can avoid them, they've been known > > to hang. Attached is a patch to use pmtimer for calibration >=20 > What about systems without ACPI? Does it explicitly exclude them? OK, I stay corrected. Still, this patch adds over 1K to kernel on i386-pc and about 0.5K to common core.img with ext2: -rw-r--r-- 1 bor bor 26848 Oct 12 20:09 /tmp/core.img-pmtimer -rw-r--r-- 1 bor bor 26320 Oct 12 18:50 /tmp/core.img-vanilla -rwxr-xr-x 1 bor bor 29224 Oct 12 20:08 /tmp/kernel.img-pmtimer -rwxr-xr-x 1 bor bor 28060 Oct 12 10:12 /tmp/kernel.img-vanilla I think it's too much for something that so far is needed only on very specific platform. May be we could restrict it to EFI only where size does not matter that much? Attached rebased patch (I briefly checked and it still boots on i386-pc and apparently correctly handles timeouts, but I cannot check other platforms). --MP_/TqKBXY1pT2P04aik=lhzV=X Content-Type: text/x-patch Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename=pmtimer_tsc_master.diff From: Andrei Borzenkov Subject: [PATCH] e/pmtimer --- grub-core/Makefile.am | 6 ++ grub-core/Makefile.core.def | 13 +++-- grub-core/commands/acpi.c | 12 ---- grub-core/commands/acpihalt.c | 66 ++++++--------------- grub-core/commands/efi/acpi.c | 59 ------------------- grub-core/commands/i386/pc/acpi.c | 81 -------------------------- grub-core/kern/acpi.c | 119 ++++++++++++++++++++++++++++++++++= ++++ grub-core/kern/efi/acpi.c | 59 +++++++++++++++++++ grub-core/kern/i386/pc/acpi.c | 81 ++++++++++++++++++++++++++ grub-core/kern/i386/tsc.c | 43 +++++++++++++- include/grub/acpi.h | 31 ++++++++-- 11 files changed, 361 insertions(+), 209 deletions(-) diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am index 5c087c8..da18dc5 100644 --- a/grub-core/Makefile.am +++ b/grub-core/Makefile.am @@ -93,6 +93,7 @@ KERNEL_HEADER_FILES +=3D $(top_builddir)/include/grub/mac= hine/kernel.h KERNEL_HEADER_FILES +=3D $(top_builddir)/include/grub/machine/pxe.h KERNEL_HEADER_FILES +=3D $(top_builddir)/include/grub/machine/int.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/acpi.h endif =20 if COND_i386_efi @@ -100,6 +101,7 @@ KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/efi= /efi.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/i386/tsc.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/acpi.h endif =20 if COND_i386_coreboot @@ -110,10 +112,12 @@ KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/v= ideo_fb.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/gfxterm.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/font.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/bufio.h +KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/acpi.h endif =20 if COND_i386_multiboot KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/i386/tsc.h +KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/acpi.h endif =20 if COND_i386_qemu @@ -152,11 +156,13 @@ KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/e= fi/efi.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/efi/disk.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/i386/tsc.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/pci.h +KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/acpi.h endif =20 if COND_ia64_efi KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/efi/efi.h KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/efi/disk.h +KERNEL_HEADER_FILES +=3D $(top_srcdir)/include/grub/acpi.h endif =20 if COND_mips diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def index 42443bc..27ee48a 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def @@ -173,9 +173,18 @@ kernel =3D { efi =3D kern/efi/init.c; efi =3D kern/efi/mm.c; efi =3D term/efi/console.c; + efi =3D kern/efi/acpi.c; =20 x86 =3D kern/i386/tsc.c; =20 + efi =3D kern/acpi.c; + i386_coreboot =3D kern/acpi.c; + i386_multiboot =3D kern/acpi.c; + i386_pc =3D kern/acpi.c; + i386_pc =3D kern/i386/pc/acpi.c; + i386_coreboot =3D kern/i386/pc/acpi.c; + i386_multiboot =3D kern/i386/pc/acpi.c; + i386_efi =3D kern/i386/efi/init.c; i386_efi =3D bus/pci.c; =20 @@ -683,10 +692,6 @@ module =3D { name =3D acpi; =20 common =3D commands/acpi.c; - efi =3D commands/efi/acpi.c; - i386_pc =3D commands/i386/pc/acpi.c; - i386_coreboot =3D commands/i386/pc/acpi.c; - i386_multiboot =3D commands/i386/pc/acpi.c; =20 enable =3D efi; enable =3D i386_pc; diff --git a/grub-core/commands/acpi.c b/grub-core/commands/acpi.c index 97c2cf2..2aaa202 100644 --- a/grub-core/commands/acpi.c +++ b/grub-core/commands/acpi.c @@ -61,18 +61,6 @@ static const struct grub_arg_option options[] =3D { {0, 0, 0, 0, 0, 0} }; =20 -/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */ -grub_uint8_t -grub_byte_checksum (void *base, grub_size_t size) -{ - grub_uint8_t *ptr; - grub_uint8_t ret =3D 0; - for (ptr =3D (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size; - ptr++) - ret +=3D *ptr; - return ret; -} - /* rev1 is 1 if ACPIv1 is to be generated, 0 otherwise. rev2 contains the revision of ACPIv2+ to generate or 0 if none. */ static int rev1, rev2; diff --git a/grub-core/commands/acpihalt.c b/grub-core/commands/acpihalt.c index da68b5b..576e2bb 100644 --- a/grub-core/commands/acpihalt.c +++ b/grub-core/commands/acpihalt.c @@ -385,63 +385,35 @@ main (int argc, char **argv) void grub_acpi_halt (void) { - struct grub_acpi_rsdp_v20 *rsdp2; - struct grub_acpi_rsdp_v10 *rsdp1; - struct grub_acpi_table_header *rsdt; - grub_uint32_t *entry_ptr; - grub_uint32_t port =3D 0; + struct grub_acpi_fadt *fadt; + grub_uint32_t port; + struct grub_acpi_table_header *dsdt; int sleep_type =3D -1; =20 - rsdp2 =3D grub_acpi_get_rsdpv2 (); - if (rsdp2) - rsdp1 =3D &(rsdp2->rsdpv1); - else - rsdp1 =3D grub_acpi_get_rsdpv1 (); - grub_dprintf ("acpi", "rsdp1=3D%p\n", rsdp1); - if (!rsdp1) + fadt =3D grub_acpi_find_fadt (); + if (!fadt) return; =20 - rsdt =3D (struct grub_acpi_table_header *) (grub_addr_t) rsdp1->rsdt_add= r; - for (entry_ptr =3D (grub_uint32_t *) (rsdt + 1); - entry_ptr < (grub_uint32_t *) (((grub_uint8_t *) rsdt) - + rsdt->length); - entry_ptr++) - { - if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "FACP", 4) =3D= =3D 0) - { - struct grub_acpi_fadt *fadt - =3D ((struct grub_acpi_fadt *) (grub_addr_t) *entry_ptr); - struct grub_acpi_table_header *dsdt - =3D (struct grub_acpi_table_header *) (grub_addr_t) fadt->dsdt_addr; - grub_uint8_t *buf =3D (grub_uint8_t *) dsdt; + dsdt =3D (struct grub_acpi_table_header *) (grub_addr_t) fadt->dsdt_addr; + port =3D fadt->pm1a; =20 - port =3D fadt->pm1a; + grub_dprintf ("acpi", "PM1a port=3D%x\n", port); =20 - grub_dprintf ("acpi", "PM1a port=3D%x\n", port); + if (grub_memcmp (dsdt->signature, "DSDT", + sizeof (dsdt->signature)) !=3D 0) + return; =20 - if (grub_memcmp (dsdt->signature, "DSDT", - sizeof (dsdt->signature)) =3D=3D 0 - && sleep_type < 0) - sleep_type =3D get_sleep_type (buf, NULL, buf + dsdt->length, - NULL, 0); - } - else if (grub_memcmp ((void *) (grub_addr_t) *entry_ptr, "SSDT", 4) = =3D=3D 0 - && sleep_type < 0) - { - struct grub_acpi_table_header *ssdt - =3D (struct grub_acpi_table_header *) (grub_addr_t) *entry_ptr; - grub_uint8_t *buf =3D (grub_uint8_t *) ssdt; + sleep_type =3D get_sleep_type ((grub_uint8_t *) dsdt, 0, + (grub_uint8_t *) dsdt + dsdt->length, 0, 0); =20 - grub_dprintf ("acpi", "SSDT =3D %p\n", ssdt); + if (sleep_type < 0 || sleep_type >=3D 8) + return; =20 - sleep_type =3D get_sleep_type (buf, NULL, buf + ssdt->length, NULL, 0); - } - } + grub_dprintf ("acpi", "SLP_TYP =3D %d, port =3D 0x%x\n", + sleep_type, port); =20 - grub_dprintf ("acpi", "SLP_TYP =3D %d, port =3D 0x%x\n", sleep_type, por= t); - if (port && sleep_type >=3D 0 && sleep_type < 8) - grub_outw (GRUB_ACPI_SLP_EN | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), - port & 0xffff); + grub_outw (GRUB_ACPI_SLP_EN + | (sleep_type << GRUB_ACPI_SLP_TYP_OFFSET), port & 0xffff); =20 grub_millisleep (1500); =20 diff --git a/grub-core/commands/efi/acpi.c b/grub-core/commands/efi/acpi.c deleted file mode 100644 index 74f8cd1..0000000 --- a/grub-core/commands/efi/acpi.c +++ /dev/null @@ -1,59 +0,0 @@ -/* acpi.c - get acpi tables. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include -#include -#include - -struct grub_acpi_rsdp_v10 * -grub_machine_acpi_get_rsdpv1 (void) -{ - unsigned i; - static grub_efi_packed_guid_t acpi_guid =3D GRUB_EFI_ACPI_TABLE_GUID; - - for (i =3D 0; i < grub_efi_system_table->num_table_entries; i++) - { - grub_efi_packed_guid_t *guid =3D - &grub_efi_system_table->configuration_table[i].vendor_guid; - - if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_packed_guid_t)= )) - return (struct grub_acpi_rsdp_v10 *) - grub_efi_system_table->configuration_table[i].vendor_table; - } - return 0; -} - -struct grub_acpi_rsdp_v20 * -grub_machine_acpi_get_rsdpv2 (void) -{ - unsigned i; - static grub_efi_packed_guid_t acpi20_guid =3D GRUB_EFI_ACPI_20_TABLE_GUI= D; - - for (i =3D 0; i < grub_efi_system_table->num_table_entries; i++) - { - grub_efi_packed_guid_t *guid =3D - &grub_efi_system_table->configuration_table[i].vendor_guid; - - if (! grub_memcmp (guid, &acpi20_guid, sizeof (grub_efi_packed_guid_= t))) - return (struct grub_acpi_rsdp_v20 *) - grub_efi_system_table->configuration_table[i].vendor_table; - } - return 0; -} diff --git a/grub-core/commands/i386/pc/acpi.c b/grub-core/commands/i386/pc= /acpi.c deleted file mode 100644 index d415d23..0000000 --- a/grub-core/commands/i386/pc/acpi.c +++ /dev/null @@ -1,81 +0,0 @@ -/* acpi.c - get acpi tables. */ -/* - * GRUB -- GRand Unified Bootloader - * Copyright (C) 2009 Free Software Foundation, Inc. - * - * GRUB is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * GRUB is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ - -#include -#include - -struct grub_acpi_rsdp_v10 * -grub_machine_acpi_get_rsdpv1 (void) -{ - int ebda_len; - grub_uint8_t *ebda, *ptr; - - grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); - ebda =3D (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); - ebda_len =3D * (grub_uint16_t *) ebda; - if (! ebda_len) - return 0; - for (ptr =3D ebda; ptr < ebda + 0x400; ptr +=3D 16) - if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 - && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 - && ((struct grub_acpi_rsdp_v10 *) ptr)->revision =3D=3D 0) - return (struct grub_acpi_rsdp_v10 *) ptr; - - grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); - for (ptr =3D (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; - ptr +=3D 16) - if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 - && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 - && ((struct grub_acpi_rsdp_v10 *) ptr)->revision =3D=3D 0) - return (struct grub_acpi_rsdp_v10 *) ptr; - return 0; -} - -struct grub_acpi_rsdp_v20 * -grub_machine_acpi_get_rsdpv2 (void) -{ - int ebda_len; - grub_uint8_t *ebda, *ptr; - - grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); - ebda =3D (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); - ebda_len =3D * (grub_uint16_t *) ebda; - if (! ebda_len) - return 0; - for (ptr =3D ebda; ptr < ebda + 0x400; ptr +=3D 16) - if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 - && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 - && ((struct grub_acpi_rsdp_v10 *) ptr)->revision !=3D 0 - && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024 - && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length) - =3D=3D 0) - return (struct grub_acpi_rsdp_v20 *) ptr; - - grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); - for (ptr =3D (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; - ptr +=3D 16) - if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 - && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 - && ((struct grub_acpi_rsdp_v10 *) ptr)->revision !=3D 0 - && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024 - && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length) - =3D=3D 0) - return (struct grub_acpi_rsdp_v20 *) ptr; - return 0; -} diff --git a/grub-core/kern/acpi.c b/grub-core/kern/acpi.c new file mode 100644 index 0000000..5292597 --- /dev/null +++ b/grub-core/kern/acpi.c @@ -0,0 +1,119 @@ +/*=20 + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2012 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +static void * +grub_acpi_rsdt_find_table (struct grub_acpi_table_header *rsdt, const char= *sig) +{ + grub_size_t s; + grub_uint32_t *ptr; + + if (!rsdt) + return 0; + + if (grub_memcmp (rsdt->signature, "RSDT", 4) !=3D 0) + return 0; + + ptr =3D (grub_uint32_t *) (rsdt + 1); + s =3D (rsdt->length - sizeof (*rsdt)) / sizeof (grub_uint32_t); + for (; s; s--, ptr++) + { + struct grub_acpi_table_header *tbl; + tbl =3D (struct grub_acpi_table_header *) (grub_addr_t) *ptr; + if (grub_memcmp (tbl->signature, sig, 4) =3D=3D 0) + return tbl; + } + return 0; +} + +static void * +grub_acpi_xsdt_find_table (struct grub_acpi_table_header *xsdt, const char= *sig) +{ + grub_size_t s; + grub_uint64_t *ptr; + + if (!xsdt) + return 0; + + if (grub_memcmp (xsdt->signature, "XSDT", 4) !=3D 0) + return 0; + + ptr =3D (grub_uint64_t *) (xsdt + 1); + s =3D (xsdt->length - sizeof (*xsdt)) / sizeof (grub_uint32_t); + for (; s; s--, ptr++) + { + struct grub_acpi_table_header *tbl; +#if GRUB_CPU_SIZEOF_VOID_P !=3D 8 + if (*ptr >> 32) + continue; +#endif + tbl =3D (struct grub_acpi_table_header *) (grub_addr_t) *ptr; + if (grub_memcmp (tbl->signature, sig, 4) =3D=3D 0) + return tbl; + } + return 0; +} + +struct grub_acpi_fadt * +grub_acpi_find_fadt (void) +{ + struct grub_acpi_fadt *fadt =3D 0; + struct grub_acpi_rsdp_v10 *rsdpv1; + struct grub_acpi_rsdp_v20 *rsdpv2; + rsdpv1 =3D grub_machine_acpi_get_rsdpv1 (); + if (rsdpv1) + fadt =3D grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) + (grub_addr_t) rsdpv1->rsdt_addr, + GRUB_ACPI_FADT_SIGNATURE); + if (fadt) + return fadt; + rsdpv2 =3D grub_machine_acpi_get_rsdpv2 (); + if (rsdpv2) + fadt =3D grub_acpi_rsdt_find_table ((struct grub_acpi_table_header *) + (grub_addr_t) rsdpv2->rsdpv1.rsdt_addr, + GRUB_ACPI_FADT_SIGNATURE); + if (fadt) + return fadt; + if (rsdpv2 +#if GRUB_CPU_SIZEOF_VOID_P !=3D 8 + && !(rsdpv2->xsdt_addr >> 32) +#endif + ) + fadt =3D grub_acpi_xsdt_find_table ((struct grub_acpi_table_header *) + (grub_addr_t) rsdpv2->xsdt_addr, + GRUB_ACPI_FADT_SIGNATURE); + if (fadt) + return fadt; + return 0; +} + +/* Simple checksum by summing all bytes. Used by ACPI and SMBIOS. */ +grub_uint8_t +grub_byte_checksum (void *base, grub_size_t size) +{ + grub_uint8_t *ptr; + grub_uint8_t ret =3D 0; + for (ptr =3D (grub_uint8_t *) base; ptr < ((grub_uint8_t *) base) + size; + ptr++) + ret +=3D *ptr; + return ret; +} diff --git a/grub-core/kern/efi/acpi.c b/grub-core/kern/efi/acpi.c new file mode 100644 index 0000000..74f8cd1 --- /dev/null +++ b/grub-core/kern/efi/acpi.c @@ -0,0 +1,59 @@ +/* acpi.c - get acpi tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include +#include + +struct grub_acpi_rsdp_v10 * +grub_machine_acpi_get_rsdpv1 (void) +{ + unsigned i; + static grub_efi_packed_guid_t acpi_guid =3D GRUB_EFI_ACPI_TABLE_GUID; + + for (i =3D 0; i < grub_efi_system_table->num_table_entries; i++) + { + grub_efi_packed_guid_t *guid =3D + &grub_efi_system_table->configuration_table[i].vendor_guid; + + if (! grub_memcmp (guid, &acpi_guid, sizeof (grub_efi_packed_guid_t)= )) + return (struct grub_acpi_rsdp_v10 *) + grub_efi_system_table->configuration_table[i].vendor_table; + } + return 0; +} + +struct grub_acpi_rsdp_v20 * +grub_machine_acpi_get_rsdpv2 (void) +{ + unsigned i; + static grub_efi_packed_guid_t acpi20_guid =3D GRUB_EFI_ACPI_20_TABLE_GUI= D; + + for (i =3D 0; i < grub_efi_system_table->num_table_entries; i++) + { + grub_efi_packed_guid_t *guid =3D + &grub_efi_system_table->configuration_table[i].vendor_guid; + + if (! grub_memcmp (guid, &acpi20_guid, sizeof (grub_efi_packed_guid_= t))) + return (struct grub_acpi_rsdp_v20 *) + grub_efi_system_table->configuration_table[i].vendor_table; + } + return 0; +} diff --git a/grub-core/kern/i386/pc/acpi.c b/grub-core/kern/i386/pc/acpi.c new file mode 100644 index 0000000..d415d23 --- /dev/null +++ b/grub-core/kern/i386/pc/acpi.c @@ -0,0 +1,81 @@ +/* acpi.c - get acpi tables. */ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include + +struct grub_acpi_rsdp_v10 * +grub_machine_acpi_get_rsdpv1 (void) +{ + int ebda_len; + grub_uint8_t *ebda, *ptr; + + grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); + ebda =3D (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); + ebda_len =3D * (grub_uint16_t *) ebda; + if (! ebda_len) + return 0; + for (ptr =3D ebda; ptr < ebda + 0x400; ptr +=3D 16) + if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision =3D=3D 0) + return (struct grub_acpi_rsdp_v10 *) ptr; + + grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); + for (ptr =3D (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; + ptr +=3D 16) + if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision =3D=3D 0) + return (struct grub_acpi_rsdp_v10 *) ptr; + return 0; +} + +struct grub_acpi_rsdp_v20 * +grub_machine_acpi_get_rsdpv2 (void) +{ + int ebda_len; + grub_uint8_t *ebda, *ptr; + + grub_dprintf ("acpi", "Looking for RSDP. Scanning EBDA\n"); + ebda =3D (grub_uint8_t *) ((* ((grub_uint16_t *) 0x40e)) << 4); + ebda_len =3D * (grub_uint16_t *) ebda; + if (! ebda_len) + return 0; + for (ptr =3D ebda; ptr < ebda + 0x400; ptr +=3D 16) + if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision !=3D 0 + && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024 + && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length) + =3D=3D 0) + return (struct grub_acpi_rsdp_v20 *) ptr; + + grub_dprintf ("acpi", "Looking for RSDP. Scanning BIOS\n"); + for (ptr =3D (grub_uint8_t *) 0xe0000; ptr < (grub_uint8_t *) 0x100000; + ptr +=3D 16) + if (grub_memcmp (ptr, GRUB_RSDP_SIGNATURE, GRUB_RSDP_SIGNATURE_SIZE) = =3D=3D 0 + && grub_byte_checksum (ptr, sizeof (struct grub_acpi_rsdp_v10)) =3D=3D 0 + && ((struct grub_acpi_rsdp_v10 *) ptr)->revision !=3D 0 + && ((struct grub_acpi_rsdp_v20 *) ptr)->length < 1024 + && grub_byte_checksum (ptr, ((struct grub_acpi_rsdp_v20 *) ptr)->length) + =3D=3D 0) + return (struct grub_acpi_rsdp_v20 *) ptr; + return 0; +} diff --git a/grub-core/kern/i386/tsc.c b/grub-core/kern/i386/tsc.c index 3a4cae6..91bcb52 100644 --- a/grub-core/kern/i386/tsc.c +++ b/grub-core/kern/i386/tsc.c @@ -1,6 +1,6 @@ /* kern/i386/tsc.c - x86 TSC time source implementation * Requires Pentium or better x86 CPU that supports the RDTSC instruction. - * This module uses the RTC (via grub_get_rtc()) to calibrate the TSC to + * This module uses the PIT to calibrate the TSC to * real time. * * GRUB -- GRand Unified Bootloader @@ -31,6 +31,7 @@ #include #endif #include +#include =20 /* This defines the value TSC had at the epoch (that is, when we calibrate= d it). */ static grub_uint64_t tsc_boot_time; @@ -111,6 +112,43 @@ grub_tsc_get_time_ms (void) } =20 #ifndef GRUB_MACHINE_XEN +static int +grub_pmtimer_tsc_calibrate (void) +{ + grub_uint32_t start; + grub_uint32_t last; + grub_uint32_t cur, end; + struct grub_acpi_fadt *fadt; + grub_port_t p; + grub_uint64_t end_tsc; + + fadt =3D grub_acpi_find_fadt (); + if (!fadt) + return 0; + p =3D fadt->pmtimer; + if (!p) + return 0; + + start =3D grub_inl (p) & 0xffffff; + last =3D start; + /* It's 3.579545 MHz clock. Wait 1 ms. */ + end =3D start + 3580; + tsc_boot_time =3D grub_get_tsc (); + while (1) + { + cur =3D grub_inl (p) & 0xffffff; + if (cur < last) + cur |=3D 0x1000000; + if (cur >=3D end) + { + end_tsc =3D grub_get_tsc (); + grub_tsc_rate =3D grub_divmod64 (1ULL<<32, end_tsc - tsc_boot_tim= e, 0); + grub_printf ("synced on PM\n"); + return 1; + } + } +} + /* Calibrate the TSC based on the RTC. */ static void calibrate_tsc (void) @@ -118,6 +156,9 @@ calibrate_tsc (void) /* First calibrate the TSC rate (relative, not absolute time). */ grub_uint64_t end_tsc; =20 + if (grub_pmtimer_tsc_calibrate ()) + return; + tsc_boot_time =3D grub_get_tsc (); grub_pit_wait (0xffff); end_tsc =3D grub_get_tsc (); diff --git a/include/grub/acpi.h b/include/grub/acpi.h index f6e6a11..fc189c2 100644 --- a/include/grub/acpi.h +++ b/include/grub/acpi.h @@ -63,16 +63,34 @@ struct grub_acpi_table_header struct grub_acpi_fadt { struct grub_acpi_table_header hdr; + /* 36 */ grub_uint32_t facs_addr; grub_uint32_t dsdt_addr; + /* 44 */ grub_uint8_t somefields1[20]; + /* 64 */ grub_uint32_t pm1a; - grub_uint8_t somefields2[64]; + /* 68 */ + grub_uint8_t somefields2[8]; + /* 76 */ + grub_uint32_t pmtimer; + /* 80 */ + grub_uint8_t somefields3[32]; + /* 112 */ + grub_uint32_t flags; + /* 116 */ + grub_uint8_t somefields4[16]; + /* 132 */ grub_uint64_t facs_xaddr; grub_uint64_t dsdt_xaddr; - grub_uint8_t somefields3[96]; + grub_uint8_t somefields5[96]; } GRUB_PACKED; =20 +enum + { + GRUB_ACPI_FADT_FLAGS_LONG_PMTIMER =3D (1 << 8) + }; + #define GRUB_ACPI_MADT_SIGNATURE "APIC" =20 struct grub_acpi_madt_entry_header @@ -176,9 +194,9 @@ 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_machine_acpi_get_rsdpv1 (void); -struct grub_acpi_rsdp_v20 *grub_machine_acpi_get_rsdpv2 (void); -grub_uint8_t grub_byte_checksum (void *base, grub_size_t size); +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= ); =20 grub_err_t grub_acpi_create_ebda (void); =20 @@ -234,4 +252,7 @@ enum GRUB_ACPI_EXTOPCODE_BANK_FIELD_OP =3D 0x87, }; =20 +struct grub_acpi_fadt * +EXPORT_FUNC(grub_acpi_find_fadt) (void); + #endif /* ! GRUB_ACPI_HEADER */ --=20 tg: (77063f4..) e/pmtimer (depends on: master) --MP_/TqKBXY1pT2P04aik=lhzV=X-- --Sig_/NqDav+DoBcBLe9xwBax4Zwx Content-Type: application/pgp-signature; name=signature.asc Content-Disposition: attachment; filename=signature.asc -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iEYEARECAAYFAlQ6qzoACgkQR6LMutpd94y0NQCgrxmjtO8j0TIfsX/Yb9eK3l14 YOcAoLuCrnyjLnz8XewQjqPoG9QGvOlu =p3+J -----END PGP SIGNATURE----- --Sig_/NqDav+DoBcBLe9xwBax4Zwx--