From nobody Tue Jan 24 22:13:35 2023 X-Original-To: dev-commits-src-branches@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 4P1h7h1QsZz3bgJP; Tue, 24 Jan 2023 22:13:36 +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 4P1h7h0rQwz3HNH; Tue, 24 Jan 2023 22:13:36 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1674598416; 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=RPMet5iarGQNvC6sVPbXzEyyG/uKbhH3SvErgomf7+8=; b=xXYfop9v0abk/JEcrIizqDbBF6qqhi0n26TqcKc1OLNT5+ibXJmLPll6VyrcJh4KeXgWWV 8cvD32CpR9DR0r8iYNx+fsEpUbl5e0t1EtuuGqDn9P+jc2ENxr3jQbNVhWck4DwHwJTicE 5PXqo34vP156+ajqeSdGj6em10Lpi18aVzEnd4J3YQgenllPhLN5oItH1UsH2JZgdc2Rw9 tWdM6nn/GcwoUDUifKE5LMmzgOnMxNbuZeVHDzU+ROzLEGKkDmVvqRlzdjZX5gLmKL7sNy 1gFD0zVfjzkgKv9N+6fYHHyPLD/NSSkF2JFHfSrVVtrF4/kGiE71Vh2h4A2Oig== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1674598416; 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=RPMet5iarGQNvC6sVPbXzEyyG/uKbhH3SvErgomf7+8=; b=NL6h/QahzAlHxfAdulz0NALSbkPiiPX27EFNcwpk+akgsj88zvHtYaGZ05SXteQIJejSY1 o/gsaQYwIZBgZ6Mp/7lnQlyxwSD32job48+WaTUDsjr2N1S3wCZLDqyys0v4bS7bui/bi2 byiMRYD2IGhsN9nYXbH74nUUQ8ozDeXsmOzmJVfHOuBV1tYN8KTMzthigX8C8B2zg9DBI4 s+wsM4aHkLssh/gH50OvtCkqaZP4wLRIP7tEZEctUJrOPW0xivlinvqMkyFZZbZjEioh1K rYIoscqzg/+wCUWqtOj6FcZ8JR5O+/s7mMtCWtmmmIfKJarNmNABVfeNfbo1nA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1674598416; a=rsa-sha256; cv=none; b=hG2ZNtEYqm0Pe8+rGByXf3r+tk6Vss0j8rys9Ruc/eB2VcvWcUyKpe5AzSu9hF2JUWAFO+ /DSNpD1ITTQxSv4XhzlIbOy6aSS4dcimyT8QC1Ds+qpD1CkjGXbUPjvADRnKfAKCdYQtDQ PXRwYGpc2ENl5B590atrfQZj5h8Xa0mDGEjS8LynlbyP9pjhY7yJDt4VtbysXEMKSPBmr+ tWk1LKbLmktSvSnmU3KI1FL3WQMFX0g6VHC3WXrisovqrZfJB6GtmIUjP83D0vc43xbXLF HLsspoHpkXMH49HptlUjj3E7e3Z5m9yDcw4KPH8sEPWZuM55+WME8adHMT5Uow== 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 4P1h7g6k1xzQh7; Tue, 24 Jan 2023 22:13:35 +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 30OMDZwI088646; Tue, 24 Jan 2023 22:13:35 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 30OMDZss088645; Tue, 24 Jan 2023 22:13:35 GMT (envelope-from git) Date: Tue, 24 Jan 2023 22:13:35 GMT Message-Id: <202301242213.30OMDZss088645@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Warner Losh Subject: git: 965939b23966 - stable/13 - kboot: amd64 use /sys/firmware/memmap to find free memory List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@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/stable/13 X-Git-Reftype: branch X-Git-Commit: 965939b23966fdfdada374af77e5aa783315a9a0 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=965939b23966fdfdada374af77e5aa783315a9a0 commit 965939b23966fdfdada374af77e5aa783315a9a0 Author: Warner Losh AuthorDate: 2022-12-02 18:10:42 +0000 Commit: Warner Losh CommitDate: 2023-01-24 21:49:41 +0000 kboot: amd64 use /sys/firmware/memmap to find free memory Use the system's firmware memory map to find a good place to put the kernel that won't stomp on anything else. While this uses obstensibly MI interfaces to get this data, arm64 doesn't have this, nor does powerpc64, so place it here. Sponsored by: Netflix (cherry picked from commit c51e1d7c0a79a4fe2774d526ad0393cd2edd3f6c) --- stand/kboot/arch/amd64/load_addr.c | 127 ++++++++++++++++++++++++++++++++++++- 1 file changed, 126 insertions(+), 1 deletion(-) diff --git a/stand/kboot/arch/amd64/load_addr.c b/stand/kboot/arch/amd64/load_addr.c index cbe066d02d40..fccd17cf8d51 100644 --- a/stand/kboot/arch/amd64/load_addr.c +++ b/stand/kboot/arch/amd64/load_addr.c @@ -30,8 +30,133 @@ #include "host_syscall.h" #include "kboot.h" +/* Refactor when we do arm64 */ + +struct memory_segments +{ + uint64_t start; + uint64_t end; + uint64_t type; +}; + +enum types { + system_ram = 1, + acpi_tables, + acpi_nv_storage, + unusable, + persistent_old, + persistent, + soft_reserved, + reserved, +}; + +struct kv +{ + uint64_t type; + char * name; +} str2type_kv[] = { + { system_ram, "System RAM" }, + { acpi_tables, "ACPI Tables" }, + { acpi_nv_storage, "ACPI Non-volatile Storage" }, + { unusable, "Unusable memory" }, + { persistent_old, "Persistent Memory (legacy)" }, + { persistent, "Persistent Memory" }, + { soft_reserved, "Soft Reserved" }, + { reserved, "reserved" }, + { 0, NULL }, +}; + +#define MEMMAP "/sys/firmware/memmap" + +static bool +str2type(struct kv *kv, const char *buf, uint64_t *value) +{ + while (kv->name != NULL) { + if (strcmp(kv->name, buf) == 0) { + *value = kv->type; + return true; + } + kv++; + } + + return false; +} + +static int +read_memmap(struct memory_segments *segs, int maxseg) +{ + int n; + char name[MAXPATHLEN]; + char buf[80]; + + n = 0; + do { + snprintf(name, sizeof(name), "%s/%d/start", MEMMAP, n); + if (!file2u64(name, &segs[n].start)) + break; + snprintf(name, sizeof(name), "%s/%d/length", MEMMAP, n); + if (!file2u64(name, &segs[n].end)) + break; + snprintf(name, sizeof(name), "%s/%d/type", MEMMAP, n); + if (!file2str(name, buf, sizeof(buf))) + break; + if (!str2type(str2type_kv, buf, &segs[n].type)) + break; + n++; + } while (n < maxseg); + + return n; +} + +#define BAD_SEG ~0ULL + +#define SZ(s) (((s).end - (s).start) + 1) + +static uint64_t +find_ram(struct memory_segments *segs, int nr_seg, uint64_t minpa, uint64_t align, + uint64_t sz, uint64_t maxpa) +{ + uint64_t start; + + /* XXX assume segs are sorted in numeric order -- assumed not ensured */ + for (int i = 0; i < nr_seg; i++) { + if (segs[i].type != system_ram || + SZ(segs[i]) < sz || + minpa + sz > segs[i].end || + maxpa < segs[i].start) + continue; + start = roundup(segs[i].start, align); + if (start < minpa) /* Too small, round up and try again */ + start = (roundup(minpa, align)); + if (start + sz > segs[i].end) /* doesn't fit in seg */ + continue; + if (start > maxpa || /* Over the edge */ + start + sz > maxpa) /* on the edge */ + break; /* No hope to continue */ + return start; + } + + return BAD_SEG; +} + uint64_t kboot_get_phys_load_segment(void) { - return (~0ULL); + static uint64_t base_seg = BAD_SEG; + struct memory_segments segs[32]; + int nr_seg; + + if (base_seg != BAD_SEG) + return (base_seg); + + nr_seg = read_memmap(segs, nitems(segs)); + if (nr_seg > 0) + base_seg = find_ram(segs, nr_seg, 2ULL << 20, 2ULL << 20, + 64ULL << 20, 4ULL << 30); + if (base_seg == BAD_SEG) { + /* XXX Should fall back to using /proc/iomem maybe? */ + /* XXX PUNT UNTIL I NEED SOMETHING BETTER */ + base_seg = 42ULL * (1 << 20); /* Jam it in at the odd-ball address of 42MB so it stands out */ + } + return (base_seg); }