Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/alpha Qemu loads the kernel directly, and so there'...
details: https://anonhg.NetBSD.org/src/rev/9817b17b8808
branches: trunk
changeset: 940091:9817b17b8808
user: thorpej <thorpej%NetBSD.org@localhost>
date: Sat Oct 03 17:31:46 2020 +0000
description:
Qemu loads the kernel directly, and so there's no bootloader to provide
a "bootinfo" structure for us. Qemu does, however, place a Linux kernel
parameter block at kernel_text[] - 0x6000 that contains Linux-style kernel
command line arguments. So, add a prom_qemu_getenv() that allows us to
look for specific things passed along to the kernel from there, and use
them as follows:
- Support specifying the root device in the forms "root=/dev/wd0a",
"root=wd0a", or "rootdev=wd0".
- Support SRM-like -flags ... in the form of "flags=AD". In the case of
Qemu, we also assume that no flags=... is the same as "flags=A", i.e.
perform an auto-boot.
Also allow an alternate delay() function to be specified, if the platform
wishes to provide one.
diffstat:
sys/arch/alpha/alpha/autoconf.c | 57 ++++++++++++++++++++++++++++++++++++++--
sys/arch/alpha/alpha/machdep.c | 39 ++++++++++++++++++++++-----
sys/arch/alpha/alpha/prom.c | 56 ++++++++++++++++++++++++++++++++++++++-
sys/arch/alpha/include/alpha.h | 3 +-
sys/arch/alpha/include/prom.h | 10 ++++++-
5 files changed, 150 insertions(+), 15 deletions(-)
diffs (297 lines):
diff -r 9afe6bee9ebc -r 9817b17b8808 sys/arch/alpha/alpha/autoconf.c
--- a/sys/arch/alpha/alpha/autoconf.c Sat Oct 03 17:30:54 2020 +0000
+++ b/sys/arch/alpha/alpha/autoconf.c Sat Oct 03 17:31:46 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: autoconf.c,v 1.54 2018/09/03 16:29:22 riastradh Exp $ */
+/* $NetBSD: autoconf.c,v 1.55 2020/10/03 17:31:46 thorpej Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -42,7 +42,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.54 2018/09/03 16:29:22 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.55 2020/10/03 17:31:46 thorpej Exp $");
#include "pci.h"
@@ -97,13 +97,64 @@
hwrpb_restart_setup();
}
+static void
+qemu_find_rootdev(void)
+{
+ char buf[32];
+
+ /*
+ * Check for "rootdev=wd0".
+ */
+ if (prom_qemu_getenv("rootdev", buf, sizeof(buf))) {
+ snprintf(bootinfo.booted_dev, sizeof(bootinfo.booted_dev),
+ "rootdev=%s", buf);
+ booted_device = device_find_by_xname(buf);
+ return;
+ }
+
+ /*
+ * Check for "root=/dev/wd0a", "root=/dev/hda1", etc.
+ */
+ if (prom_qemu_getenv("root", buf, sizeof(buf))) {
+ const size_t devlen = strlen("/dev/");
+ const char *cp = buf;
+ char *ecp = &buf[sizeof(buf) - 1];
+
+ snprintf(bootinfo.booted_dev, sizeof(bootinfo.booted_dev),
+ "root=%s", buf);
+
+ /* Find the start of the device xname. */
+ if (strlen(cp) > devlen && strncmp(cp, "/dev/", devlen) == 0) {
+ cp += devlen;
+ }
+
+ /* Now strip any partition letter off the end. */
+ while (ecp != cp) {
+ if (*ecp >= '0' && *ecp <= '9') {
+ break;
+ }
+ *ecp-- = '\0';
+ }
+
+ booted_device = device_find_by_xname(cp);
+ return;
+ }
+
+ printf("WARNING: no rootdev= or root= arguments provided by Qemu\n");
+}
+
void
cpu_rootconf(void)
{
- if (booted_device == NULL)
+ if (booted_device == NULL && alpha_is_qemu) {
+ qemu_find_rootdev();
+ }
+
+ if (booted_device == NULL) {
printf("WARNING: can't figure what device matches \"%s\"\n",
bootinfo.booted_dev);
+ }
rootconf();
}
diff -r 9afe6bee9ebc -r 9817b17b8808 sys/arch/alpha/alpha/machdep.c
--- a/sys/arch/alpha/alpha/machdep.c Sat Oct 03 17:30:54 2020 +0000
+++ b/sys/arch/alpha/alpha/machdep.c Sat Oct 03 17:31:46 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.365 2020/09/27 23:16:10 thorpej Exp $ */
+/* $NetBSD: machdep.c,v 1.366 2020/10/03 17:31:46 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2019 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.365 2020/09/27 23:16:10 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.366 2020/10/03 17:31:46 thorpej Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -320,12 +320,24 @@
bootinfo.hwrpb_phys = ((struct rpb *)HWRPB_ADDR)->rpb_phys;
bootinfo.hwrpb_size = ((struct rpb *)HWRPB_ADDR)->rpb_size;
init_prom_interface(ptb, (struct rpb *)HWRPB_ADDR);
- prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo.boot_flags,
- sizeof bootinfo.boot_flags);
- prom_getenv(PROM_E_BOOTED_FILE, bootinfo.booted_kernel,
- sizeof bootinfo.booted_kernel);
- prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev,
- sizeof bootinfo.booted_dev);
+ if (alpha_is_qemu) {
+ /*
+ * Grab boot flags from kernel command line.
+ * Assume autoboot if not supplied.
+ */
+ if (! prom_qemu_getenv("flags", bootinfo.boot_flags,
+ sizeof(bootinfo.boot_flags))) {
+ strlcpy(bootinfo.boot_flags, "A",
+ sizeof(bootinfo.boot_flags));
+ }
+ } else {
+ prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo.boot_flags,
+ sizeof bootinfo.boot_flags);
+ prom_getenv(PROM_E_BOOTED_FILE, bootinfo.booted_kernel,
+ sizeof bootinfo.booted_kernel);
+ prom_getenv(PROM_E_BOOTED_DEV, bootinfo.booted_dev,
+ sizeof bootinfo.booted_dev);
+ }
}
/*
@@ -1602,6 +1614,8 @@
}
}
+void (*alpha_delay_fn)(unsigned long);
+
/*
* Wait "n" microseconds.
*/
@@ -1613,6 +1627,15 @@
if (n == 0)
return;
+ /*
+ * If we have an alternative delay function, go ahead and
+ * use it.
+ */
+ if (alpha_delay_fn != NULL) {
+ (*alpha_delay_fn)(n);
+ return;
+ }
+
pcc0 = alpha_rpcc() & 0xffffffffUL;
cycles = 0;
usec = 0;
diff -r 9afe6bee9ebc -r 9817b17b8808 sys/arch/alpha/alpha/prom.c
--- a/sys/arch/alpha/alpha/prom.c Sat Oct 03 17:30:54 2020 +0000
+++ b/sys/arch/alpha/alpha/prom.c Sat Oct 03 17:31:46 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: prom.c,v 1.57 2020/09/27 23:16:10 thorpej Exp $ */
+/* $NetBSD: prom.c,v 1.58 2020/10/03 17:31:46 thorpej Exp $ */
/*
* Copyright (c) 1992, 1994, 1995, 1996 Carnegie Mellon University
@@ -27,7 +27,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: prom.c,v 1.57 2020/09/27 23:16:10 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: prom.c,v 1.58 2020/10/03 17:31:46 thorpej Exp $");
#include "opt_multiprocessor.h"
@@ -64,6 +64,8 @@
static kmutex_t prom_lock;
+static struct linux_kernel_params qemu_kernel_params;
+
#ifdef _PROM_MAY_USE_PROM_CONSOLE
pt_entry_t prom_pte, saved_pte[1]; /* XXX */
@@ -137,6 +139,21 @@
prom_dispatch_v.routine_arg = c->crb_v_dispatch;
prom_dispatch_v.routine = c->crb_v_dispatch->entry_va;
+ if (alpha_is_qemu) {
+ /*
+ * Qemu has placed a Linux kernel parameter block
+ * at kernel_text[] - 0x6000. We ensure the command
+ * line field is always NUL-terminated to simplify
+ * things later.
+ */
+ extern char kernel_text[];
+ memcpy(&qemu_kernel_params,
+ (void *)((vaddr_t)kernel_text - 0x6000),
+ sizeof(qemu_kernel_params));
+ qemu_kernel_params.kernel_cmdline[
+ sizeof(qemu_kernel_params.kernel_cmdline) - 1] = '\0';
+ }
+
#ifdef _PROM_MAY_USE_PROM_CONSOLE
if (prom_uses_prom_console()) {
/*
@@ -170,6 +187,41 @@
cn_tab = &promcons;
}
+bool
+prom_qemu_getenv(const char *var, char *buf, size_t buflen)
+{
+ const size_t varlen = strlen(var);
+ const char *sp;
+
+ if (!alpha_is_qemu) {
+ return false;
+ }
+
+ sp = qemu_kernel_params.kernel_cmdline;
+ for (;;) {
+ sp = strstr(sp, var);
+ if (sp == NULL) {
+ return false;
+ }
+ sp += varlen;
+ if (*sp++ != '=') {
+ continue;
+ }
+ /* Found it. */
+ break;
+ }
+
+ while (--buflen) {
+ if (*sp == ' ' || *sp == '\t' || *sp == '\0') {
+ break;
+ }
+ *buf++ = *sp++;
+ }
+ *buf = '\0';
+
+ return true;
+}
+
#ifdef _PROM_MAY_USE_PROM_CONSOLE
static void prom_cache_sync(void);
#endif
diff -r 9afe6bee9ebc -r 9817b17b8808 sys/arch/alpha/include/alpha.h
--- a/sys/arch/alpha/include/alpha.h Sat Oct 03 17:30:54 2020 +0000
+++ b/sys/arch/alpha/include/alpha.h Sat Oct 03 17:31:46 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: alpha.h,v 1.41 2020/09/27 23:16:10 thorpej Exp $ */
+/* $NetBSD: alpha.h,v 1.42 2020/10/03 17:31:46 thorpej Exp $ */
/*
* Copyright (c) 1988 University of Utah.
@@ -73,6 +73,7 @@
extern int bootdev_debug;
extern int alpha_fp_sync_complete;
extern int alpha_unaligned_print, alpha_unaligned_fix, alpha_unaligned_sigbus;
+extern void (*alpha_delay_fn)(unsigned long);
void XentArith(uint64_t, uint64_t, uint64_t); /* MAGIC */
void XentIF(uint64_t, uint64_t, uint64_t); /* MAGIC */
diff -r 9afe6bee9ebc -r 9817b17b8808 sys/arch/alpha/include/prom.h
--- a/sys/arch/alpha/include/prom.h Sat Oct 03 17:30:54 2020 +0000
+++ b/sys/arch/alpha/include/prom.h Sat Oct 03 17:31:46 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: prom.h,v 1.15 2020/09/03 02:09:09 thorpej Exp $ */
+/* $NetBSD: prom.h,v 1.16 2020/10/03 17:31:46 thorpej Exp $ */
/*
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
@@ -46,6 +46,13 @@
uint64_t bits;
} prom_return_t;
+/* Linux kernel parameter block filled out by Qemu. */
+struct linux_kernel_params {
+ char kernel_cmdline[256];
+ uint64_t initrd_base;
+ uint64_t initrd_size;
+};
+
#ifdef _STANDALONE
int getchar(void);
void putchar(int);
@@ -53,6 +60,7 @@
void prom_halt(int) __attribute__((__noreturn__));
int prom_getenv(int, char *, int);
+bool prom_qemu_getenv(const char *, char *, size_t);
void hwrpb_primary_init(void);
void hwrpb_restart_setup(void);
Home |
Main Index |
Thread Index |
Old Index