From patchwork Fri Apr 21 14:24: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: 753449 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 3w8dWX3jWlz9s4s for ; Sat, 22 Apr 2017 00:33:12 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="UtcZjqi3"; dkim-atps=neutral Received: by lists.denx.de (Postfix, from userid 105) id 11F90C21D59; Fri, 21 Apr 2017 14:22:11 +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_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 AAE93C21CE5; Fri, 21 Apr 2017 14:21:28 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id 13928C21CCC; Fri, 21 Apr 2017 14:21:18 +0000 (UTC) Received: from mail-wr0-f194.google.com (mail-wr0-f194.google.com [209.85.128.194]) by lists.denx.de (Postfix) with ESMTPS id C379EC21CFF for ; Fri, 21 Apr 2017 14:21:13 +0000 (UTC) Received: by mail-wr0-f194.google.com with SMTP id 6so8170202wra.1 for ; Fri, 21 Apr 2017 07:21:13 -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=S/ck1gONYaDKdSagcF+EPSt59+HxKl/d13XoDMSSTgY=; b=UtcZjqi3+LkGfaCTVjy8UqA37Mx/MHOn5NPSTxbOhdNxKEthmlgoFdej0WS/tQ/YcG 9+Hhg5fX1lt31BUIV6ymu2v6mrT/MAJxEqUTzv6Tc1cXMKAPunoDR2jj/Ff+uHqfWHIW Tl743ha5ALZ1zKwGr/107n4keQQyOYIDRsvM3AQZxE3sOoSTDEVdRbnM36CMcoPz/zK3 uLCMwgwR7MPlojBcyonot9TN4g4WMPFMs4Fp4NYzFtid6CC9N5Ph91PrlWG87skFooaa lqFAXdr78EDTRXrWkYrq9YboBBQFZghW099smFXioW2PfpZ5dBokMT9LYHRXPhrmbDOp r6SQ== 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=S/ck1gONYaDKdSagcF+EPSt59+HxKl/d13XoDMSSTgY=; b=CS1zTOnI6QmiM4MeX2Y//cvmMw2PTv7X2mahCpTQ4XoR69SUhvFnI4y6nYOBlEScko mcbhVsaj2U/Q5SzFjsIZBaPV3TovbIxcqAk5oYYK6Swf7eRW0AUfcNDbspz74MsfmrsT 2pvt4+tBqUWagIzi9FWv7Oc8e7/yRIR1fspsE9Aa+g54fhIV5epxB+NVIpBBvm/GnHam cTlBUDnQkWgA5UTLI3O/5tGb699sWKPBsUJOUAg86b7nJRNJZj18hoo7y+YqeTz6pFI8 vvWWCogoPekD2c4zy53PPXuu+8SVKjF93YgPMonUJEzISNjfLmxQFgPDA/wA5OSD0aU/ 9eHg== X-Gm-Message-State: AN3rC/4DaGy3bLT9yjJbJCQArNzSgUnoG5R0C9TiwhurTlUOoMzBqKHx bSPkmXztTw7SaA== X-Received: by 10.223.151.6 with SMTP id r6mr7055987wrb.189.1492784473393; Fri, 21 Apr 2017 07:21:13 -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 4sm464843edt.64.2017.04.21.07.21.11 (version=TLS1_1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 21 Apr 2017 07:21:12 -0700 (PDT) From: Bin Meng To: Simon Glass , Stefan Roese , U-Boot Mailing List Date: Fri, 21 Apr 2017 07:24:36 -0700 Message-Id: <1492784689-15701-10-git-send-email-bmeng.cn@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1492784689-15701-1-git-send-email-bmeng.cn@gmail.com> References: <1492784689-15701-1-git-send-email-bmeng.cn@gmail.com> Subject: [U-Boot] [PATCH v2 09/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 Reviewed-by: Simon Glass --- Changes in v2: - add a function comment block for acpi_find_wakeup_vector() arch/x86/include/asm/acpi_table.h | 10 ++++++ arch/x86/include/asm/tables.h | 1 + arch/x86/lib/acpi_table.c | 72 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) diff --git a/arch/x86/include/asm/acpi_table.h b/arch/x86/include/asm/acpi_table.h index bbd80a1..20b906c 100644 --- a/arch/x86/include/asm/acpi_table.h +++ b/arch/x86/include/asm/acpi_table.h @@ -317,3 +317,13 @@ 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); + +/** + * acpi_find_wakeup_vector() - find OS installed wake up vector address + * + * This routine parses the ACPI table to locate the wake up vector installed + * by the OS previously. + * + * @return: wake up vector address installed by the OS + */ +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; +}