aboutsummaryrefslogtreecommitdiff
path: root/stand/kboot
diff options
context:
space:
mode:
authorWarner Losh <imp@FreeBSD.org>2023-02-03 15:40:22 +0000
committerWarner Losh <imp@FreeBSD.org>2023-02-03 15:41:40 +0000
commit84eb9b2306fd4b8cf4d9328ff661f7684c596642 (patch)
treea9515f6efb2f843e8b61fb53e929fbb2caf208bb /stand/kboot
parent2069a2a08f6e555285be71be042e85c75b6feb02 (diff)
Diffstat (limited to 'stand/kboot')
-rw-r--r--stand/kboot/main.c33
1 files changed, 25 insertions, 8 deletions
diff --git a/stand/kboot/main.c b/stand/kboot/main.c
index 7f548fe15b08..6631cb38ae22 100644
--- a/stand/kboot/main.c
+++ b/stand/kboot/main.c
@@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <bootstrap.h>
#include "host_syscall.h"
#include "kboot.h"
+#include "stand.h"
struct arch_switch archsw;
extern void *_end;
@@ -49,6 +50,11 @@ static void kboot_zfs_probe(void);
extern int command_fdt_internal(int argc, char *argv[]);
+#define PA_INVAL (vm_offset_t)-1
+static vm_offset_t pa_start = PA_INVAL;
+static vm_offset_t padding;
+static vm_offset_t offset;
+
static uint64_t commit_limit;
static uint64_t committed_as;
static uint64_t mem_avail;
@@ -95,8 +101,8 @@ memory_limits(void)
int
kboot_getdev(void **vdev, const char *devspec, const char **path)
{
- int rv;
struct devdesc **dev = (struct devdesc **)vdev;
+ int rv;
/*
* If it looks like this is just a path and no device, go with the
@@ -311,11 +317,13 @@ time(time_t *tloc)
struct host_kexec_segment loaded_segments[HOST_KEXEC_SEGMENT_MAX];
int nkexec_segments = 0;
+#define SEGALIGN (1ul<<20)
+
static ssize_t
get_phys_buffer(vm_offset_t dest, const size_t len, void **buf)
{
int i = 0;
- const size_t segsize = 8*1024*1024;
+ const size_t segsize = 64*1024*1024;
if (nkexec_segments == HOST_KEXEC_SEGMENT_MAX)
panic("Tried to load too many kexec segments");
@@ -328,7 +336,7 @@ get_phys_buffer(vm_offset_t dest, const size_t len, void **buf)
loaded_segments[nkexec_segments].buf = host_getmem(segsize);
loaded_segments[nkexec_segments].bufsz = segsize;
- loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,segsize);
+ loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,SEGALIGN);
loaded_segments[nkexec_segments].memsz = segsize;
i = nkexec_segments;
@@ -347,9 +355,17 @@ kboot_copyin(const void *src, vm_offset_t dest, const size_t len)
ssize_t segsize, remainder;
void *destbuf;
+ if (pa_start == PA_INVAL) {
+ pa_start = kboot_get_phys_load_segment();
+// padding = 2 << 20; /* XXX amd64: revisit this when we make it work */
+ padding = 0;
+ offset = dest;
+ get_phys_buffer(pa_start, len, &destbuf);
+ }
+
remainder = len;
do {
- segsize = get_phys_buffer(dest, remainder, &destbuf);
+ segsize = get_phys_buffer(dest + pa_start + padding - offset, remainder, &destbuf);
bcopy(src, destbuf, segsize);
remainder -= segsize;
src += segsize;
@@ -367,7 +383,7 @@ kboot_copyout(vm_offset_t src, void *dest, const size_t len)
remainder = len;
do {
- segsize = get_phys_buffer(src, remainder, &srcbuf);
+ segsize = get_phys_buffer(src + pa_start + padding - offset, remainder, &srcbuf);
bcopy(srcbuf, dest, segsize);
remainder -= segsize;
src += segsize;
@@ -420,17 +436,18 @@ kboot_autoload(void)
static void
kboot_kseg_get(int *nseg, void **ptr)
{
-#if 0
int a;
+ printf("kseg_get: %d segments\n", nkexec_segments);
+ printf("VA SZ PA MEMSZ\n");
+ printf("---------------- -------- ---------------- -----\n");
for (a = 0; a < nkexec_segments; a++) {
- printf("kseg_get: %jx %jx %jx %jx\n",
+ printf("%016jx %08jx %016jx %08jx\n",
(uintmax_t)loaded_segments[a].buf,
(uintmax_t)loaded_segments[a].bufsz,
(uintmax_t)loaded_segments[a].mem,
(uintmax_t)loaded_segments[a].memsz);
}
-#endif
*nseg = nkexec_segments;
*ptr = &loaded_segments[0];