#include <sys/param.h>
#include <machine/metadata.h>
#include <sys/linker.h>
#include <fdt_platform.h>
#include <libfdt.h>
#include "kboot.h"
#include "efi.h"
static bool
do_memory_from_fdt(int fd)
{
struct stat sb;
char *buf = NULL;
int len, offset;
uint32_t sz, ver, esz;
uint64_t mmap_pa;
const uint32_t *u32p;
const uint64_t *u64p;
if (fstat(fd, &sb) < 0)
return false;
buf = malloc(sb.st_size);
if (buf == NULL)
return false;
len = read(fd, buf, sb.st_size);
if (len <= 0)
goto errout;
offset = fdt_path_offset(buf, "/chosen");
if (offset <= 0)
goto errout;
u64p = fdt_getprop(buf, offset, "linux,uefi-system-table", &len);
if (u64p == NULL)
goto errout;
efi_set_systbl(fdt64_to_cpu(*u64p));
u32p = fdt_getprop(buf, offset, "linux,uefi-mmap-desc-ver", &len);
if (u32p == NULL)
goto errout;
ver = fdt32_to_cpu(*u32p);
u32p = fdt_getprop(buf, offset, "linux,uefi-mmap-desc-size", &len);
if (u32p == NULL)
goto errout;
esz = fdt32_to_cpu(*u32p);
u32p = fdt_getprop(buf, offset, "linux,uefi-mmap-size", &len);
if (u32p == NULL)
goto errout;
sz = fdt32_to_cpu(*u32p);
u64p = fdt_getprop(buf, offset, "linux,uefi-mmap-start", &len);
if (u64p == NULL)
goto errout;
mmap_pa = fdt64_to_cpu(*u64p);
free(buf);
printf("UEFI MMAP: Ver %d Ent Size %d Tot Size %d PA %#lx\n",
ver, esz, sz, mmap_pa);
efi_read_from_pa(mmap_pa, sz, esz, ver);
return true;
errout:
free(buf);
return false;
}
bool
enumerate_memory_arch(void)
{
int fd = -1;
bool rv = false;
fd = open("host:/sys/firmware/fdt", O_RDONLY);
if (fd != -1) {
rv = do_memory_from_fdt(fd);
close(fd);
}
if (!rv) {
printf("Could not obtain UEFI memory tables, expect failure\n");
}
populate_avail_from_iomem();
print_avail();
return true;
}
uint64_t
kboot_get_phys_load_segment(void)
{
#define HOLE_SIZE (64ul << 20)
#define KERN_ALIGN (2ul << 20)
static uint64_t s = 0;
if (s != 0)
return (s);
print_avail();
s = first_avail(KERN_ALIGN, HOLE_SIZE, SYSTEM_RAM);
printf("KBOOT GET PHYS Using %#llx\n", (long long)s);
if (s != 0)
return (s);
s = 0x40000000 | 0x4200000;
printf("Falling back to the crazy address %#lx which works in qemu\n", s);
return (s);
}
void
bi_loadsmap(struct preloaded_file *kfp)
{
efi_bi_loadsmap(kfp);
}