summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasper Lievisse Adriaanse <jasper@cvs.openbsd.org>2013-04-08 09:42:27 +0000
committerJasper Lievisse Adriaanse <jasper@cvs.openbsd.org>2013-04-08 09:42:27 +0000
commitdf3046a19769349875443e00f396e021a4e2a890 (patch)
treec951ee5c4e969fb5ce9f8266f8988ab0621ec0f6
parent27c6fde252afa8dcfcc383029c9ff51df9aec9ba (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.c29
-rw-r--r--sys/arch/octeon/octeon/machdep.c48
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.
*/