From nobody Fri Feb 03 15:50:37 2023 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4P7g992nnQz3kRmR; Fri, 3 Feb 2023 15:50:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4P7g991v2rz3HY4; Fri, 3 Feb 2023 15:50:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675439437; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZGQCSuFYXFFG6qFNGoIShlcu6lBgf0JcdjHi6kmZxAQ=; b=Xo8rIXfXJjUFrUPV2TXrCik00fsM8ciWnHDUhqQgOCgRJQZbXXFi3EFIntxJdppWUOUk2O BZ5l5Im3ozYuvWIOdXqLhM2L+jjiG5LxAu+GpA6hTF9Fxgjzz44z/eMhglqr0Xl3bQDshs lO96NAefXU5EmLvv8LbRzTN19s7sSbNReASSl8bPpkcGnfei2lyafwKEColbEkDmJOx0Q6 ytTMkXFPGIcL9CntXWuB+/3TS0Vq6O3XAiz9R8wd+qzQzicJS1C4M5iD/CcaxJ31lhZZ+G mx2LvLcJpHffxsGdfC29joLstRMvQZgA7Em7EAa3Avt926zDY2WC1BEto7thog== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1675439437; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=ZGQCSuFYXFFG6qFNGoIShlcu6lBgf0JcdjHi6kmZxAQ=; b=m8Luz/4kY/sMaQKeN7dgWsuXVigLbJfJUcYKTbywDS+DZs9HoFp3LTbkcwVWChgVWD0JKx 586jhKi8CL+ISlhbqqFJHt2hDKEGcScu+T5Io26ByQyamfXU7gZhWuh2v+Vi2jFkftkRp0 wFvwuotwxRYsROi5lkFt2MaaK1GmTtirN4cpZpLwqJXzcNF0iXzHKIxmynyDBdciajopqH ybPLPsJgJZc1p2F9uu093PuP4Pwv8G7dAaO6+/tsgfsBJuD9kl3HN7GAfDq5S1ZoMQ6lOe Fj9FlrO5HgWCn4vxsGCvYJyp6nf3YfbFa0BrqzNHSLvMmrzxqdEAiB3XOKM77w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1675439437; a=rsa-sha256; cv=none; b=q1vNQPzskpayX/t8z6bOMnhTt+LTnSknrwVza2O7NrPufBe+jAGAozPNPTiDrqabnJ2rqy 8RL53hObJb3re+auReJumwPRxZSsrV1kmuLW46xA3c6mL5ffJpTpxvoOWdHj7BO19uNJ/J 7LZxjzwZ/WJPX+rSGhtwVND+5UqFHtb1i5SP+fzFUH0B1jgPyVVUZ0C4Q4cS6GzpBt5vpp xfaLIj4p/AzJgjEEGEkkv0pwCvd1TXc/5/Tcm8WoD7hjhp+1wkgqEhx8a1eFmiqWsf3m4E 59txA/s6KFFYSiXWCMvfXoYGSHwA+6asy2YqEWAXvYbYUyOFEHfFSr3/Dr60wg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4P7g990zSxzgB2; Fri, 3 Feb 2023 15:50:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 313Fobjf022957; Fri, 3 Feb 2023 15:50:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 313Fobuk022956; Fri, 3 Feb 2023 15:50:37 GMT (envelope-from git) Date: Fri, 3 Feb 2023 15:50:37 GMT Message-Id: <202302031550.313Fobuk022956@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Warner Losh Subject: git: 33e5b27254e7 - main - kboot: Add parsing of /proc/iomem into seg.c List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 33e5b27254e78c45a3cb728243709c16100fac36 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=33e5b27254e78c45a3cb728243709c16100fac36 commit 33e5b27254e78c45a3cb728243709c16100fac36 Author: Warner Losh AuthorDate: 2023-02-03 15:38:14 +0000 Commit: Warner Losh CommitDate: 2023-02-03 15:41:39 +0000 kboot: Add parsing of /proc/iomem into seg.c We'll be using this code for most / all of the platforms since iomem is the only interface that can tell us of the reserved to the linux kernel areas that we cannot place the new kernel into, but that we are free to use once we hit trampoline. aarch64 will use this shortly, and similar code in amd64 will be refactored when I make that platform work. Sponsored by: Netflix Reviewed by: tsoome Differential Revision: https://reviews.freebsd.org/D38309 --- stand/kboot/kboot.h | 2 + stand/kboot/seg.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) diff --git a/stand/kboot/kboot.h b/stand/kboot/kboot.h index 2d89933b51aa..dcf1487ce404 100644 --- a/stand/kboot/kboot.h +++ b/stand/kboot/kboot.h @@ -36,12 +36,14 @@ void hostdisk_zfs_probe(void); bool hostdisk_zfs_find_default(void); /* seg.c */ +#define SYSTEM_RAM 1 void init_avail(void); void need_avail(int n); void add_avail(uint64_t start, uint64_t end, uint64_t type); void remove_avail(uint64_t start, uint64_t end, uint64_t type); uint64_t first_avail(uint64_t align, uint64_t min_size, uint64_t type); void print_avail(void); +bool populate_avail_from_iomem(void); /* util.c */ bool file2str(const char *fn, char *buffer, size_t buflen); diff --git a/stand/kboot/seg.c b/stand/kboot/seg.c index 41ded9b4083c..8cf3b833c9d1 100644 --- a/stand/kboot/seg.c +++ b/stand/kboot/seg.c @@ -195,3 +195,152 @@ first_avail(uint64_t align, uint64_t min_size, uint64_t memtype) return (0); } + +enum types { + system_ram = SYSTEM_RAM, + firmware_reserved, + linux_code, + linux_data, + linux_bss, + unknown, +}; + +static struct kv +{ + uint64_t type; + char * name; + int flags; +#define KV_KEEPER 1 +} str2type_kv[] = { + { linux_code, "Kernel code", KV_KEEPER }, + { linux_data, "Kernel data", KV_KEEPER }, + { linux_bss, "Kernel bss", KV_KEEPER }, + { firmware_reserved, "reserved" }, + { 0, NULL }, +}; + +static const char * +parse_line(const char *line, uint64_t *startp, uint64_t *endp) +{ + const char *walker; + char *next; + uint64_t start, end; + + /* + * Each line is a range followed by a descriptoin of the form: + * + * Bail if we have any parsing errors. + */ + walker = line; + start = strtoull(walker, &next, 16); + if (start == ULLONG_MAX || walker == next) + return (NULL); + walker = next; + if (*walker != '-') + return (NULL); + walker++; + end = strtoull(walker, &next, 16); + if (end == ULLONG_MAX || walker == next) + return (NULL); + walker = next; + /* Now eat the ' : ' in front of the string we want to return */ + if (strncmp(walker, " : ", 3) != 0) + return (NULL); + *startp = start; + *endp = end; + return (walker + 3); +} + +static struct kv * +kvlookup(const char *str, struct kv *kvs, size_t nkv) +{ + for (int i = 0; i < nkv; i++) + if (strcmp(kvs[i].name, str) == 0) + return (&kvs[i]); + + return (NULL); +} + +/* Trim trailing whitespace */ +static void +chop(char *line) +{ + char *ep = line + strlen(line) - 1; + + while (ep >= line && isspace(*ep)) + *ep-- = '\0'; +} + +#define SYSTEM_RAM_STR "System RAM" +#define RESERVED "reserved" + +bool +populate_avail_from_iomem(void) +{ + int fd; + char buf[128]; + const char *str; + uint64_t start, end; + struct kv *kv; + + fd = open("host:/proc/iomem", O_RDONLY); + if (fd == -1) { + printf("Can't get memory map\n"); + return false; + } + + if (fgetstr(buf, sizeof(buf), fd) < 0) + goto out; /* Nothing to do ???? */ + init_avail(); + chop(buf); + while (true) { + /* + * Look for top level items we understand. Skip anything that's + * a continuation, since we don't care here. If we care, we'll + * consume them all when we recognize that top level item. + */ + if (buf[0] == ' ') /* Continuation lines? Ignore */ + goto next_line; + str = parse_line(buf, &start, &end); + if (str == NULL) /* Malformed -> ignore */ + goto next_line; + /* + * All we care about is System RAM + */ + if (strncmp(str, SYSTEM_RAM_STR, sizeof(SYSTEM_RAM_STR) - 1) == 0) + add_avail(start, end, system_ram); + else if (strncmp(str, RESERVED, sizeof(RESERVED) - 1) == 0) + add_avail(start, end, firmware_reserved); + else + goto next_line; /* Ignore hardware */ + while (fgetstr(buf, sizeof(buf), fd) >= 0 && buf[0] == ' ') { + chop(buf); + str = parse_line(buf, &start, &end); + if (str == NULL) + break; + kv = kvlookup(str, str2type_kv, nitems(str2type_kv)); + if (kv == NULL) /* failsafe for new types: igonre */ + remove_avail(start, end, unknown); + else if ((kv->flags & KV_KEEPER) == 0) + remove_avail(start, end, kv->type); + /* Else no need to adjust since it's a keeper */ + } + + /* + * if buf[0] == ' ' then we know that the fgetstr failed and we + * should break. Otherwise fgetstr succeeded and we have a + * buffer we need to examine for being a top level item. + */ + if (buf[0] == ' ') + break; + chop(buf); + continue; /* buf has next top level line to parse */ +next_line: + if (fgetstr(buf, sizeof(buf), fd) < 0) + break; + } + +out: + close(fd); + return true; +}