From nobody Thu Jan 30 22:33:44 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) client-ip=78.46.105.101; envelope-from=seabios-bounces@seabios.org; helo=coreboot.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of seabios.org designates 78.46.105.101 as permitted sender) smtp.mailfrom=seabios-bounces@seabios.org; dmarc=fail(p=none dis=none) header.from=gmail.com Return-Path: Received: from coreboot.org (78.46.105.101 [78.46.105.101]) by mx.zohomail.com with SMTPS id 1737532003187964.2809135407743; Tue, 21 Jan 2025 23:46:43 -0800 (PST) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTPA id 173ED2150E; Wed, 22 Jan 2025 07:46:37 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) by coreboot.org (Postfix) with ESMTP id 17A6520785 for ; Wed, 22 Jan 2025 07:46:22 +0000 (UTC) Received: from authenticated-user (PRIMARY_HOSTNAME [PUBLIC_IP]) for ; Tue, 21 Jan 2025 23:46:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1737531980; x=1738136780; darn=seabios.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=70PZtTcBmqZZ/6FmoFnVvEiMSa1Pab9Z4m0eesTc5LY=; b=HFB++qXOoDG+e5aPB8k5tXLHMObhcdGoLZYjZCw4LAuxvjbJsHzAToCLSTiaHoWnTw g0ZX0iJn1y9O6T6wrb5581DDGUm00Adm0BGpgSWd7wfYUp0jtABbk/6iLcpZxAiwsH1r dqHF+OlS5gQ7xgmA3NPNKQdHPCm/GevdsLQ6Hxr6zahUe6TXldzZqx2B5R+/5WLeRaCJ 3MFqrjaUexwM3Wupd1KtVr9+YPMrlTKa1PqVBKBYcPmu6p8WvZ26MFtsysjLenRejexD 0CbsRsQjbjilSIxoZaj5hITi8yGsa4U7nlGOVtyXvaPwhC9ZA7v0eO/gORmnd88eDSHz 07dQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737531980; x=1738136780; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=70PZtTcBmqZZ/6FmoFnVvEiMSa1Pab9Z4m0eesTc5LY=; b=Q9Zb6sSMKhzrwsLOEDGJL5gu77F0+5B3S6cheNsOnewH8bISJ+Ixtz+YDqBJjggRN9 JoP0h1ANOSpWQPoRUgUGZDK2Jhj/tHucFGM+PDEgaHDqdvFmBhV2OqqiKX9tVI2D3iYK 9z/wfx1+2rW8TDA35i07LLlMjiv9Lc6WTEXcWHl9GTWqmzhUgzCFoqJD5IiRj+MgxR/m yrZdGWUisVEbtbuhx1PSDw2ILCq4vlb3iuJ+V6Egkn0oVbOalnzedaN6A6iER554Mj3P xlfmEdC2P55jaqNgp6cCbN1NUcBlsV8Ugt+Q1jkCwH286M/mgrIuxPE+VkwxI+3ZOCvu qZGA== X-Gm-Message-State: AOJu0YwcjDTHLKCP3ej3FYHxPk5c8DSKksgyMG8jMV2MVe69UQL32hvy vk9yzLVvb623vfx5wUc17eCimE9au4XNySonJ+sguasLcjgM8vqMUAEKqBQKSD4wQoe/nl86wKV DjDQyivt/pEo8d38OfZoxeVEPPH+2vbM3 X-Gm-Gg: ASbGnctWcWAPLsIxPq7B+6z9EOEXF5Wr2ZV/uVF0oivT666t+LEJq9HlKRpARPEWlfq ZH1o5wJD+GCqcO8ZseEUPyMIDZTEdx0PD8IZpv38onKLhb8eo7ro= X-Google-Smtp-Source: AGHT+IGI64tYUhQJHqFyZ47Mnvv45Ki3+v7igEF+xLhpWXtyOU7Bj9UMzVgbMOx4pKabuWtmaIiCHkg1C6EZ+RcSLrI= X-Received: by 2002:a05:6602:2c81:b0:847:4fc0:c6c3 with SMTP id ca18e2360f4ac-851b61cacbemr1788305839f.7.1737531980405; Tue, 21 Jan 2025 23:46:20 -0800 (PST) MIME-Version: 1.0 From: Timothy Kenno Handojo Date: Wed, 22 Jan 2025 14:46:09 +0700 X-Gm-Features: AbW1kvZj12PjM80NQlcNG8a7o_xNHdna_1ladiRtG0pYc7pyadEfkp5L7pHhVFE Message-ID: To: seabios@seabios.org Message-ID-Hash: MX4O5JGYNZ6KZBDKJ5JW2ICSBRY32YQW X-Message-ID-Hash: MX4O5JGYNZ6KZBDKJ5JW2ICSBRY32YQW X-MailFrom: kennohan@gmail.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-seabios.seabios.org-0; header-match-seabios.seabios.org-1; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.6b1 Precedence: list Subject: [SeaBIOS] [PATCH] NVRAM bootorder List-Id: SeaBIOS mailing list Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Content-Transfer-Encoding: quoted-printable Authentication-Results: coreboot.org; auth=pass smtp.auth=mailman@coreboot.org smtp.mailfrom=seabios-bounces@seabios.org X-Spamd-Bar: / X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1737532005316019000 Content-Type: text/plain; charset="utf-8" Revision from a previous patch. Sorry it took so long. This change allows seabios to load bootorder not only from CBFS but also from the NVRAM as well, making use of coreboot's cmos.layout. Tested on QEMU Q35 From 3aee65ff1a9d5926ff18fa0770362e59e8b52257 Mon Sep 17 00:00:00 2001 From: Timothy Kenno Handojo Date: Wed, 22 Jan 2025 14:40:18 +0700 Subject: [PATCH] boot: Allow setting bootorder from CMOS entry The original bootorder from CBFS remains, but takes lower priority. Signed-off-by: Timothy Kenno Handojo --- Makefile | 2 +- src/boot.c | 9 +++- src/nvram.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nvram.h | 46 +++++++++++++++++ 4 files changed, 199 insertions(+), 2 deletions(-) create mode 100644 src/nvram.c create mode 100644 src/nvram.h diff --git a/Makefile b/Makefile index d3341870..48f0b9ac 100644 --- a/Makefile +++ b/Makefile @@ -46,7 +46,7 @@ SRC32FLAT=3D$(SRCBOTH) post.c e820map.c malloc.c romfile.c x86.c \ fw/mtrr.c fw/xen.c fw/acpi.c fw/mptable.c fw/pirtable.c \ fw/smbios.c fw/romfile_loader.c fw/dsdt_parser.c hw/virtio-ring.c \ hw/virtio-pci.c hw/virtio-mmio.c hw/virtio-blk.c hw/virtio-scsi.c \ - hw/tpm_drivers.c hw/nvme.c sha256.c sha512.c + hw/tpm_drivers.c hw/nvme.c sha256.c sha512.c nvram.c SRC32SEG=3Dstring.c output.c pcibios.c apm.c stacks.c hw/pci.c hw/serialio.c DIRS=3Dsrc src/hw src/fw vgasrc diff --git a/src/boot.c b/src/boot.c index 5c37dafd..c5e102cf 100644 --- a/src/boot.c +++ b/src/boot.c @@ -21,6 +21,8 @@ #include "string.h" // memset #include "util.h" // irqtimer_calc #include "tcgbios.h" // tpm_* +#include "nvram.h" // get_nvram_bootorder + /**************************************************************** * Helper search functions @@ -250,8 +252,13 @@ loadBootOrder(void) { if (!CONFIG_BOOTORDER) return; + char *f =3D NULL; + + f =3D get_nvram_bootorder(); + + if (!f) + f =3D romfile_loadfile("bootorder", NULL); - char *f =3D romfile_loadfile("bootorder", NULL); if (!f) return; diff --git a/src/nvram.c b/src/nvram.c new file mode 100644 index 00000000..145a062d --- /dev/null +++ b/src/nvram.c @@ -0,0 +1,144 @@ +// Code to manipulate NVRAM configuration +// +// Copyright (C) 2024-2025 Timothy Kenno Handojo +// Taken and adapted from coreboot's libpayload +// +// This file may be distributed under the terms of the GNU LGPLv3 license. + +/* NOTE: +To avoid confusion, it is important to keep in mind that in this file, +the term CMOS does NOT refer to the RTC, but instead the NVRAM as a whole. +While this technically includes the RTC part, the main focus wouldn't be i= t, +and instead be the configurable parts (i.e. BIOS settings). +*/ + +#include "nvram.h" +#include "string.h" // memcmp, strlen +#include "malloc.h" // malloc_low +#include "x86.h" // inb, outb +#include "output.h" // dprintf +#include "util.h" // cb_header, find_cb_table, find_cb_subtable + +#define CB_TAG_CMOS_OPTION_TABLE 0x00c8 +#define CB_TAG_OPTION 0x00c9 +#define CB_TAG_OPTION_CHECKSUM 0x00cc + + +u8 nvram_read(u8 addr){ + u16 rtc_port =3D addr < 128 ? RTC_PORT_STANDARD : RTC_PORT_EXTENDED; + + outb(addr, rtc_port); + return inb(rtc_port + 1); +} + +void nvram_write(u8 val, u8 addr) +{ + u16 rtc_port =3D addr < 128 ? RTC_PORT_STANDARD : RTC_PORT_EXTENDED; + + outb(addr, rtc_port); + outb(val, rtc_port + 1); +} + +struct nvram_accessor { + u8 (*read)(u8 reg); + void (*write)(u8 val, u8 reg); +}; + +struct nvram_accessor *use_nvram =3D &(struct nvram_accessor) { + nvram_read, + nvram_write +}; + +static struct cb_cmos_entries *lookup_cmos_entry(struct cb_cmos_option_table *option_table, const char *name) +{ + struct cb_cmos_entries *cmos_entry, *next; + int len =3D name ? strlen(name) : 0; + + /* CMOS entries are located right after the option table */ + cmos_entry =3D (struct cb_cmos_entries*)((unsigned char *)option_table + option_table->header_length); + while (cmos_entry) { + if (memcmp((const char*)cmos_entry->name, name, len) =3D=3D 0) + return cmos_entry; + next =3D (struct cb_cmos_entries*)((unsigned char *)cmos_entry + cmos_entry->size); + cmos_entry =3D (next->tag =3D=3D CB_TAG_OPTION) ? next : NULL; + } + + dprintf(1, "ERROR: No such CMOS option (%s)\n", name); + return NULL; +} + +static int get_cmos_value(const struct nvram_accessor *nvram, u32 bitnum, u32 len, void *valptr) +{ + u8 *value =3D valptr; + int offs =3D 0; + u32 addr, bit; + u8 reg8; + + /* Convert to byte borders */ + addr=3D(bitnum / 8); + bit=3D(bitnum % 8); + + /* Handle single byte or less */ + if(len <=3D 8) { + reg8 =3D nvram->read(addr); + reg8 >>=3D bit; + value[0] =3D reg8 & ((1 << len) -1); + return 0; + } + + /* When handling more than a byte, copy whole bytes */ + while (len > 0) { + len -=3D 8; + value[offs++]=3Dnvram->read(addr++); + } + + return 0; +} + +int options_checksum_valid(const struct nvram_accessor *nvram, struct cb_cmos_checksum *option_checksum) +{ + int i; + int checksum_location =3D option_checksum->location / 8; + u16 checksum =3D 0, checksum_old; + + for(i =3D option_checksum->range_start; i <=3D option_checksum->range_end= ; i++) { + checksum +=3D nvram->read(i); + } + + checksum_old =3D ((nvram->read(checksum_location)<<8) | nvram->read(checksum_location+1)); + + return (checksum_old =3D=3D checksum); +} + +void *get_nvram_bootorder() +{ + const char *name =3D "bootorder"; + struct cb_header *cbh =3D find_cb_table(); + + if (!cbh) + return NULL; + struct cb_cmos_option_table *option_table =3D find_cb_subtable(cbh, CB_TAG_CMOS_OPTION_TABLE); + struct cb_cmos_checksum *option_checksum =3D find_cb_subtable(cbh, CB_TAG_OPTION_CHECKSUM); + if (option_table =3D=3D NULL) { + dprintf(1, "Could not find coreboot option table.\n"); + return NULL; + } + + struct cb_cmos_entries *cmos_entry =3D lookup_cmos_entry(option_table, na= me); + + if (!cmos_entry) + return NULL; + int cmos_length =3D cmos_entry->length; + + /* extra byte to ensure 0-terminated strings */ + void *buf =3D malloc_low(cmos_length+1); + memset(buf, 0, cmos_length+1); + + if(!options_checksum_valid(use_nvram, option_checksum)) { + dprintf(1, "Invalid option checksum.\n"); + return NULL; + } + get_cmos_value(use_nvram, cmos_entry->bit, cmos_entry->length, buf); + + return buf; +} diff --git a/src/nvram.h b/src/nvram.h new file mode 100644 index 00000000..e57b9e1c --- /dev/null +++ b/src/nvram.h @@ -0,0 +1,46 @@ +// Definitions for NVRAM configuration + +/* NOTE: +To avoid confusion, it is important to keep in mind that in this file, +the term CMOS does NOT refer to the RTC, but instead the NVRAM as a whole. +While this technically includes the RTC part, the main focus wouldn't be i= t, +and instead be the configurable parts (i.e. BIOS settings). +*/ + +#ifndef __NVRAM_H +#define __NVRAM_H + +#include "types.h" // u32, u8 + +#define RTC_PORT_STANDARD 0x70 +#define RTC_PORT_EXTENDED 0x72 + +struct cb_cmos_option_table { + u32 tag; + u32 size; + u32 header_length; +}; + +#define CB_CMOS_MAX_NAME_LENGTH 32 +struct cb_cmos_entries { + u32 tag; + u32 size; + u32 bit; + u32 length; + u32 config; + u32 config_id; + u8 name[CB_CMOS_MAX_NAME_LENGTH]; +}; + +struct cb_cmos_checksum { + u32 tag; + u32 size; + u32 range_start; + u32 range_end; + u32 location; + u32 type; +}; + +void *get_nvram_bootorder(); + +#endif \ No newline at end of file --=20 2.39.5 _______________________________________________ SeaBIOS mailing list -- seabios@seabios.org To unsubscribe send an email to seabios-leave@seabios.org