diff --git a/stand/kboot/kboot/arch/amd64/load_addr.c b/stand/kboot/kboot/arch/amd64/load_addr.c index 4bd2a19dab48..ae53aa75da19 100644 --- a/stand/kboot/kboot/arch/amd64/load_addr.c +++ b/stand/kboot/kboot/arch/amd64/load_addr.c @@ -1,181 +1,82 @@ /*- * Copyright (c) 2022 Netflix, Inc * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include #include #include "stand.h" #include "host_syscall.h" +#include "efi.h" #include "kboot.h" #include "bootstrap.h" -/* Refactor when we do arm64 */ - -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 struct memory_segments segs[64]; /* make dynamic later */ -static int nr_seg; - -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; -} - bool enumerate_memory_arch(void) { - int n; - char name[MAXPATHLEN]; - char buf[80]; - - for (n = 0; n < nitems(segs); n++) { - snprintf(name, sizeof(name), "%s/%d/start", MEMMAP, n); - if (!file2u64(name, &segs[n].start)) - break; - snprintf(name, sizeof(name), "%s/%d/end", 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; - } - - nr_seg = n; - - return true; -} - -#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; - - printf("minpa %#jx align %#jx sz %#jx maxpa %#jx\n", - (uintmax_t)minpa, - (uintmax_t)align, - (uintmax_t)sz, - (uintmax_t)maxpa); - /* 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; + efi_read_from_sysfs(); + if (!populate_avail_from_iomem()) + return (false); + print_avail(); + return (true); } uint64_t kboot_get_phys_load_segment(void) { static uint64_t base_seg = BAD_SEG; if (base_seg != BAD_SEG) return (base_seg); 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 = 300ULL * (1 << 20); } return (base_seg); } void bi_loadsmap(struct preloaded_file *kfp) { struct bios_smap smap[32], *sm; struct memory_segments *s; int smapnum, len; for (smapnum = 0; smapnum < min(32, nr_seg); smapnum++) { sm = &smap[smapnum]; s = &segs[smapnum]; sm->base = s->start; sm->length = s->end - s->start + 1; sm->type = SMAP_TYPE_MEMORY; } len = smapnum * sizeof(struct bios_smap); file_addmetadata(kfp, MODINFOMD_SMAP, len, &smap[0]); }