Module Name: src
Committed By: thorpej
Date: Sat Oct 3 17:31:46 UTC 2020
Modified Files:
src/sys/arch/alpha/alpha: autoconf.c machdep.c prom.c
src/sys/arch/alpha/include: alpha.h prom.h
Log Message:
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.
To generate a diff of this commit:
cvs rdiff -u -r1.54 -r1.55 src/sys/arch/alpha/alpha/autoconf.c
cvs rdiff -u -r1.365 -r1.366 src/sys/arch/alpha/alpha/machdep.c
cvs rdiff -u -r1.57 -r1.58 src/sys/arch/alpha/alpha/prom.c
cvs rdiff -u -r1.41 -r1.42 src/sys/arch/alpha/include/alpha.h
cvs rdiff -u -r1.15 -r1.16 src/sys/arch/alpha/include/prom.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/alpha/alpha/autoconf.c
diff -u src/sys/arch/alpha/alpha/autoconf.c:1.54 src/sys/arch/alpha/alpha/autoconf.c:1.55
--- src/sys/arch/alpha/alpha/autoconf.c:1.54 Mon Sep 3 16:29:22 2018
+++ src/sys/arch/alpha/alpha/autoconf.c Sat Oct 3 17:31:46 2020
@@ -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 @@ cpu_configure(void)
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();
}
Index: src/sys/arch/alpha/alpha/machdep.c
diff -u src/sys/arch/alpha/alpha/machdep.c:1.365 src/sys/arch/alpha/alpha/machdep.c:1.366
--- src/sys/arch/alpha/alpha/machdep.c:1.365 Sun Sep 27 23:16:10 2020
+++ src/sys/arch/alpha/alpha/machdep.c Sat Oct 3 17:31:46 2020
@@ -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 @@ nobootinfo:
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 @@ setregs(register struct lwp *l, struct e
}
}
+void (*alpha_delay_fn)(unsigned long);
+
/*
* Wait "n" microseconds.
*/
@@ -1613,6 +1627,15 @@ delay(unsigned long n)
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;
Index: src/sys/arch/alpha/alpha/prom.c
diff -u src/sys/arch/alpha/alpha/prom.c:1.57 src/sys/arch/alpha/alpha/prom.c:1.58
--- src/sys/arch/alpha/alpha/prom.c:1.57 Sun Sep 27 23:16:10 2020
+++ src/sys/arch/alpha/alpha/prom.c Sat Oct 3 17:31:46 2020
@@ -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 @@ int prom_mapped = 1; /* Is PROM still m
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 @@ init_prom_interface(u_long ptb_pfn, stru
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 @@ init_bootstrap_console(void)
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
Index: src/sys/arch/alpha/include/alpha.h
diff -u src/sys/arch/alpha/include/alpha.h:1.41 src/sys/arch/alpha/include/alpha.h:1.42
--- src/sys/arch/alpha/include/alpha.h:1.41 Sun Sep 27 23:16:10 2020
+++ src/sys/arch/alpha/include/alpha.h Sat Oct 3 17:31:46 2020
@@ -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 u_long cpu_amask; /* from AMASK
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 */
Index: src/sys/arch/alpha/include/prom.h
diff -u src/sys/arch/alpha/include/prom.h:1.15 src/sys/arch/alpha/include/prom.h:1.16
--- src/sys/arch/alpha/include/prom.h:1.15 Thu Sep 3 02:09:09 2020
+++ src/sys/arch/alpha/include/prom.h Sat Oct 3 17:31:46 2020
@@ -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 @@ typedef union {
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 putchar(int);
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);