Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107877626
D36603.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
13 KB
Referenced Files
None
Subscribers
None
D36603.diff
View Options
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
Details
Attached
Mime Type
text/plain
Expires
Sun, Jan 19, 10:41 PM (21 h, 2 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15964187
Default Alt Text
D36603.diff (13 KB)
Attached To
Mode
D36603: kboot: Move load address stuff to MD code
Attached
Detach File
Event Timeline
Log In to Comment