summaryrefslogtreecommitdiff
path: root/sys/arch/armish/stand
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2006-07-29 15:01:50 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2006-07-29 15:01:50 +0000
commit20ec1696e0640c3e063f6ce869fe0cfa0c5c4587 (patch)
tree650b44e18f63a4b9c710be73cf52dad5109e14a1 /sys/arch/armish/stand
parentc11c824cade1312eaf5ad0179468c582be542193 (diff)
ework armish bootloader into an interactive one, much like i386 has.
Make sure disk names match those used by the kernel. This means that now it boots from wd0 by default, whatever slot it is in.
Diffstat (limited to 'sys/arch/armish/stand')
-rw-r--r--sys/arch/armish/stand/boot/Makefile20
-rw-r--r--sys/arch/armish/stand/boot/boot.c75
-rw-r--r--sys/arch/armish/stand/boot/clock.c5
-rw-r--r--sys/arch/armish/stand/boot/conf.c22
-rw-r--r--sys/arch/armish/stand/boot/dev_armish.c115
-rw-r--r--sys/arch/armish/stand/boot/devopen.c67
-rw-r--r--sys/arch/armish/stand/boot/libsa.h (renamed from sys/arch/armish/stand/boot/boot.h)21
-rw-r--r--sys/arch/armish/stand/boot/machdep.c69
-rw-r--r--sys/arch/armish/stand/boot/ns16550.c38
-rw-r--r--sys/arch/armish/stand/boot/pciide.c54
-rw-r--r--sys/arch/armish/stand/boot/time.c12
-rw-r--r--sys/arch/armish/stand/boot/wd.c63
-rw-r--r--sys/arch/armish/stand/boot/wdc.c70
-rw-r--r--sys/arch/armish/stand/boot/wdvar.h41
14 files changed, 396 insertions, 276 deletions
diff --git a/sys/arch/armish/stand/boot/Makefile b/sys/arch/armish/stand/boot/Makefile
index f2cb95d2d55..e5d91f24a9b 100644
--- a/sys/arch/armish/stand/boot/Makefile
+++ b/sys/arch/armish/stand/boot/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.3 2006/07/29 00:48:52 deraadt Exp $
+# $OpenBSD: Makefile,v 1.4 2006/07/29 15:01:49 kettenis Exp $
NOMAN=
@@ -6,14 +6,20 @@ NOMAN=
PROG= boot
S= ${.CURDIR}/../../../..
-CPPFLAGS+= -nostdinc -I../.. -I. -I${S} -D_STANDALONE
-CPPFLAGS+= -DCONSPEED=115200
-CPPFLAGS+= -DCONADDR=0xfe800000UL
+.PATH: ${S}/stand/boot
+.PATH: ${S}/lib/libsa
-COPTS+= -ffreestanding -fno-stack-protector -malignment-traps
+CPPFLAGS+= -D_STANDALONE
+CPPFLAGS+= -nostdinc -I../.. -I. -I${.CURDIR} -I${S}
+CPPFLAGS+= -DCONADDR=0xfe800000UL -DCONSPEED=115200
-SRCS= start.S boot.c conf.c clock.c ns16550.c wd.c wdc.c pciide.c
-SRCS+= devopen.c exec.c
+COPTS+= -ffreestanding -fno-stack-protector
+
+SRCS= start.S
+SRCS+= boot.c cmd.c vars.c
+SRCS+= conf.c devopen.c exec.c machdep.c dev_armish.c time.c
+SRCS+= clock.c ns16550.c wd.c wdc.c pciide.c
+SRCS+= ctime.c strtol.c
### find out what to use for libkern
KERN_AS= library
diff --git a/sys/arch/armish/stand/boot/boot.c b/sys/arch/armish/stand/boot/boot.c
deleted file mode 100644
index ed47f80bc92..00000000000
--- a/sys/arch/armish/stand/boot/boot.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/* $OpenBSD: boot.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
-
-/*
- * Copyright (c) 2006 Mark Kettenis
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <lib/libsa/stand.h>
-#include <lib/libsa/loadfile.h>
-
-int
-main(void)
-{
- u_long marks[MARK_MAX];
-
- cons_init();
-
- printf("OpenBSD/armish boot\n");
-
- printf("OIOWTVR: 0x%x\n", *((volatile uint32_t *)0xffffe15c));
- printf("ATUCR: 0x%x\n", *((volatile uint32_t *)0xffffe180));
- printf("ATU_OIOWTVR: 0x%x\n", *((volatile uint32_t *)0xffffe15c));
- printf("ATU_OMWTVR0: 0x%x\n", *((volatile uint32_t *)0xffffe160));
- printf("ATU_OUMWTVR0: 0x%x\n", *((volatile uint32_t *)0xffffe164));
- printf("ATU_OMWTVR1: 0x%x\n", *((volatile uint32_t *)0xffffe168));
- printf("ATU_OUMWTVR1: 0x%x\n", *((volatile uint32_t *)0xffffe16c));
- volatile uint32_t *p = ((volatile uint32_t *)0xffffe180);
- *p = 1<<1;
- printf("ATUCR: 0x%x\n", *((volatile uint32_t *)0xffffe180));
-
-#define L1_S_SHIFT 20
- {
- uint32_t *pde;
-
- __asm volatile("mrc p15, 0, %0, c2, c0, 0" : "=r" (pde));
-
- printf("pde %x\n", pde);
- pde = (uint32_t *)((uint32_t) pde & 0x0fffffff);
- printf("mapping of %x is %x\n", p, pde[(u_int32_t)p >> L1_S_SHIFT]);
- p = (u_int32_t *)0x90000000;
- printf("mapping of %x is %x\n", p, pde[(u_int32_t)p >> L1_S_SHIFT]);
- p = (u_int32_t *)0xa0000000;
- printf("mapping of %x is %x\n", p, pde[(u_int32_t)p >> L1_S_SHIFT]);
- p = (u_int32_t *)0x00000000;
- printf("mapping of %x is %x\n", p, pde[(u_int32_t)p >> L1_S_SHIFT]);
-
- p = (u_int32_t *)0x90000000;
- pde[(u_int32_t)p >> L1_S_SHIFT] = ((uint32_t)p & 0xfff00000) | 0xc02;
- printf("new mapping of %x is %x\n", p, pde[(u_int32_t)p >> L1_S_SHIFT]);
-
- }
-
- marks[MARK_START] = 0;
- if (loadfile("wd2a:/bsd", marks, LOAD_ALL) < 0) {
- printf("loadfile: errno %\n", errno);
- goto err;
- }
-
- run_loadfile(marks, 0);
-
- err:
- printf("halted...");
- for (;;) ;
-}
diff --git a/sys/arch/armish/stand/boot/clock.c b/sys/arch/armish/stand/boot/clock.c
index d3f1a61dee7..99d7ddb1a1a 100644
--- a/sys/arch/armish/stand/boot/clock.c
+++ b/sys/arch/armish/stand/boot/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: clock.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: clock.c,v 1.1 2003/06/25 17:24:22 cdi Exp $ */
/*-
@@ -38,9 +38,8 @@
*/
#include <sys/types.h>
-#include <lib/libsa/stand.h>
-#include "boot.h"
+#include "libsa.h"
#define DELAY_CALIBRATE 1000
diff --git a/sys/arch/armish/stand/boot/conf.c b/sys/arch/armish/stand/boot/conf.c
index 65145648755..4fe508eb61d 100644
--- a/sys/arch/armish/stand/boot/conf.c
+++ b/sys/arch/armish/stand/boot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: conf.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: conf.c,v 1.4 2005/12/11 12:17:06 christos Exp $ */
/*
@@ -34,10 +34,13 @@
#include <sys/param.h>
-#include <lib/libsa/stand.h>
+#include <dev/cons.h>
+
+#include "libsa.h"
#include <lib/libsa/ufs.h>
-#include "boot.h"
+const char version[] = "0.9";
+int debug = 0;
/*
* Device configuration
@@ -45,8 +48,7 @@
struct devsw devsw[] = {
{ "wd", wdstrategy, wdopen, wdclose, noioctl },
};
-
-int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
+int ndevs = NENTS(devsw);
/*
* Filesystem configuration
@@ -55,5 +57,13 @@ struct fs_ops file_system[] = {
{ ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek,
ufs_stat, ufs_readdir }
};
+int nfsys = NENTS(file_system);
-int nfsys = sizeof(file_system) / sizeof(file_system[0]);
+/*
+ * Console configuration
+ */
+struct consdev constab[] = {
+ { com_probe, com_init, com_getc, com_putc },
+ { NULL }
+};
+struct consdev *cn_tab;
diff --git a/sys/arch/armish/stand/boot/dev_armish.c b/sys/arch/armish/stand/boot/dev_armish.c
new file mode 100644
index 00000000000..40e0293f07a
--- /dev/null
+++ b/sys/arch/armish/stand/boot/dev_armish.c
@@ -0,0 +1,115 @@
+/* $OpenBSD: dev_armish.c,v 1.1 2006/07/29 15:01:49 kettenis Exp $ */
+
+/*
+ * Copyright (c) 2006 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <dev/cons.h>
+
+#include "libsa.h"
+
+const char cdevs[][4] = {
+ "cn", "", "", "", "", "", "", "",
+ "", "", "", "", "com"
+};
+const int ncdevs = NENTS(cdevs);
+
+void
+devboot(dev_t dev, char *p)
+{
+ strlcpy(p, "wd0a", 5);
+}
+
+int
+cnspeed(dev_t dev, int sp)
+{
+ return CONSPEED;
+}
+
+int pch_pos;
+
+void
+putchar(c)
+ int c;
+{
+ switch(c) {
+ case '\177': /* DEL erases */
+ cnputc('\b');
+ cnputc(' ');
+ case '\b':
+ cnputc('\b');
+ if (pch_pos)
+ pch_pos--;
+ break;
+ case '\t':
+ do
+ cnputc(' ');
+ while(++pch_pos % 8);
+ break;
+ case '\n':
+ case '\r':
+ cnputc(c);
+ pch_pos=0;
+ break;
+ default:
+ cnputc(c);
+ pch_pos++;
+ break;
+ }
+}
+
+int
+getchar()
+{
+ int c = cngetc();
+
+ if (c == '\r')
+ c = '\n';
+
+ if ((c < ' ' && c != '\n') || c == '\177')
+ return(c);
+
+ putchar(c);
+
+ return(c);
+}
+
+char ttyname_buf[8];
+
+char *
+ttyname(int fd)
+{
+ snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d",
+ cdevs[major(cn_tab->cn_dev)], minor(cn_tab->cn_dev));
+
+ return ttyname_buf;
+}
+
+dev_t
+ttydev(char *name)
+{
+ int i, unit = -1;
+ char *no = name + strlen(name) - 1;
+
+ while (no >= name && *no >= '0' && *no <= '9')
+ unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
+ if (no < name || unit < 0)
+ return NODEV;
+ for (i = 0; i < ncdevs; i++)
+ if (strncmp(name, cdevs[i], no - name + 1) == 0)
+ return (makedev(i, unit));
+ return NODEV;
+}
diff --git a/sys/arch/armish/stand/boot/devopen.c b/sys/arch/armish/stand/boot/devopen.c
index 78521074535..5cb7b5c2dc9 100644
--- a/sys/arch/armish/stand/boot/devopen.c
+++ b/sys/arch/armish/stand/boot/devopen.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: devopen.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: devopen.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: devopen.c,v 1.1 2003/06/25 17:24:22 cdi Exp $ */
/*-
@@ -37,55 +37,46 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
-#include <lib/libsa/stand.h>
+#include "libsa.h"
-#include "boot.h"
+#define MAXDEVNAME 16
/*
* Parse a device spec.
*
- * Format:
- * [device:][filename]
+ * [A-Za-z]*[0-9]*[A-Za-z]:file
+ * dev uint part
*/
int
-devparse(const char *fname, int *dev, u_int8_t *unit,
- u_int8_t *part, const char **file)
+devparse(const char *fname, int *dev, int *unit, int *part, const char **file)
{
- const char *col;
+ const char *s;
*unit = 0; /* default to wd0a */
*part = 0;
*dev = 0;
- *file = DEFKERNELNAME;
- if (fname == NULL)
- return (0);
-
- if ( (col = strchr(fname, ':')) != NULL) {
+ s = strchr(fname, ':');
+ if (s != NULL) {
int devlen;
- u_int8_t i, u, p;
+ int i, u, p;
struct devsw *dp;
char devname[MAXDEVNAME];
- devlen = col - fname;
+ devlen = s - fname;
if (devlen > MAXDEVNAME)
return (EINVAL);
-#define isnum(c) (((c) >= '0') && ((c) <= '9'))
-#if 0
-#define isalpha(c) (((c) >= 'a') && ((c) <= 'z'))
-#endif
-
/* extract device name */
for (i = 0; isalpha(fname[i]) && (i < devlen); i++)
devname[i] = fname[i];
devname[i] = 0;
- if (!isnum(fname[i]))
+ if (!isdigit(fname[i]))
return (EUNIT);
/* device number */
- for (u = 0; isnum(fname[i]) && (i < devlen); i++)
+ for (u = 0; isdigit(fname[i]) && (i < devlen); i++)
u = u * 10 + (fname[i] - '0');
if (!isalpha(fname[i]))
@@ -110,11 +101,10 @@ devparse(const char *fname, int *dev, u_int8_t *unit,
*unit = u;
*part = p;
*dev = i;
- fname = ++col;
+ fname = ++s;
}
- if (*fname)
- *file = fname;
+ *file = fname;
return (0);
}
@@ -122,25 +112,18 @@ devparse(const char *fname, int *dev, u_int8_t *unit,
int
devopen(struct open_file *f, const char *fname, char **file)
{
- struct devsw *dp;
- u_int8_t unit, part;
- int dev, error;
-
- DPRINTF(("devopen(%s)\n", fname));
+ struct devsw *dp;
+ int dev, unit, part, error;
- if ( (error = devparse(fname, &dev, &unit, &part,
- (const char **)file)) != 0)
- return error;
+ error = devparse(fname, &dev, &unit, &part, (const char **)file);
+ if (error)
+ return (error);
- dp = &devsw[dev];
- if ((void *)dp->dv_open == (void *)nodev)
- return ENXIO;
+ dp = &devsw[dev];
+ if ((void *)dp->dv_open == (void *)nodev)
+ return (ENXIO);
- f->f_dev = dp;
-
- if ( (error = (*dp->dv_open)(f, unit, part)) != 0)
- printf("%s%d%c: %d = %s\n", devsw[dev].dv_name,
- unit, 'a' + part, error, strerror(error));
+ f->f_dev = dp;
- return error;
+ return (*dp->dv_open)(f, unit, part);
}
diff --git a/sys/arch/armish/stand/boot/boot.h b/sys/arch/armish/stand/boot/libsa.h
index c5499e34ac5..db8403024ac 100644
--- a/sys/arch/armish/stand/boot/boot.h
+++ b/sys/arch/armish/stand/boot/libsa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: boot.h,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: libsa.h,v 1.1 2006/07/29 15:01:49 kettenis Exp $ */
/*
* Copyright (c) 2006 Mark Kettenis
@@ -16,12 +16,23 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#define DPRINTF(x) printf x;
+#include <lib/libsa/stand.h>
+
+#define DEFAULT_KERNEL_ADDRESS 0
-#define MAXDEVNAME 16
-#define DEFBOOTDEV "wd0a"
-#define DEFKERNELNAME "bsd"
+#ifdef DEBUG
+#define DPRINTF(x) printf x;
+#else
+#define DPRINTF(x)
+#endif
+/*
+ * com
+ */
+void com_probe(struct consdev *);
+void com_init(struct consdev *);
+int com_getc(dev_t);
+void com_putc(dev_t, int);
/*
* wd
diff --git a/sys/arch/armish/stand/boot/machdep.c b/sys/arch/armish/stand/boot/machdep.c
new file mode 100644
index 00000000000..d23a1f45380
--- /dev/null
+++ b/sys/arch/armish/stand/boot/machdep.c
@@ -0,0 +1,69 @@
+/* $OpenBSD: machdep.c,v 1.1 2006/07/29 15:01:49 kettenis Exp $ */
+
+/*
+ * Copyright (c) 2006 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/types.h>
+#include <arm/pte.h>
+
+#include "libsa.h"
+
+#define L1_IDX(va) (((uint32_t)(va)) >> L1_S_SHIFT)
+
+#define ATU_OIOWTVR 0xffffe15c
+#define ATU_ATUCR 0xffffe180
+
+#define ATUCR_OUT_EN (1U << 1)
+
+void
+machdep(void)
+{
+ uint32_t *pde;
+ uint32_t va;
+
+ /*
+ * Clean up the mess that RedBoot left us in, amd make sure we
+ * can access the PCI bus.
+ */
+
+ *((volatile uint32_t *)(ATU_ATUCR)) = ATUCR_OUT_EN;
+
+ __asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r" (pde));
+ pde = (uint32_t *)((uint32_t)pde & 0x0fffffff);
+
+ va = *((volatile uint32_t *)(ATU_OIOWTVR));
+ pde[L1_IDX(va)] = (va & L1_ADDR_BITS) | L1_S_AP(AP_KRWUR) | L1_TYPE_S;
+
+ /* Start timer */
+ __asm volatile ("mcr p6, 0, %0, c3, c1, 0" :: "r" (0xffffffff));
+ __asm volatile ("mcr p6, 0, %0, c1, c1, 0" :: "r" (0x00000032));
+
+ cninit();
+}
+
+int
+main(void)
+{
+ boot(0);
+ return 0;
+}
+
+void
+_rtt(void)
+{
+ printf("halted...");
+ for (;;) ;
+}
diff --git a/sys/arch/armish/stand/boot/ns16550.c b/sys/arch/armish/stand/boot/ns16550.c
index 66690e8eb2c..7f9a14e9719 100644
--- a/sys/arch/armish/stand/boot/ns16550.c
+++ b/sys/arch/armish/stand/boot/ns16550.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ns16550.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: ns16550.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: ns16550.c,v 1.3 2005/12/24 20:07:03 perry Exp $ */
/*
@@ -37,13 +37,16 @@
*/
/*
- * This file provides the cons_init() function and console I/O routines
- * for boards that use 16550-compatible UARTs.
+ * This file provides console I/O routines for boards that use
+ * 16550-compatible UARTs.
*/
#include <sys/types.h>
+
+#include <dev/cons.h>
#include <dev/ic/comreg.h>
-#include <lib/libsa/stand.h>
+
+#include "libsa.h"
#define INB(x) *((volatile uint8_t *) (CONADDR + (x)))
#define OUTB(x, v) *((volatile uint8_t *) (CONADDR + (x))) = (v)
@@ -76,7 +79,14 @@ comspeed(int speed)
}
void
-cons_init(void)
+com_probe(struct consdev *cn)
+{
+ cn->cn_pri = CN_NORMAL;
+ cn->cn_dev = makedev(12, 0);
+}
+
+void
+com_init(struct consdev *cn)
{
int rate;
@@ -92,17 +102,20 @@ cons_init(void)
}
int
-getchar(void)
+com_getc(dev_t dev)
{
uint8_t stat;
+ if (dev & 0x80)
+ return ISSET(stat = INB(com_lsr), LSR_RXRDY);
+
while (!ISSET(stat = INB(com_lsr), LSR_RXRDY))
/* spin */ ;
return (INB(com_data));
}
-static void
-iputchar(int c)
+void
+com_putc(dev_t dev, int c)
{
uint8_t stat;
int timo;
@@ -122,12 +135,3 @@ iputchar(int c)
/* Clear any interrupts generated by this transmission. */
(void) INB(com_iir);
}
-
-void
-putchar(int c)
-{
-
- if (c == '\n')
- iputchar('\r');
- iputchar(c);
-}
diff --git a/sys/arch/armish/stand/boot/pciide.c b/sys/arch/armish/stand/boot/pciide.c
index 97cc4885186..f27f173e982 100644
--- a/sys/arch/armish/stand/boot/pciide.c
+++ b/sys/arch/armish/stand/boot/pciide.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pciide.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: pciide.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: pciide.c,v 1.5 2005/12/11 12:17:06 christos Exp $ */
/*-
@@ -35,64 +35,30 @@
*/
#include <sys/types.h>
-#include <lib/libsa/stand.h>
-#include "boot.h"
+#include "libsa.h"
#include "wdvar.h"
-/*
- * WD1003 / ATA Disk Controller register definitions.
- */
-
-/* offsets of registers in the 'regular' register region */
-#define wd_data 0 /* data register (R/W - 16 bits) */
-#define wd_error 1 /* error register (R) */
-#define wd_precomp 1 /* write precompensation (W) */
-#define wd_seccnt 2 /* sector count (R/W) */
-#define wd_ireason 2 /* interrupt reason (R/W) (for atapi) */
-#define wd_sector 3 /* first sector number (R/W) */
-#define wd_cyl_lo 4 /* cylinder address, low byte (R/W) */
-#define wd_cyl_hi 5 /* cylinder address, high byte (R/W) */
-#define wd_sdh 6 /* sector size/drive/head (R/W) */
-#define wd_command 7 /* command register (W) */
-#define wd_lba_lo 3 /* lba address, low byte (RW) */
-#define wd_lba_mi 4 /* lba address, middle byte (RW) */
-#define wd_lba_hi 5 /* lba address, high byte (RW) */
-
-/* "shadow" registers; these may or may not overlap regular registers */
-#define wd_status 8 /* immediate status (R) */
-#define wd_features 9 /* features (W) */
-
-/* offsets of registers in the auxiliary register region */
-#define wd_aux_altsts 0 /* alternate fixed disk status (R) */
-#define wd_aux_ctlr 0 /* fixed disk controller control (W) */
-#define WDCTL_4BIT 0x08 /* use four head bits (wd1003) */
-#define WDCTL_RST 0x04 /* reset the controller */
-#define WDCTL_IDS 0x02 /* disable controller interrupts */
-
int
-pciide_init(chp, unit)
- struct wdc_channel *chp;
- u_int *unit;
+pciide_init(struct wdc_channel *chp, u_int chan)
{
u_int32_t cmdreg, ctlreg;
- int i, compatchan = 0;
+ int i;
/*
- * two channels per chip, two drives per channel
+ * two channels per chip, one drive per channel
*/
- compatchan = *unit / PCIIDE_CHANNEL_NDEV;
- if (compatchan >= PCIIDE_NUM_CHANNELS)
+ if (chan >= PCIIDE_NUM_CHANNELS)
return (ENXIO);
- *unit %= PCIIDE_CHANNEL_NDEV;
+ chp->ndrives = 1;
- DPRINTF(("[pciide] unit: %d, channel: %d\n", *unit, compatchan));
+ DPRINTF(("[pciide] channel: %d\n", chan));
/*
* XXX map?
*/
- cmdreg = 0x90000200 + compatchan * 0x10;
- ctlreg = 0x90000208 + compatchan * 0x10;
+ cmdreg = 0x90000200 + chan * 0x10;
+ ctlreg = 0x90000208 + chan * 0x10;
/* set up cmd regsiters */
chp->c_cmdbase = (u_int8_t *)cmdreg;
diff --git a/sys/arch/armish/stand/boot/time.c b/sys/arch/armish/stand/boot/time.c
new file mode 100644
index 00000000000..1b0e9fcc838
--- /dev/null
+++ b/sys/arch/armish/stand/boot/time.c
@@ -0,0 +1,12 @@
+#include <sys/types.h>
+
+#include "libsa.h"
+
+time_t
+getsecs(void)
+{
+ uint32_t count;
+
+ __asm volatile ("mrc p6, 0, %0, c3, c1, 0" : "=r" (count));
+ return ((0xffffffff - count) / 12500000);
+}
diff --git a/sys/arch/armish/stand/boot/wd.c b/sys/arch/armish/stand/boot/wd.c
index f907d271e1a..7fc9fceac41 100644
--- a/sys/arch/armish/stand/boot/wd.c
+++ b/sys/arch/armish/stand/boot/wd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wd.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: wd.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: wd.c,v 1.5 2005/12/11 12:17:06 christos Exp $ */
/*-
@@ -40,15 +40,43 @@
#include <sys/types.h>
#include <sys/stdint.h>
-#include <lib/libsa/stand.h>
#include <machine/param.h>
-#include "boot.h"
+#include "libsa.h"
#include "wdvar.h"
-static int wd_get_params(struct wd_softc *wd);
-static int wdgetdisklabel(struct wd_softc *wd);
-static void wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp);
+void wdprobe(void);
+int wd_get_params(struct wd_softc *wd);
+int wdgetdisklabel(struct wd_softc *wd);
+void wdgetdefaultlabel(struct wd_softc *wd, struct disklabel *lp);
+
+struct wd_softc wd_devs[NUNITS];
+int wd_ndevs = -1;
+
+void
+wdprobe(void)
+{
+ struct wd_softc *wd = wd_devs;
+ u_int chan, drive, unit = 0;
+
+ for (chan = 0; chan < PCIIDE_NUM_CHANNELS; chan++) {
+ if (wdc_init(wd, chan) != 0)
+ continue;
+ for (drive = 0; drive < wd->sc_channel.ndrives; drive++) {
+ wd->sc_unit = unit;
+ wd->sc_drive = drive;
+
+ if (wd_get_params(wd) != 0)
+ continue;
+
+ DPRINTF(("wd%d: channel %d drive %d\n",
+ unit, chan, drive));
+ unit++;
+ }
+ }
+
+ wd_ndevs = unit;
+}
/*
* Get drive parameters through 'device identify' command.
@@ -199,7 +227,7 @@ wdopen(struct open_file *f, ...)
{
int error;
va_list ap;
- u_int unit, part;
+ u_int unit, part, drive;
struct wd_softc *wd;
va_start(ap, f);
@@ -207,26 +235,23 @@ wdopen(struct open_file *f, ...)
part = va_arg(ap, u_int);
va_end(ap);
- DPRINTF(("wdopen: %d:%d\n", unit, part));
+ DPRINTF(("wdopen: wd%d%c\n", unit, 'a' + part));
- wd = alloc(sizeof(struct wd_softc));
- if (wd == NULL)
- return ENOMEM;
+ if (unit < 0 || unit >= NUNITS)
+ return (ENXIO);
- memset(wd, 0, sizeof(struct wd_softc));
+ if (wd_ndevs == -1)
+ wdprobe();
- if (wdc_init(wd, &unit) != 0)
+ if (unit >= wd_ndevs)
return (ENXIO);
+ wd = &wd_devs[unit];
wd->sc_part = part;
- wd->sc_unit = unit;
- if ( (error = wd_get_params(wd)) != 0)
+ if ((error = wdgetdisklabel(wd)) != 0)
return (error);
- if ( (error = wdgetdisklabel(wd)) != 0)
- return error;
-
f->f_devdata = wd;
return (0);
}
@@ -268,7 +293,7 @@ wdstrategy(f, rw, dblk, size, buf, rsize)
for (i = 0; i < nsect; i++, blkno++) {
int error;
- if ( (error = wdc_exec_read(wd, WDCC_READ, blkno, buf)) != 0)
+ if ((error = wdc_exec_read(wd, WDCC_READ, blkno, buf)) != 0)
return (error);
buf += wd->sc_label.d_secsize;
diff --git a/sys/arch/armish/stand/boot/wdc.c b/sys/arch/armish/stand/boot/wdc.c
index d6e151dc175..562dddcc203 100644
--- a/sys/arch/armish/stand/boot/wdc.c
+++ b/sys/arch/armish/stand/boot/wdc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdc.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: wdc.c,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: wdc.c,v 1.7 2005/12/11 12:17:06 christos Exp $ */
/*-
@@ -38,47 +38,11 @@
*/
#include <sys/types.h>
-#if 0
-#include <sys/disklabel.h>
-#endif
-
-#include <lib/libsa/stand.h>
#include <machine/param.h>
-#include "boot.h"
+#include "libsa.h"
#include "wdvar.h"
-/*
- * WD1003 / ATA Disk Controller register definitions.
- */
-
-/* offsets of registers in the 'regular' register region */
-#define wd_data 0 /* data register (R/W - 16 bits) */
-#define wd_error 1 /* error register (R) */
-#define wd_precomp 1 /* write precompensation (W) */
-#define wd_seccnt 2 /* sector count (R/W) */
-#define wd_ireason 2 /* interrupt reason (R/W) (for atapi) */
-#define wd_sector 3 /* first sector number (R/W) */
-#define wd_cyl_lo 4 /* cylinder address, low byte (R/W) */
-#define wd_cyl_hi 5 /* cylinder address, high byte (R/W) */
-#define wd_sdh 6 /* sector size/drive/head (R/W) */
-#define wd_command 7 /* command register (W) */
-#define wd_lba_lo 3 /* lba address, low byte (RW) */
-#define wd_lba_mi 4 /* lba address, middle byte (RW) */
-#define wd_lba_hi 5 /* lba address, high byte (RW) */
-
-/* "shadow" registers; these may or may not overlap regular registers */
-#define wd_status 8 /* immediate status (R) */
-#define wd_features 9 /* features (W) */
-
-/* offsets of registers in the auxiliary register region */
-#define wd_aux_altsts 0 /* alternate fixed disk status (R) */
-#define wd_aux_ctlr 0 /* fixed disk controller control (W) */
-#define WDCTL_4BIT 0x08 /* use four head bits (wd1003) */
-#define WDCTL_RST 0x04 /* reset the controller */
-#define WDCTL_IDS 0x02 /* disable controller interrupts */
-
-
#define WDCDELAY 100
#define WDCNDELAY_RST 31000 * 10
@@ -214,7 +178,7 @@ wdcprobe(chp)
int
wdc_init(sc, unit)
struct wd_softc *sc;
- u_int *unit;
+ u_int unit;
{
if (pciide_init(&sc->sc_channel, unit) != 0)
return (ENXIO);
@@ -264,18 +228,18 @@ wdc_read_block(sc, wd_c)
* Send a command to the device (CHS and LBA addressing).
*/
int
-wdccommand(sc, wd_c)
- struct wd_softc *sc;
+wdccommand(wd, wd_c)
+ struct wd_softc *wd;
struct wdc_command *wd_c;
{
u_int8_t err;
- struct wdc_channel *chp = &sc->sc_channel;
+ struct wdc_channel *chp = &wd->sc_channel;
#if 0
DPRINTF(("wdccommand(%d, %d, %d, %d, %d, %d, %d)\n",
- wd_c->drive, wd_c->r_command, wd_c->r_cyl,
- wd_c->r_head, wd_c->r_sector, wd_c->bcount,
- wd_c->r_precomp));
+ wd_c->drive, wd_c->r_command, wd_c->r_cyl,
+ wd_c->r_head, wd_c->r_sector, wd_c->bcount,
+ wd_c->r_precomp));
#endif
WDC_WRITE_REG(chp, wd_precomp, wd_c->r_precomp);
@@ -291,8 +255,8 @@ wdccommand(sc, wd_c)
return (ENXIO);
if (WDC_READ_REG(chp, wd_status) & WDCS_ERR) {
- printf("wd%d: error %x\n", chp->compatchan,
- WDC_READ_REG(chp, wd_error));
+ DPRINTF(("wd%d: error %x\n", wd->sc_unit,
+ WDC_READ_REG(chp, wd_error)));
return (ENXIO);
}
@@ -334,8 +298,8 @@ wdccommandext(wd, wd_c)
return (ENXIO);
if (WDC_READ_REG(chp, wd_status) & WDCS_ERR) {
- printf("wd%d: error %x\n", chp->compatchan,
- WDC_READ_REG(chp, wd_error));
+ DPRINTF(("wd%d: error %x\n", wd->sc_unit,
+ WDC_READ_REG(chp, wd_error)));
return (ENXIO);
}
@@ -355,12 +319,12 @@ wdc_exec_identify(wd, data)
memset(&wd_c, 0, sizeof(wd_c));
- wd_c.drive = wd->sc_unit;
+ wd_c.drive = wd->sc_drive;
wd_c.r_command = WDCC_IDENTIFY;
wd_c.bcount = DEV_BSIZE;
wd_c.data = data;
- if ( (error = wdccommand(wd, &wd_c)) != 0)
+ if ((error = wdccommand(wd, &wd_c)) != 0)
return (error);
return wdc_read_block(wd, &wd_c);
@@ -403,7 +367,7 @@ wdc_exec_read(wd, cmd, blkno, data)
wd_c.data = data;
wd_c.r_count = 1;
- wd_c.drive = wd->sc_unit;
+ wd_c.drive = wd->sc_drive;
wd_c.r_command = cmd;
wd_c.bcount = wd->sc_label.d_secsize;
@@ -413,7 +377,7 @@ wdc_exec_read(wd, cmd, blkno, data)
error = wdccommand(wd, &wd_c);
if (error != 0)
- return error;
+ return (error);
return wdc_read_block(wd, &wd_c);
}
diff --git a/sys/arch/armish/stand/boot/wdvar.h b/sys/arch/armish/stand/boot/wdvar.h
index 57e9076b941..7ab338b7f8f 100644
--- a/sys/arch/armish/stand/boot/wdvar.h
+++ b/sys/arch/armish/stand/boot/wdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: wdvar.h,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $OpenBSD: wdvar.h,v 1.2 2006/07/29 15:01:49 kettenis Exp $ */
/* $NetBSD: wdvar.h,v 1.6 2005/12/11 12:17:06 christos Exp $ */
/*-
@@ -34,11 +34,41 @@
#ifndef _STAND_WDVAR_H
#define _STAND_WDVAR_H
+#include <sys/disklabel.h>
+
#include <dev/ic/wdcreg.h>
#include <dev/ata/atareg.h>
#include <dev/pci/pciidereg.h>
-#include <sys/disklabel.h>
+/*
+ * WD1003 / ATA Disk Controller register definitions.
+ */
+
+/* offsets of registers in the 'regular' register region */
+#define wd_data 0 /* data register (R/W - 16 bits) */
+#define wd_error 1 /* error register (R) */
+#define wd_precomp 1 /* write precompensation (W) */
+#define wd_seccnt 2 /* sector count (R/W) */
+#define wd_ireason 2 /* interrupt reason (R/W) (for atapi) */
+#define wd_sector 3 /* first sector number (R/W) */
+#define wd_cyl_lo 4 /* cylinder address, low byte (R/W) */
+#define wd_cyl_hi 5 /* cylinder address, high byte (R/W) */
+#define wd_sdh 6 /* sector size/drive/head (R/W) */
+#define wd_command 7 /* command register (W) */
+#define wd_lba_lo 3 /* lba address, low byte (RW) */
+#define wd_lba_mi 4 /* lba address, middle byte (RW) */
+#define wd_lba_hi 5 /* lba address, high byte (RW) */
+
+/* "shadow" registers; these may or may not overlap regular registers */
+#define wd_status 8 /* immediate status (R) */
+#define wd_features 9 /* features (W) */
+
+/* offsets of registers in the auxiliary register region */
+#define wd_aux_altsts 0 /* alternate fixed disk status (R) */
+#define wd_aux_ctlr 0 /* fixed disk controller control (W) */
+#define WDCTL_4BIT 0x08 /* use four head bits (wd1003) */
+#define WDCTL_RST 0x04 /* reset the controller */
+#define WDCTL_IDS 0x02 /* disable controller interrupts */
#define WDC_TIMEOUT 2000000
#define PCIIDE_CHANNEL_NDEV 2
@@ -52,7 +82,7 @@ struct wdc_channel {
volatile u_int8_t *c_cmdreg[WDC_NPORTS + WDC_NSHADOWREG];
volatile u_int16_t *c_data;
- u_int8_t compatchan;
+ u_int8_t ndrives;
};
#define WDC_READ_REG(chp, reg) *(chp)->c_cmdreg[(reg)]
@@ -74,6 +104,7 @@ struct wd_softc {
struct ataparams sc_params;
struct disklabel sc_label;
struct wdc_channel sc_channel;
+ u_int sc_drive;
};
struct wdc_command {
@@ -92,12 +123,12 @@ struct wdc_command {
u_int64_t r_blkno;
};
-int wdc_init (struct wd_softc*, u_int*);
+int wdc_init (struct wd_softc*, u_int);
int wdccommand (struct wd_softc*, struct wdc_command*);
int wdccommandext (struct wd_softc*, struct wdc_command*);
int wdc_exec_read (struct wd_softc*, u_int8_t, daddr_t, void*);
int wdc_exec_identify (struct wd_softc*, void*);
-int pciide_init (struct wdc_channel*, u_int*);
+int pciide_init (struct wdc_channel*, u_int);
#endif /* _STAND_WDVAR_H */