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);