From patchwork Thu Mar 16 14:26:36 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 739864 X-Patchwork-Delegate: bmeng.cn@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 3vkWCY2wcvz9rvt for ; Fri, 17 Mar 2017 01:32:41 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Gm4Ksi/K"; dkim-atps=neutral Received: by lists.denx.de (Postfix, from userid 105) id 2C62EC21C27; Thu, 16 Mar 2017 14:24:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 2804BC21C79; Thu, 16 Mar 2017 14:22:49 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 4F970C21C3C; Thu, 16 Mar 2017 14:22:35 +0000 (UTC) Received: from mail-pf0-f195.google.com (mail-pf0-f195.google.com [209.85.192.195]) by lists.denx.de (Postfix) with ESMTPS id 7A0F7C21C6F for ; Thu, 16 Mar 2017 14:22:31 +0000 (UTC) Received: by mail-pf0-f195.google.com with SMTP id o126so5974342pfb.1 for ; Thu, 16 Mar 2017 07:22:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=t14tE7S2n7Qi9b16ZgrwycrGSkOoAyEZayP1ij3Zvk8=; b=Gm4Ksi/KNHdw0eNFy8XJR7ZtbKawzd/vdECEu46AurRy7GOCj9Ca7h2bkg7naxUr5X kh/glHPL9S72rJjh3FKB27Nc3Jhpm1yEgvWQRq24Q4L47PHQusue0uemfG/Y3afMtiX/ ThjYpRaW+iXvCjL2kkwt1HzvcN6lWpPRN/Gk+YoMPKb18g54jM0748REzb9u3TLCKtbo hE9CQd54aJWCNvaIeQVwJDqJ4C1aEHiDYiD2WJfDwKUyCmtO+AuNket5d1eSsgt4M14u uNs7/LsPLqgtybvmlYLuoCVV8ppynh80ERibGP+vOjFGSHgoK4TdsQEec7c2F4l+dcEd 2SyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=t14tE7S2n7Qi9b16ZgrwycrGSkOoAyEZayP1ij3Zvk8=; b=Ff/OhHYkK9llO2wDJt2yCfYdpC7Qr6ynti53ckS8xTbl7+PZlu5kjszko4/KPjMye7 z0wxv2fd4lhy6S7+GMGiRPzMARz5qH/hD3pXtjSsD3oVCrjNMbX12E1FlxEvNq9RBK8N vugZGu0II8afRApHQG5q2sKtVGihhZ8Pht/TpD3LRszo3qRO3YiA43DTf4Ws0HiceBf0 UnPoIbdXex5LY9JlNOKGeXkKzymtBpNh3/GcEE2nA6TCbPlfvkuFdPu8DCtQuKUVlOvS BPa1m2JF0TRN3l/f7bLYOwCzkA1Kx0cBu98JER6IvaS0p4y5QYvln6CpeqNXvSlmmtsA 12TA== X-Gm-Message-State: AFeK/H2QXD5b0Ok0KxQffXxpliJ1A7pNr7g7kcP59UXq43ygUkUQzFU8zfLD3OPoSdw6BA== X-Received: by 10.99.101.67 with SMTP id z64mr10562693pgb.78.1489674150126; Thu, 16 Mar 2017 07:22:30 -0700 (PDT) Received: from ala-d2121-lx1.wrs.com (unknown-157-139.windriver.com. [147.11.157.139]) by smtp.gmail.com with ESMTPSA id c64sm11039959pfa.45.2017.03.16.07.22.28 (version=TLS1_1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 16 Mar 2017 07:22:29 -0700 (PDT) From: Bin Meng To: Simon Glass , Stefan Roese , U-Boot Mailing List Date: Thu, 16 Mar 2017 07:26:36 -0700 Message-Id: <1489674408-17498-11-git-send-email-bmeng.cn@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1489674408-17498-1-git-send-email-bmeng.cn@gmail.com> References: <1489674408-17498-1-git-send-email-bmeng.cn@gmail.com> Subject: [U-Boot] [PATCH 10/22] x86: acpi: Add one API to find OS wakeup vector X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" This adds one API acpi_find_wakeup_vector() to locate OS wakeup vector from the ACPI FACS table, to be used in the S3 boot path. Signed-off-by: Bin Meng --- arch/x86/include/asm/acpi_table.h | 1 + arch/x86/include/asm/tables.h | 1 + arch/x86/lib/acpi_table.c | 72 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+) diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index bbd80a1..6cadd90 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -317,3 +317,4 @@ int acpi_create_madt_lapic_nmi(struct acpi_madt_lapic_nmi *lapic_nmi, u32 acpi_fill_madt(u32 current); void acpi_create_gnvs(struct acpi_global_nvs *gnvs); ulong write_acpi_tables(ulong start); +void *acpi_find_wakeup_vector(void); diff --git a/arch/x86/include/asm/tables.h b/arch/x86/include/asm/tables.h index d1b2388..9e8208b 100644 --- a/arch/x86/include/asm/tables.h +++ b/arch/x86/include/asm/tables.h @@ -15,6 +15,7 @@ * PIRQ routing table, Multi-Processor table and ACPI table. */ #define ROM_TABLE_ADDR 0xf0000 +#define ROM_TABLE_END 0xfffff #define ROM_TABLE_ALIGN 1024 diff --git a/arch/x86/lib/acpi_table.c b/arch/x86/lib/acpi_table.c index 355456d..f118345 100644 --- a/arch/x86/lib/acpi_table.c +++ b/arch/x86/lib/acpi_table.c @@ -438,3 +438,75 @@ ulong write_acpi_tables(ulong start) return current; } + +static struct acpi_rsdp *acpi_valid_rsdp(struct acpi_rsdp *rsdp) +{ + if (strncmp((char *)rsdp, RSDP_SIG, sizeof(RSDP_SIG) - 1) != 0) + return NULL; + + debug("Looking on %p for valid checksum\n", rsdp); + + if (table_compute_checksum((void *)rsdp, 20) != 0) + return NULL; + debug("acpi rsdp checksum 1 passed\n"); + + if ((rsdp->revision > 1) && + (table_compute_checksum((void *)rsdp, rsdp->length) != 0)) + return NULL; + debug("acpi rsdp checksum 2 passed\n"); + + return rsdp; +} + +void *acpi_find_wakeup_vector(void) +{ + char *p, *end; + struct acpi_rsdp *rsdp = NULL; + struct acpi_rsdt *rsdt; + struct acpi_fadt *fadt = NULL; + struct acpi_facs *facs; + void *wake_vec; + int i; + + debug("Trying to find the wakeup vector...\n"); + + /* Find RSDP */ + for (p = (char *)ROM_TABLE_ADDR; p < (char *)ROM_TABLE_END; p += 16) { + rsdp = acpi_valid_rsdp((struct acpi_rsdp *)p); + if (rsdp) + break; + } + + if (rsdp == NULL) + return NULL; + + debug("RSDP found at %p\n", rsdp); + rsdt = (struct acpi_rsdt *)rsdp->rsdt_address; + + end = (char *)rsdt + rsdt->header.length; + debug("RSDT found at %p ends at %p\n", rsdt, end); + + for (i = 0; ((char *)&rsdt->entry[i]) < end; i++) { + fadt = (struct acpi_fadt *)rsdt->entry[i]; + if (strncmp((char *)fadt, "FACP", 4) == 0) + break; + fadt = NULL; + } + + if (fadt == NULL) + return NULL; + + debug("FADT found at %p\n", fadt); + facs = (struct acpi_facs *)fadt->firmware_ctrl; + + if (facs == NULL) { + debug("No FACS found, wake up from S3 not possible.\n"); + return NULL; + } + + debug("FACS found at %p\n", facs); + wake_vec = (void *)facs->firmware_waking_vector; + debug("OS waking vector is %p\n", wake_vec); + + return wake_vec; +}