diff options
author | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2013-04-08 09:42:27 +0000 |
---|---|---|
committer | Jasper Lievisse Adriaanse <jasper@cvs.openbsd.org> | 2013-04-08 09:42:27 +0000 |
commit | df3046a19769349875443e00f396e021a4e2a890 (patch) | |
tree | c951ee5c4e969fb5ce9f8266f8988ab0621ec0f6 | |
parent | 27c6fde252afa8dcfcc383029c9ff51df9aec9ba (diff) |
allow octeon to find it's root device, based on the flags passed by U-Boot. The ${bootcmd}
needs to be something like 'bootoctlinux root=/dev/octcf0'.
This will be temporary untill we have proper bootblocks, but for now, this (in combination)
with an upcoming installer diff allows my CAM-0100 to autoboot straight of the disk, without
having to load the kernel via TFTP.
ok bcallah@ yasuoka@
-rw-r--r-- | sys/arch/octeon/octeon/autoconf.c | 29 | ||||
-rw-r--r-- | sys/arch/octeon/octeon/machdep.c | 48 |
2 files changed, 74 insertions, 3 deletions
diff --git a/sys/arch/octeon/octeon/autoconf.c b/sys/arch/octeon/octeon/autoconf.c index f5f45e8f201..3a3d081af29 100644 --- a/sys/arch/octeon/octeon/autoconf.c +++ b/sys/arch/octeon/octeon/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.3 2012/06/17 11:02:32 miod Exp $ */ +/* $OpenBSD: autoconf.c,v 1.4 2013/04/08 09:42:26 jasper Exp $ */ /* * Copyright (c) 2009 Miodrag Vallat. * @@ -24,11 +24,13 @@ #include <machine/autoconf.h> extern void dumpconf(void); +void parse_uboot_root(void); int cold = 1; struct device *bootdv = NULL; char bootdev[16]; enum devclass bootdev_class = DV_DULL; +extern char uboot_rootdev[]; void cpu_configure(void) @@ -43,6 +45,29 @@ cpu_configure(void) } void +parse_uboot_root(void) +{ + char *p; + size_t len; + + /* + * Turn the U-Boot root device (root=/dev/octcf0) into a boot device. + */ + p = strrchr(uboot_rootdev, '/'); + if (p == NULL) + return; + p++; + + len = strlen(p); + if (len <= 2 || len >= sizeof bootdev - 1) + return; + + memcpy(bootdev, p, len); + bootdev[len] = '\0'; + bootdev_class = DV_DISK; +} + +void diskconf(void) { if (bootdv != NULL) @@ -62,7 +87,7 @@ device_register(struct device *dev, void *aux) const char *name = dev->dv_xname; if (dev->dv_class != bootdev_class) - return; + return; switch (bootdev_class) { case DV_DISK: diff --git a/sys/arch/octeon/octeon/machdep.c b/sys/arch/octeon/octeon/machdep.c index 8051195bca4..07c386aa973 100644 --- a/sys/arch/octeon/octeon/machdep.c +++ b/sys/arch/octeon/octeon/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.32 2013/04/06 07:53:57 jasper Exp $ */ +/* $OpenBSD: machdep.c,v 1.33 2013/04/08 09:42:26 jasper Exp $ */ /* * Copyright (c) 2009, 2010 Miodrag Vallat. @@ -95,6 +95,8 @@ vm_map_t phys_map; struct boot_desc *octeon_boot_desc; struct boot_info *octeon_boot_info; +char uboot_rootdev[OCTEON_ARGV_MAX]; + /* * safepri is a safe priority for sleep to set for a spin-wait * during autoconfiguration or after a panic. @@ -122,6 +124,9 @@ vaddr_t mips_init(__register_t, __register_t, __register_t, __register_t); boolean_t is_memory_range(paddr_t, psize_t, psize_t); void octeon_memory_init(struct boot_info *); int octeon_cpuspeed(int *); +static void process_bootargs(void); + +extern void parse_uboot_root(void); cons_decl(cn30xxuart); struct consdev uartcons = cons_init(cn30xxuart); @@ -375,6 +380,8 @@ mips_init(__register_t a0, __register_t a1, __register_t a2 __unused, cpu_cpuspeed = octeon_cpuspeed; + process_bootargs(); + /* * Get a console, very early but after initial mapping setup. */ @@ -555,6 +562,45 @@ octeon_cpuspeed(int *freq) return (0); } + +static void +process_bootargs(void) +{ + int i; + extern struct boot_desc *octeon_boot_desc; + + /* + * The kernel is booted via a bootoctlinux command. Thus we need to skip + * argv[0] when we start to decode the boot arguments (${bootargs}). + * Note that U-Boot doesn't pass us anything by default, we need + * explicitly pass the rootdevice. + */ + for (i = 1; i < octeon_boot_desc->argc; i++ ) { + const char *arg = + (const char*)PHYS_TO_CKSEG0(octeon_boot_desc->argv[i]); + + if (arg == NULL) + continue; + +#ifdef DEBUG + printf("boot_desc->argv[%d] = %s\n", + i, PHYS_TO_CKSEG0(octeon_boot_desc->argv[i])); +#endif + + /* + * XXX: We currently only expect one other argument, + * argv[1], root=ROOTDEV. + */ + if (strncmp(arg, "root=", 5) == 0) { + if (*uboot_rootdev == '\0') { + strlcpy(uboot_rootdev, arg, + sizeof(uboot_rootdev)); + parse_uboot_root(); + } + } + } +} + /* * Machine dependent system variables. */ |