Page MenuHomeFreeBSD

D36603.diff
No OneTemporary

D36603.diff

diff --git a/stand/kboot/arch/amd64/Makefile.inc b/stand/kboot/arch/amd64/Makefile.inc
--- a/stand/kboot/arch/amd64/Makefile.inc
+++ b/stand/kboot/arch/amd64/Makefile.inc
@@ -1,4 +1,4 @@
-SRCS+= host_syscall.S amd64_tramp.S elf64_freebsd.c
+SRCS+= host_syscall.S amd64_tramp.S elf64_freebsd.c load_addr.c
CFLAGS+= -I${SYSDIR}/contrib/dev/acpica/include
diff --git a/stand/kboot/arch/amd64/load_addr.c b/stand/kboot/arch/amd64/load_addr.c
new file mode 100644
--- /dev/null
+++ b/stand/kboot/arch/amd64/load_addr.c
@@ -0,0 +1,37 @@
+/*-
+ * 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 <sys/param.h>
+#include <sys/endian.h>
+
+#include "stand.h"
+#include "host_syscall.h"
+#include "kboot.h"
+
+uint64_t
+kboot_get_phys_load_segment(void)
+{
+ return (~0ULL);
+}
diff --git a/stand/kboot/arch/powerpc64/Makefile.inc b/stand/kboot/arch/powerpc64/Makefile.inc
--- a/stand/kboot/arch/powerpc64/Makefile.inc
+++ b/stand/kboot/arch/powerpc64/Makefile.inc
@@ -1,6 +1,6 @@
CFLAGS+= -mcpu=powerpc64
-SRCS+= ppc64_elf_freebsd.c host_syscall.S kerneltramp.S
+SRCS+= ppc64_elf_freebsd.c host_syscall.S kerneltramp.S load_addr.c
SRCS+= ucmpdi2.c
LDFLAGS= -nostdlib -static -T ${.CURDIR}/arch/${MACHINE_ARCH}/ldscript.powerpc
diff --git a/stand/kboot/arch/powerpc64/load_addr.c b/stand/kboot/arch/powerpc64/load_addr.c
new file mode 100644
--- /dev/null
+++ b/stand/kboot/arch/powerpc64/load_addr.c
@@ -0,0 +1,210 @@
+/*-
+ * Copyright (C) 2010-2014 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * 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 ``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 TOOLS GMBH 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 <sys/param.h>
+#include <sys/endian.h>
+
+#include "stand.h"
+#include "host_syscall.h"
+#include "kboot.h"
+
+struct region_desc {
+ uint64_t start;
+ uint64_t end;
+};
+
+/*
+ * Find a good place to load the kernel, subject to the PowerPC's constraints
+ *
+ * This excludes ranges that are marked as reserved.
+ * And 0..end of kernel
+ *
+ * It then tries to find the memory exposed from the DTB, which it assumes is one
+ * contiguous range. It adds everything not in that list to the excluded list.
+ *
+ * Sort, dedup, and it finds the first region and uses that as the load_segment
+ * and returns that. All addresses are offset by this amount.
+ */
+uint64_t
+kboot_get_phys_load_segment(void)
+{
+ int fd;
+ uint64_t entry[2];
+ static uint64_t load_segment = ~(0UL);
+ uint64_t val_64;
+ uint32_t val_32;
+ struct region_desc rsvd_reg[32];
+ int rsvd_reg_cnt = 0;
+ int ret, a, b;
+ uint64_t start, end;
+
+ if (load_segment == ~(0UL)) {
+
+ /* Default load address is 0x00000000 */
+ load_segment = 0UL;
+
+ /* Read reserved regions */
+ fd = host_open("/proc/device-tree/reserved-ranges", O_RDONLY, 0);
+ if (fd >= 0) {
+ while (host_read(fd, &entry[0], sizeof(entry)) == sizeof(entry)) {
+ rsvd_reg[rsvd_reg_cnt].start = be64toh(entry[0]);
+ rsvd_reg[rsvd_reg_cnt].end =
+ be64toh(entry[1]) + rsvd_reg[rsvd_reg_cnt].start - 1;
+ rsvd_reg_cnt++;
+ }
+ host_close(fd);
+ }
+ /* Read where the kernel ends */
+ fd = host_open("/proc/device-tree/chosen/linux,kernel-end", O_RDONLY, 0);
+ if (fd >= 0) {
+ ret = host_read(fd, &val_64, sizeof(val_64));
+
+ if (ret == sizeof(uint64_t)) {
+ rsvd_reg[rsvd_reg_cnt].start = 0;
+ rsvd_reg[rsvd_reg_cnt].end = be64toh(val_64) - 1;
+ } else {
+ memcpy(&val_32, &val_64, sizeof(val_32));
+ rsvd_reg[rsvd_reg_cnt].start = 0;
+ rsvd_reg[rsvd_reg_cnt].end = be32toh(val_32) - 1;
+ }
+ rsvd_reg_cnt++;
+
+ host_close(fd);
+ }
+ /* Read memory size (SOCKET0 only) */
+ fd = host_open("/proc/device-tree/memory@0/reg", O_RDONLY, 0);
+ if (fd < 0)
+ fd = host_open("/proc/device-tree/memory/reg", O_RDONLY, 0);
+ if (fd >= 0) {
+ ret = host_read(fd, &entry, sizeof(entry));
+
+ /* Memory range in start:length format */
+ entry[0] = be64toh(entry[0]);
+ entry[1] = be64toh(entry[1]);
+
+ /* Reserve everything what is before start */
+ if (entry[0] != 0) {
+ rsvd_reg[rsvd_reg_cnt].start = 0;
+ rsvd_reg[rsvd_reg_cnt].end = entry[0] - 1;
+ rsvd_reg_cnt++;
+ }
+ /* Reserve everything what is after end */
+ if (entry[1] != 0xffffffffffffffffUL) {
+ rsvd_reg[rsvd_reg_cnt].start = entry[0] + entry[1];
+ rsvd_reg[rsvd_reg_cnt].end = 0xffffffffffffffffUL;
+ rsvd_reg_cnt++;
+ }
+
+ host_close(fd);
+ }
+
+ /* Sort entries in ascending order (bubble) */
+ for (a = rsvd_reg_cnt - 1; a > 0; a--) {
+ for (b = 0; b < a; b++) {
+ if (rsvd_reg[b].start > rsvd_reg[b + 1].start) {
+ struct region_desc tmp;
+ tmp = rsvd_reg[b];
+ rsvd_reg[b] = rsvd_reg[b + 1];
+ rsvd_reg[b + 1] = tmp;
+ }
+ }
+ }
+
+ /* Join overlapping/adjacent regions */
+ for (a = 0; a < rsvd_reg_cnt - 1; ) {
+
+ if ((rsvd_reg[a + 1].start >= rsvd_reg[a].start) &&
+ ((rsvd_reg[a + 1].start - 1) <= rsvd_reg[a].end)) {
+ /* We have overlapping/adjacent regions! */
+ rsvd_reg[a].end =
+ MAX(rsvd_reg[a].end, rsvd_reg[a + a].end);
+
+ for (b = a + 1; b < rsvd_reg_cnt - 1; b++)
+ rsvd_reg[b] = rsvd_reg[b + 1];
+ rsvd_reg_cnt--;
+ } else
+ a++;
+ }
+
+ /* Find the first free region */
+ if (rsvd_reg_cnt > 0) {
+ start = 0;
+ end = rsvd_reg[0].start;
+ for (a = 0; a < rsvd_reg_cnt - 1; a++) {
+ if ((start >= rsvd_reg[a].start) &&
+ (start <= rsvd_reg[a].end)) {
+ start = rsvd_reg[a].end + 1;
+ end = rsvd_reg[a + 1].start;
+ } else
+ break;
+ }
+
+ if (start != end) {
+ uint64_t align = 64UL*1024UL*1024UL;
+
+ /* Align both to 64MB boundary */
+ start = (start + align - 1UL) & ~(align - 1UL);
+ end = ((end + 1UL) & ~(align - 1UL)) - 1UL;
+
+ if (start < end)
+ load_segment = start;
+ }
+ }
+ }
+
+ return (load_segment);
+}
+
+#if 0
+/*
+ * XXX this appears to be unused, but may have been for selecting the allowed
+ * kernels ABIs. It's been unused since the first commit, which suggests an
+ * error in bringing this into the tree.
+ */
+uint8_t
+kboot_get_kernel_machine_bits(void)
+{
+ static uint8_t bits = 0;
+ struct old_utsname utsname;
+ int ret;
+
+ if (bits == 0) {
+ /* Default is 32-bit kernel */
+ bits = 32;
+
+ /* Try to get system type */
+ memset(&utsname, 0, sizeof(utsname));
+ ret = host_uname(&utsname);
+ if (ret == 0) {
+ if (strcmp(utsname.machine, "ppc64") == 0)
+ bits = 64;
+ else if (strcmp(utsname.machine, "ppc64le") == 0)
+ bits = 64;
+ }
+ }
+
+ return (bits);
+}
+#endif
diff --git a/stand/kboot/kboot.h b/stand/kboot/kboot.h
--- a/stand/kboot/kboot.h
+++ b/stand/kboot/kboot.h
@@ -8,5 +8,7 @@
#define KBOOT_H
void do_init(void);
+uint64_t kboot_get_phys_load_segment(void);
+uint8_t kboot_get_kernel_machine_bits(void);
#endif /* KBOOT_H */
diff --git a/stand/kboot/main.c b/stand/kboot/main.c
--- a/stand/kboot/main.c
+++ b/stand/kboot/main.c
@@ -49,166 +49,6 @@
extern int command_fdt_internal(int argc, char *argv[]);
-struct region_desc {
- uint64_t start;
- uint64_t end;
-};
-
-static uint64_t
-kboot_get_phys_load_segment(void)
-{
- int fd;
- uint64_t entry[2];
- static uint64_t load_segment = ~(0UL);
- uint64_t val_64;
- uint32_t val_32;
- struct region_desc rsvd_reg[32];
- int rsvd_reg_cnt = 0;
- int ret, a, b;
- uint64_t start, end;
-
- if (load_segment == ~(0UL)) {
-
- /* Default load address is 0x00000000 */
- load_segment = 0UL;
-
- /* Read reserved regions */
- fd = host_open("/proc/device-tree/reserved-ranges", O_RDONLY, 0);
- if (fd >= 0) {
- while (host_read(fd, &entry[0], sizeof(entry)) == sizeof(entry)) {
- rsvd_reg[rsvd_reg_cnt].start = be64toh(entry[0]);
- rsvd_reg[rsvd_reg_cnt].end =
- be64toh(entry[1]) + rsvd_reg[rsvd_reg_cnt].start - 1;
- rsvd_reg_cnt++;
- }
- host_close(fd);
- }
- /* Read where the kernel ends */
- fd = host_open("/proc/device-tree/chosen/linux,kernel-end", O_RDONLY, 0);
- if (fd >= 0) {
- ret = host_read(fd, &val_64, sizeof(val_64));
-
- if (ret == sizeof(uint64_t)) {
- rsvd_reg[rsvd_reg_cnt].start = 0;
- rsvd_reg[rsvd_reg_cnt].end = be64toh(val_64) - 1;
- } else {
- memcpy(&val_32, &val_64, sizeof(val_32));
- rsvd_reg[rsvd_reg_cnt].start = 0;
- rsvd_reg[rsvd_reg_cnt].end = be32toh(val_32) - 1;
- }
- rsvd_reg_cnt++;
-
- host_close(fd);
- }
- /* Read memory size (SOCKET0 only) */
- fd = host_open("/proc/device-tree/memory@0/reg", O_RDONLY, 0);
- if (fd < 0)
- fd = host_open("/proc/device-tree/memory/reg", O_RDONLY, 0);
- if (fd >= 0) {
- ret = host_read(fd, &entry, sizeof(entry));
-
- /* Memory range in start:length format */
- entry[0] = be64toh(entry[0]);
- entry[1] = be64toh(entry[1]);
-
- /* Reserve everything what is before start */
- if (entry[0] != 0) {
- rsvd_reg[rsvd_reg_cnt].start = 0;
- rsvd_reg[rsvd_reg_cnt].end = entry[0] - 1;
- rsvd_reg_cnt++;
- }
- /* Reserve everything what is after end */
- if (entry[1] != 0xffffffffffffffffUL) {
- rsvd_reg[rsvd_reg_cnt].start = entry[0] + entry[1];
- rsvd_reg[rsvd_reg_cnt].end = 0xffffffffffffffffUL;
- rsvd_reg_cnt++;
- }
-
- host_close(fd);
- }
-
- /* Sort entries in ascending order (bubble) */
- for (a = rsvd_reg_cnt - 1; a > 0; a--) {
- for (b = 0; b < a; b++) {
- if (rsvd_reg[b].start > rsvd_reg[b + 1].start) {
- struct region_desc tmp;
- tmp = rsvd_reg[b];
- rsvd_reg[b] = rsvd_reg[b + 1];
- rsvd_reg[b + 1] = tmp;
- }
- }
- }
-
- /* Join overlapping/adjacent regions */
- for (a = 0; a < rsvd_reg_cnt - 1; ) {
-
- if ((rsvd_reg[a + 1].start >= rsvd_reg[a].start) &&
- ((rsvd_reg[a + 1].start - 1) <= rsvd_reg[a].end)) {
- /* We have overlapping/adjacent regions! */
- rsvd_reg[a].end =
- MAX(rsvd_reg[a].end, rsvd_reg[a + a].end);
-
- for (b = a + 1; b < rsvd_reg_cnt - 1; b++)
- rsvd_reg[b] = rsvd_reg[b + 1];
- rsvd_reg_cnt--;
- } else
- a++;
- }
-
- /* Find the first free region */
- if (rsvd_reg_cnt > 0) {
- start = 0;
- end = rsvd_reg[0].start;
- for (a = 0; a < rsvd_reg_cnt - 1; a++) {
- if ((start >= rsvd_reg[a].start) &&
- (start <= rsvd_reg[a].end)) {
- start = rsvd_reg[a].end + 1;
- end = rsvd_reg[a + 1].start;
- } else
- break;
- }
-
- if (start != end) {
- uint64_t align = 64UL*1024UL*1024UL;
-
- /* Align both to 64MB boundary */
- start = (start + align - 1UL) & ~(align - 1UL);
- end = ((end + 1UL) & ~(align - 1UL)) - 1UL;
-
- if (start < end)
- load_segment = start;
- }
- }
- }
-
- return (load_segment);
-}
-
-uint8_t
-kboot_get_kernel_machine_bits(void)
-{
- static uint8_t bits = 0;
- struct old_utsname utsname;
- int ret;
-
- if (bits == 0) {
- /* Default is 32-bit kernel */
- bits = 32;
-
- /* Try to get system type */
- memset(&utsname, 0, sizeof(utsname));
- ret = host_uname(&utsname);
- if (ret == 0) {
- if (strcmp(utsname.machine, "ppc64") == 0)
- bits = 64;
- else if (strcmp(utsname.machine, "ppc64le") == 0)
- bits = 64;
- }
- }
-
- return (bits);
-}
-
int
kboot_getdev(void **vdev, const char *devspec, const char **path)
{

File Metadata

Mime Type
text/plain
Expires
Mon, Sep 30, 6:25 AM (22 h, 1 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13108494
Default Alt Text
D36603.diff (13 KB)

Event Timeline