summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2006-07-28 17:12:07 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2006-07-28 17:12:07 +0000
commit15e0980d8f0b251e6cfdfbe72fc67e79b514466c (patch)
treea567a5307e80cea488d60c5c8fc934fcd3fb9649
parentc8b15e982f697762676be53dca799e0f7ce902fd (diff)
First stab at an armish bootloader. It will load /bsd from the drive in the
upper slot of the Thecus n2100. Glued together from bits from the NetBSD cobalt and evbarm ports.
-rw-r--r--sys/arch/armish/stand/boot/Makefile39
-rw-r--r--sys/arch/armish/stand/boot/boot.c75
-rw-r--r--sys/arch/armish/stand/boot/boot.h31
-rw-r--r--sys/arch/armish/stand/boot/clock.c56
-rw-r--r--sys/arch/armish/stand/boot/conf.c59
-rw-r--r--sys/arch/armish/stand/boot/devopen.c146
-rw-r--r--sys/arch/armish/stand/boot/exec.c31
-rw-r--r--sys/arch/armish/stand/boot/ldscript84
-rw-r--r--sys/arch/armish/stand/boot/ns16550.c133
-rw-r--r--sys/arch/armish/stand/boot/pciide.c109
-rw-r--r--sys/arch/armish/stand/boot/start.S83
-rw-r--r--sys/arch/armish/stand/boot/wd.c279
-rw-r--r--sys/arch/armish/stand/boot/wdc.c419
-rw-r--r--sys/arch/armish/stand/boot/wdvar.h103
14 files changed, 1647 insertions, 0 deletions
diff --git a/sys/arch/armish/stand/boot/Makefile b/sys/arch/armish/stand/boot/Makefile
new file mode 100644
index 00000000000..b265ba3a7b5
--- /dev/null
+++ b/sys/arch/armish/stand/boot/Makefile
@@ -0,0 +1,39 @@
+PROG= boot
+
+S= ${.CURDIR}/../../../..
+
+CPPFLAGS+= -nostdinc -I../.. -I. -I${S} -D_STANDALONE
+CPPFLAGS+= -DCONSPEED=115200
+CPPFLAGS+= -DCONADDR=0xfe800000UL
+
+COPTS+= -ffreestanding -fno-stack-protector -malignment-traps
+
+SRCS= start.S boot.c conf.c clock.c ns16550.c wd.c wdc.c pciide.c
+SRCS+= devopen.c exec.c
+
+### find out what to use for libkern
+KERN_AS= library
+.include "${S}/lib/libkern/Makefile.inc"
+LIBKERN= ${KERNLIB}
+
+### find out what to use for libsa
+SA_AS= library
+SAREL=
+USE_LOADFILE= yes
+.include "${S}/lib/libsa/Makefile.inc"
+LIBSA= ${SALIB}
+
+LDFLAGS= -T ${.CURDIR}/ldscript
+
+${PROG}: ${OBJS} ${LIBKERN} ${LIBSA}
+ ${LD} ${LDFLAGS} -o boot ${OBJS} ${LIBSA} ${LIBKERN} ${LIBSA}
+
+.if !make(obj)
+.BEGIN:
+ @([ -h machine ] || ln -s ${.CURDIR}/../../../${MACHINE}/include machine)
+ @([ -h arm ] || ln -s ${.CURDIR}/../../../arm/include arm)
+.NOPATH: machine arm
+CLEANFILES+= machine arm
+.endif
+
+.include <bsd.prog.mk>
diff --git a/sys/arch/armish/stand/boot/boot.c b/sys/arch/armish/stand/boot/boot.c
new file mode 100644
index 00000000000..ed47f80bc92
--- /dev/null
+++ b/sys/arch/armish/stand/boot/boot.c
@@ -0,0 +1,75 @@
+/* $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/boot.h b/sys/arch/armish/stand/boot/boot.h
new file mode 100644
index 00000000000..c5499e34ac5
--- /dev/null
+++ b/sys/arch/armish/stand/boot/boot.h
@@ -0,0 +1,31 @@
+/* $OpenBSD: boot.h,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.
+ */
+
+#define DPRINTF(x) printf x;
+
+#define MAXDEVNAME 16
+#define DEFBOOTDEV "wd0a"
+#define DEFKERNELNAME "bsd"
+
+
+/*
+ * wd
+ */
+int wdstrategy(void *, int, daddr_t, size_t, void *, size_t *);
+int wdopen(struct open_file *, ...);
+int wdclose(struct open_file *);
diff --git a/sys/arch/armish/stand/boot/clock.c b/sys/arch/armish/stand/boot/clock.c
new file mode 100644
index 00000000000..d3f1a61dee7
--- /dev/null
+++ b/sys/arch/armish/stand/boot/clock.c
@@ -0,0 +1,56 @@
+/* $OpenBSD: clock.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: clock.c,v 1.1 2003/06/25 17:24:22 cdi Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Manuel Bouyer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <lib/libsa/stand.h>
+
+#include "boot.h"
+
+#define DELAY_CALIBRATE 1000
+
+void
+delay(int ms)
+{
+ /*
+ * XXX need *real* clock calibration.
+ */
+ volatile register int N = ms * DELAY_CALIBRATE;
+ for (; --N;)
+ ;
+}
diff --git a/sys/arch/armish/stand/boot/conf.c b/sys/arch/armish/stand/boot/conf.c
new file mode 100644
index 00000000000..65145648755
--- /dev/null
+++ b/sys/arch/armish/stand/boot/conf.c
@@ -0,0 +1,59 @@
+/* $OpenBSD: conf.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: conf.c,v 1.4 2005/12/11 12:17:06 christos Exp $ */
+
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)conf.c 8.1 (Berkeley) 6/10/93
+ */
+
+#include <sys/param.h>
+
+#include <lib/libsa/stand.h>
+#include <lib/libsa/ufs.h>
+
+#include "boot.h"
+
+/*
+ * Device configuration
+ */
+struct devsw devsw[] = {
+ { "wd", wdstrategy, wdopen, wdclose, noioctl },
+};
+
+int ndevs = (sizeof(devsw)/sizeof(devsw[0]));
+
+/*
+ * Filesystem configuration
+ */
+struct fs_ops file_system[] = {
+ { ufs_open, ufs_close, ufs_read, ufs_write, ufs_seek,
+ ufs_stat, ufs_readdir }
+};
+
+int nfsys = sizeof(file_system) / sizeof(file_system[0]);
diff --git a/sys/arch/armish/stand/boot/devopen.c b/sys/arch/armish/stand/boot/devopen.c
new file mode 100644
index 00000000000..78521074535
--- /dev/null
+++ b/sys/arch/armish/stand/boot/devopen.c
@@ -0,0 +1,146 @@
+/* $OpenBSD: devopen.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: devopen.c,v 1.1 2003/06/25 17:24:22 cdi Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Rolf Grossmann.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <lib/libsa/stand.h>
+
+#include "boot.h"
+
+/*
+ * Parse a device spec.
+ *
+ * Format:
+ * [device:][filename]
+ */
+int
+devparse(const char *fname, int *dev, u_int8_t *unit,
+ u_int8_t *part, const char **file)
+{
+ const char *col;
+
+ *unit = 0; /* default to wd0a */
+ *part = 0;
+ *dev = 0;
+ *file = DEFKERNELNAME;
+
+ if (fname == NULL)
+ return (0);
+
+ if ( (col = strchr(fname, ':')) != NULL) {
+ int devlen;
+ u_int8_t i, u, p;
+ struct devsw *dp;
+ char devname[MAXDEVNAME];
+
+ devlen = col - 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]))
+ return (EUNIT);
+
+ /* device number */
+ for (u = 0; isnum(fname[i]) && (i < devlen); i++)
+ u = u * 10 + (fname[i] - '0');
+
+ if (!isalpha(fname[i]))
+ return (EPART);
+
+ /* partition number */
+ if (i < devlen)
+ p = fname[i++] - 'a';
+
+ if (i != devlen)
+ return (ENXIO);
+
+ /* check device name */
+ for (dp = devsw, i = 0; i < ndevs; dp++, i++) {
+ if (dp->dv_name && !strcmp(devname, dp->dv_name))
+ break;
+ }
+
+ if (i >= ndevs)
+ return (ENXIO);
+
+ *unit = u;
+ *part = p;
+ *dev = i;
+ fname = ++col;
+ }
+
+ if (*fname)
+ *file = fname;
+
+ return (0);
+}
+
+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));
+
+ if ( (error = devparse(fname, &dev, &unit, &part,
+ (const char **)file)) != 0)
+ return error;
+
+ 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));
+
+ return error;
+}
diff --git a/sys/arch/armish/stand/boot/exec.c b/sys/arch/armish/stand/boot/exec.c
new file mode 100644
index 00000000000..d44aae439ba
--- /dev/null
+++ b/sys/arch/armish/stand/boot/exec.c
@@ -0,0 +1,31 @@
+/* $OpenBSD: exec.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 <sys/param.h>
+
+#include <lib/libsa/loadfile.h>
+
+typedef void (*startfuncp)(void) __attribute__ ((noreturn));
+
+void
+run_loadfile(u_long *marks, int howto)
+{
+ (*(startfuncp)(marks[MARK_ENTRY]))();
+
+ /* NOTREACHED */
+}
diff --git a/sys/arch/armish/stand/boot/ldscript b/sys/arch/armish/stand/boot/ldscript
new file mode 100644
index 00000000000..fab694cfc57
--- /dev/null
+++ b/sys/arch/armish/stand/boot/ldscript
@@ -0,0 +1,84 @@
+/* $OpenBSD: ldscript,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: ldscript,v 1.6 2005/12/11 12:17:10 christos Exp $ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",
+ "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(FLASH)
+MEMORY
+{
+ /* We will locate the .text section in flash, and will run directly
+ from there just long enough to relocate our .text and .data into
+ a small chunk of SDRAM starting at (SDRAM + 1M). */
+ flash : o = 0xf0080000, l = 6M
+ sdram : o = 0x00100000, l = 1M /* kernel loads at 0xa0200000 */
+}
+SECTIONS
+{
+ FLASH = 0x00100000;
+
+ /* Read-only sections, merged into text segment: */
+ __text_store = FLASH;
+ .text :
+ AT (FLASH)
+ {
+ *(.text)
+ *(.text.*)
+ *(.stub)
+ *(.glue_7t) *(.glue_7)
+ *(.rodata) *(.rodata.*)
+ } > sdram =0
+ PROVIDE (__etext = .);
+ PROVIDE (_etext = .);
+ PROVIDE (etext = .);
+ __data_store = FLASH + SIZEOF(.text);
+ .data :
+ AT (LOADADDR(.text) + SIZEOF(.text))
+ {
+ __data_start = . ;
+ *(.data)
+ *(.data.*)
+ } > sdram
+ .sdata :
+ AT (LOADADDR(.data) + SIZEOF(.data))
+ {
+ *(.sdata)
+ *(.sdata.*)
+ . = ALIGN(32 / 8);
+ } > sdram
+ _edata = .;
+ PROVIDE (edata = .);
+ __bss_start = .;
+ __bss_start__ = .;
+ .sbss :
+ {
+ PROVIDE (__sbss_start = .);
+ PROVIDE (___sbss_start = .);
+ *(.dynsbss)
+ *(.sbss)
+ *(.sbss.*)
+ *(.scommon)
+ PROVIDE (__sbss_end = .);
+ PROVIDE (___sbss_end = .);
+ } > sdram
+ .bss :
+ {
+ *(.dynbss)
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ /* Align here to ensure that the .bss section occupies space up to
+ _end. Align after .bss to ensure correct alignment even if the
+ .bss section disappears because there are no input sections. */
+ . = ALIGN(32 / 8);
+ } > sdram
+ . = ALIGN(32 / 8);
+ _end = .;
+ _bss_end__ = . ; __bss_end__ = . ; __end__ = . ;
+ PROVIDE (end = .);
+ .image (FLASH + SIZEOF(.text) + SIZEOF(.data) + SIZEOF(.sdata)) :
+ AT (LOADADDR(.sdata) + SIZEOF(.sdata))
+ {
+ *(.image)
+ }
+}
diff --git a/sys/arch/armish/stand/boot/ns16550.c b/sys/arch/armish/stand/boot/ns16550.c
new file mode 100644
index 00000000000..66690e8eb2c
--- /dev/null
+++ b/sys/arch/armish/stand/boot/ns16550.c
@@ -0,0 +1,133 @@
+/* $OpenBSD: ns16550.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: ns16550.c,v 1.3 2005/12/24 20:07:03 perry Exp $ */
+
+/*
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * This file provides the cons_init() function and console I/O routines
+ * for boards that use 16550-compatible UARTs.
+ */
+
+#include <sys/types.h>
+#include <dev/ic/comreg.h>
+#include <lib/libsa/stand.h>
+
+#define INB(x) *((volatile uint8_t *) (CONADDR + (x)))
+#define OUTB(x, v) *((volatile uint8_t *) (CONADDR + (x))) = (v)
+
+#define ISSET(t,f) ((t) & (f))
+
+#ifndef NS16550_FREQ
+#define NS16550_FREQ COM_FREQ
+#endif
+
+static int
+comspeed(int speed)
+{
+#define divrnd(n, q) (((n)*2/(q)+1)/2) /* divide and round off */
+
+ int x, err;
+
+ if (speed <= 0)
+ return (-1);
+ x = divrnd((NS16550_FREQ / 16), speed);
+ if (x <= 0)
+ return (-1);
+ err = divrnd((((quad_t)NS16550_FREQ) / 16) * 1000, speed * x) - 1000;
+ if (err < 0)
+ err = -err;
+ if (err > COM_TOLERANCE)
+ return (-1);
+ return (x);
+#undef divrnd
+}
+
+void
+cons_init(void)
+{
+ int rate;
+
+ OUTB(com_cfcr, LCR_DLAB);
+ rate = comspeed(CONSPEED);
+ OUTB(com_dlbl, rate);
+ OUTB(com_dlbh, rate >> 8);
+ OUTB(com_cfcr, LCR_8BITS);
+ OUTB(com_mcr, MCR_DTR | MCR_RTS);
+ OUTB(com_fifo,
+ FIFO_ENABLE | FIFO_RCV_RST | FIFO_XMT_RST | FIFO_TRIGGER_1);
+ OUTB(com_ier, 0);
+}
+
+int
+getchar(void)
+{
+ uint8_t stat;
+
+ while (!ISSET(stat = INB(com_lsr), LSR_RXRDY))
+ /* spin */ ;
+ return (INB(com_data));
+}
+
+static void
+iputchar(int c)
+{
+ uint8_t stat;
+ int timo;
+
+ /* Wait for any pending transmission to finish. */
+ timo = 50000;
+ while (!ISSET(stat = INB(com_lsr), LSR_TXRDY) && --timo)
+ /* spin */ ;
+
+ OUTB(com_data, c);
+
+ /* Wait for this transmission to complete. */
+ timo = 1500000;
+ while (!ISSET(stat = INB(com_lsr), LSR_TXRDY) && --timo)
+ /* spin */ ;
+
+ /* 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
new file mode 100644
index 00000000000..97cc4885186
--- /dev/null
+++ b/sys/arch/armish/stand/boot/pciide.c
@@ -0,0 +1,109 @@
+/* $OpenBSD: pciide.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: pciide.c,v 1.5 2005/12/11 12:17:06 christos Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <lib/libsa/stand.h>
+
+#include "boot.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;
+{
+ u_int32_t cmdreg, ctlreg;
+ int i, compatchan = 0;
+
+ /*
+ * two channels per chip, two drives per channel
+ */
+ compatchan = *unit / PCIIDE_CHANNEL_NDEV;
+ if (compatchan >= PCIIDE_NUM_CHANNELS)
+ return (ENXIO);
+ *unit %= PCIIDE_CHANNEL_NDEV;
+
+ DPRINTF(("[pciide] unit: %d, channel: %d\n", *unit, compatchan));
+
+ /*
+ * XXX map?
+ */
+ cmdreg = 0x90000200 + compatchan * 0x10;
+ ctlreg = 0x90000208 + compatchan * 0x10;
+
+ /* set up cmd regsiters */
+ chp->c_cmdbase = (u_int8_t *)cmdreg;
+ chp->c_data = (u_int16_t *)(cmdreg + wd_data);
+ for (i = 0; i < WDC_NPORTS; i++)
+ chp->c_cmdreg[i] = chp->c_cmdbase + i;
+ /* set up shadow registers */
+ chp->c_cmdreg[wd_status] = chp->c_cmdreg[wd_command];
+ chp->c_cmdreg[wd_features] = chp->c_cmdreg[wd_precomp];
+ /* set up ctl registers */
+ chp->c_ctlbase = (u_int8_t *)ctlreg;
+
+ return (0);
+}
diff --git a/sys/arch/armish/stand/boot/start.S b/sys/arch/armish/stand/boot/start.S
new file mode 100644
index 00000000000..03f3e10d2de
--- /dev/null
+++ b/sys/arch/armish/stand/boot/start.S
@@ -0,0 +1,83 @@
+/* $OpenBSD: start.S,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: srtbegin.S,v 1.7 2005/12/11 12:17:10 christos Exp $ */
+
+/*
+ * Copyright (c) 2002 Wasabi Systems, Inc.
+ * All rights reserved.
+ *
+ * Written by Jason R. Thorpe for Wasabi Systems, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed for the NetBSD Project by
+ * Wasabi Systems, Inc.
+ * 4. The name of Wasabi Systems, Inc. may not be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <machine/asm.h>
+#include <arm/armreg.h>
+
+#define STACKSIZE 8192
+
+ENTRY(start)
+ /*
+ * We assume we've been loaded VA==PA, or that the MMU
+ * is disabled. Make sure the MMU is disabled so that
+ * we don't have to care about the caches.
+ */
+ /* Clear the BSS. */
+ adr r1, Lbss
+ ldmia r1, {r1, r2}
+ sub r2, r2, r1
+ mov r3, #0
+
+1: strb r3, [r1], #0x01
+ subs r2, r2, #0x01
+ bgt 1b
+
+ /* Set the stack pointer */
+ adr r1, Lstack
+ ldr r1, [r1]
+ add sp, r1, #STACKSIZE
+
+ b _C_LABEL(main)
+
+Ltext:
+ .word _C_LABEL(__text_store)
+ .word _C_LABEL(start)
+ .word _C_LABEL(_etext)
+
+Ldata:
+ .word _C_LABEL(__data_store)
+ .word _C_LABEL(__data_start)
+
+Lbss:
+ .word _C_LABEL(_edata)
+ .word _C_LABEL(_end)
+
+Lstack:
+ .word Lstackspace
+
+ .comm Lstackspace, STACKSIZE
diff --git a/sys/arch/armish/stand/boot/wd.c b/sys/arch/armish/stand/boot/wd.c
new file mode 100644
index 00000000000..f907d271e1a
--- /dev/null
+++ b/sys/arch/armish/stand/boot/wd.c
@@ -0,0 +1,279 @@
+/* $OpenBSD: wd.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: wd.c,v 1.5 2005/12/11 12:17:06 christos Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Manuel Bouyer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#include <sys/stdint.h>
+
+#include <lib/libsa/stand.h>
+#include <machine/param.h>
+
+#include "boot.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);
+
+/*
+ * Get drive parameters through 'device identify' command.
+ */
+int
+wd_get_params(wd)
+ struct wd_softc *wd;
+{
+ int error;
+ unsigned char buf[DEV_BSIZE];
+
+ if ((error = wdc_exec_identify(wd, buf)) != 0)
+ return (error);
+
+ wd->sc_params = *(struct ataparams *)buf;
+
+ /* 48-bit LBA addressing */
+ if ((wd->sc_params.atap_cmd2_en & ATAPI_CMD2_48AD) != 0) {
+ DPRINTF(("Drive supports LBA48.\n"));
+#if defined(_ENABLE_LBA48)
+ wd->sc_flags |= WDF_LBA48;
+#endif
+ }
+
+ /* Prior to ATA-4, LBA was optional. */
+ if ((wd->sc_params.atap_capabilities1 & WDC_CAP_LBA) != 0) {
+ DPRINTF(("Drive supports LBA.\n"));
+ wd->sc_flags |= WDF_LBA;
+ }
+
+ return (0);
+}
+
+/*
+ * Initialize disk label to the default value.
+ */
+void
+wdgetdefaultlabel(wd, lp)
+ struct wd_softc *wd;
+ struct disklabel *lp;
+{
+ memset(lp, 0, sizeof(struct disklabel));
+
+ lp->d_secsize = DEV_BSIZE;
+ lp->d_ntracks = wd->sc_params.atap_heads;
+ lp->d_nsectors = wd->sc_params.atap_sectors;
+ lp->d_ncylinders = wd->sc_params.atap_cylinders;
+ lp->d_secpercyl = lp->d_ntracks * lp->d_nsectors;
+
+ if (strcmp(wd->sc_params.atap_model, "ST506") == 0)
+ lp->d_type = DTYPE_ST506;
+ else
+ lp->d_type = DTYPE_ESDI;
+
+ strncpy(lp->d_typename, wd->sc_params.atap_model, 16);
+ strncpy(lp->d_packname, "fictitious", 16);
+ if (wd->sc_capacity > UINT32_MAX)
+ lp->d_secperunit = UINT32_MAX;
+ else
+ lp->d_secperunit = wd->sc_capacity;
+ lp->d_rpm = 3600;
+ lp->d_interleave = 1;
+ lp->d_flags = 0;
+
+ lp->d_partitions[RAW_PART].p_offset = 0;
+ lp->d_partitions[RAW_PART].p_size =
+ lp->d_secperunit * (lp->d_secsize / DEV_BSIZE);
+ lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED;
+ lp->d_npartitions = MAXPARTITIONS; /* RAW_PART + 1 ??? */
+
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ lp->d_checksum = dkcksum(lp);
+}
+
+/*
+ * Read disk label from the device.
+ */
+int
+wdgetdisklabel(wd)
+ struct wd_softc *wd;
+{
+ char *msg;
+ int sector;
+ size_t rsize;
+ struct disklabel *lp;
+ unsigned char buf[DEV_BSIZE];
+
+ wdgetdefaultlabel(wd, &wd->sc_label);
+
+ /*
+ * Find OpenBSD Partition in DOS partition table.
+ */
+ sector = 0;
+ if (wdstrategy(wd, F_READ, DOSBBSECTOR, DEV_BSIZE, buf, &rsize))
+ return EOFFSET;
+
+ if (*(u_int16_t *)&buf[DOSMAGICOFF] == DOSMAGIC) {
+ int i;
+ struct dos_partition *dp = (struct dos_partition *)buf;
+
+ /*
+ * Lookup OpenBSD slice. If there is none, go ahead
+ * and try to read the disklabel off sector #0.
+ */
+
+ memcpy(dp, &buf[DOSPARTOFF], NDOSPART * sizeof(*dp));
+ for (i = 0; i < NDOSPART; i++) {
+ if (dp[i].dp_typ == DOSPTYP_OPENBSD) {
+ sector = letoh32(dp[i].dp_start);
+ break;
+ }
+ }
+ }
+
+ if (wdstrategy(wd, F_READ, sector + LABELSECTOR, DEV_BSIZE,
+ buf, &rsize))
+ return EOFFSET;
+
+ if ((msg = getdisklabel(buf + LABELOFFSET, &wd->sc_label)))
+ printf("wd%d: getdisklabel: %s\n", wd->sc_unit, msg);
+
+ lp = &wd->sc_label;
+
+ /* check partition */
+ if ((wd->sc_part >= lp->d_npartitions) ||
+ (lp->d_partitions[wd->sc_part].p_fstype == FS_UNUSED)) {
+ DPRINTF(("illegal partition\n"));
+ return (EPART);
+ }
+
+ DPRINTF(("label info: d_secsize %d, d_nsectors %d, d_ncylinders %d,"
+ "d_ntracks %d, d_secpercyl %d\n",
+ wd->sc_label.d_secsize,
+ wd->sc_label.d_nsectors,
+ wd->sc_label.d_ncylinders,
+ wd->sc_label.d_ntracks,
+ wd->sc_label.d_secpercyl));
+
+ return (0);
+}
+
+/*
+ * Open device (read drive parameters and disklabel)
+ */
+int
+wdopen(struct open_file *f, ...)
+{
+ int error;
+ va_list ap;
+ u_int unit, part;
+ struct wd_softc *wd;
+
+ va_start(ap, f);
+ unit = va_arg(ap, u_int);
+ part = va_arg(ap, u_int);
+ va_end(ap);
+
+ DPRINTF(("wdopen: %d:%d\n", unit, part));
+
+ wd = alloc(sizeof(struct wd_softc));
+ if (wd == NULL)
+ return ENOMEM;
+
+ memset(wd, 0, sizeof(struct wd_softc));
+
+ if (wdc_init(wd, &unit) != 0)
+ return (ENXIO);
+
+ wd->sc_part = part;
+ wd->sc_unit = unit;
+
+ if ( (error = wd_get_params(wd)) != 0)
+ return (error);
+
+ if ( (error = wdgetdisklabel(wd)) != 0)
+ return error;
+
+ f->f_devdata = wd;
+ return (0);
+}
+
+/*
+ * Close device.
+ */
+int
+wdclose(struct open_file *f)
+{
+ return 0;
+}
+
+/*
+ * Read some data.
+ */
+int
+wdstrategy(f, rw, dblk, size, buf, rsize)
+ void *f;
+ int rw;
+ daddr_t dblk;
+ size_t size;
+ void *buf;
+ size_t *rsize;
+{
+ int i, nsect;
+ daddr_t blkno;
+ struct wd_softc *wd = f;
+
+ if (size == 0)
+ return (0);
+
+ if (rw != F_READ)
+ return EOPNOTSUPP;
+
+ nsect = howmany(size, wd->sc_label.d_secsize);
+ blkno = dblk + wd->sc_label.d_partitions[wd->sc_part].p_offset;
+
+ for (i = 0; i < nsect; i++, blkno++) {
+ int error;
+
+ if ( (error = wdc_exec_read(wd, WDCC_READ, blkno, buf)) != 0)
+ return (error);
+
+ buf += wd->sc_label.d_secsize;
+ }
+
+ *rsize = size;
+ return (0);
+}
diff --git a/sys/arch/armish/stand/boot/wdc.c b/sys/arch/armish/stand/boot/wdc.c
new file mode 100644
index 00000000000..d6e151dc175
--- /dev/null
+++ b/sys/arch/armish/stand/boot/wdc.c
@@ -0,0 +1,419 @@
+/* $OpenBSD: wdc.c,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: wdc.c,v 1.7 2005/12/11 12:17:06 christos Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Manuel Bouyer.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/types.h>
+#if 0
+#include <sys/disklabel.h>
+#endif
+
+#include <lib/libsa/stand.h>
+#include <machine/param.h>
+
+#include "boot.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
+
+static int wdcprobe(struct wdc_channel *chp);
+static int wdc_wait_for_ready(struct wdc_channel *chp);
+static int wdc_read_block(struct wd_softc *sc, struct wdc_command *wd_c);
+static int __wdcwait_reset(struct wdc_channel *chp, int drv_mask);
+
+/*
+ * Reset the controller.
+ */
+static int
+__wdcwait_reset(chp, drv_mask)
+ struct wdc_channel *chp;
+ int drv_mask;
+{
+ int timeout;
+ u_int8_t st0, st1;
+
+ /* wait for BSY to deassert */
+ for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) {
+ WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM); /* master */
+ delay(10);
+ st0 = WDC_READ_REG(chp, wd_status);
+ WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM | 0x10); /* slave */
+ delay(10);
+ st1 = WDC_READ_REG(chp, wd_status);
+
+ if ((drv_mask & 0x01) == 0) {
+ /* no master */
+ if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
+ /* No master, slave is ready, it's done */
+ goto end;
+ }
+ } else if ((drv_mask & 0x02) == 0) {
+ /* no slave */
+ if ((drv_mask & 0x01) != 0 && (st0 & WDCS_BSY) == 0) {
+ /* No slave, master is ready, it's done */
+ goto end;
+ }
+ } else {
+ /* Wait for both master and slave to be ready */
+ if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
+ goto end;
+ }
+ }
+
+ delay(WDCDELAY);
+ }
+
+ /* Reset timed out. Maybe it's because drv_mask was not right */
+ if (st0 & WDCS_BSY)
+ drv_mask &= ~0x01;
+ if (st1 & WDCS_BSY)
+ drv_mask &= ~0x02;
+
+end:
+ return (drv_mask);
+}
+
+/* Test to see controller with at last one attached drive is there.
+ * Returns a bit for each possible drive found (0x01 for drive 0,
+ * 0x02 for drive 1).
+ * Logic:
+ * - If a status register is at 0xff, assume there is no drive here
+ * (ISA has pull-up resistors). Similarly if the status register has
+ * the value we last wrote to the bus (for IDE interfaces without pullups).
+ * If no drive at all -> return.
+ * - reset the controller, wait for it to complete (may take up to 31s !).
+ * If timeout -> return.
+ */
+static int
+wdcprobe(chp)
+ struct wdc_channel *chp;
+{
+ u_int8_t st0, st1, sc, sn, cl, ch;
+ u_int8_t ret_value = 0x03;
+ u_int8_t drive;
+ int found;
+
+ /*
+ * Sanity check to see if the wdc channel responds at all.
+ */
+ WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM);
+ delay(10);
+ st0 = WDC_READ_REG(chp, wd_status);
+ WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM | 0x10);
+ delay(10);
+ st1 = WDC_READ_REG(chp, wd_status);
+
+ if (st0 == 0xff || st0 == WDSD_IBM)
+ ret_value &= ~0x01;
+ if (st1 == 0xff || st1 == (WDSD_IBM | 0x10))
+ ret_value &= ~0x02;
+ if (ret_value == 0)
+ return (ENXIO);
+
+ /* assert SRST, wait for reset to complete */
+ WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM);
+ delay(10);
+ WDC_WRITE_CTLREG(chp, wd_aux_ctlr, WDCTL_RST | WDCTL_IDS);
+ delay(1000);
+ WDC_WRITE_CTLREG(chp, wd_aux_ctlr, WDCTL_IDS);
+ delay(1000);
+ (void) WDC_READ_REG(chp, wd_error);
+ WDC_WRITE_CTLREG(chp, wd_aux_ctlr, WDCTL_4BIT);
+ delay(10);
+
+ ret_value = __wdcwait_reset(chp, ret_value);
+
+ /* if reset failed, there's nothing here */
+ if (ret_value == 0)
+ return (ENXIO);
+
+ /*
+ * Test presence of drives. First test register signatures looking for
+ * ATAPI devices. If it's not an ATAPI and reset said there may be
+ * something here assume it's ATA or OLD. Ghost will be killed later in
+ * attach routine.
+ */
+ found = 0;
+ for (drive = 0; drive < 2; drive++) {
+ if ((ret_value & (0x01 << drive)) == 0)
+ continue;
+ return (0);
+ }
+ return (ENXIO);
+}
+
+/*
+ * Initialize the device.
+ */
+int
+wdc_init(sc, unit)
+ struct wd_softc *sc;
+ u_int *unit;
+{
+ if (pciide_init(&sc->sc_channel, unit) != 0)
+ return (ENXIO);
+ if (wdcprobe(&sc->sc_channel) != 0)
+ return (ENXIO);
+ return (0);
+}
+
+/*
+ * Wait until the device is ready.
+ */
+int
+wdc_wait_for_ready(chp)
+ struct wdc_channel *chp;
+{
+ u_int timeout;
+ for (timeout = WDC_TIMEOUT; timeout > 0; --timeout) {
+ if ((WDC_READ_REG(chp, wd_status) & (WDCS_BSY | WDCS_DRDY))
+ == WDCS_DRDY)
+ return (0);
+ }
+ return (ENXIO);
+}
+
+/*
+ * Read one block off the device.
+ */
+int
+wdc_read_block(sc, wd_c)
+ struct wd_softc *sc;
+ struct wdc_command *wd_c;
+{
+ int i;
+ struct wdc_channel *chp = &sc->sc_channel;
+ u_int16_t *ptr = (u_int16_t*)wd_c->data;
+
+ if (ptr == NULL)
+ return (0);
+
+ for (i = wd_c->bcount; i > 0; i -= sizeof(u_int16_t))
+ *ptr++ = WDC_READ_DATA(chp);
+
+ return (0);
+}
+
+/*
+ * Send a command to the device (CHS and LBA addressing).
+ */
+int
+wdccommand(sc, wd_c)
+ struct wd_softc *sc;
+ struct wdc_command *wd_c;
+{
+ u_int8_t err;
+ struct wdc_channel *chp = &sc->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));
+#endif
+
+ WDC_WRITE_REG(chp, wd_precomp, wd_c->r_precomp);
+ WDC_WRITE_REG(chp, wd_seccnt, wd_c->r_count);
+ WDC_WRITE_REG(chp, wd_sector, wd_c->r_sector);
+ WDC_WRITE_REG(chp, wd_cyl_lo, wd_c->r_cyl);
+ WDC_WRITE_REG(chp, wd_cyl_hi, wd_c->r_cyl >> 8);
+ WDC_WRITE_REG(chp, wd_sdh,
+ WDSD_IBM | (wd_c->drive << 4) | wd_c->r_head);
+ WDC_WRITE_REG(chp, wd_command, wd_c->r_command);
+
+ if (wdc_wait_for_ready(chp) != 0)
+ 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));
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+/*
+ * Send a command to the device (LBA48 addressing).
+ */
+int
+wdccommandext(wd, wd_c)
+ struct wd_softc *wd;
+ struct wdc_command *wd_c;
+{
+ u_int8_t err;
+ struct wdc_channel *chp = &wd->sc_channel;
+
+ /* Select drive, head, and addressing mode. */
+ WDC_WRITE_REG(chp, wd_sdh, (wd_c->drive << 4) | WDSD_LBA);
+
+ /* previous */
+ WDC_WRITE_REG(chp, wd_features, 0);
+ WDC_WRITE_REG(chp, wd_seccnt, wd_c->r_count >> 8);
+ WDC_WRITE_REG(chp, wd_lba_hi, wd_c->r_blkno >> 40);
+ WDC_WRITE_REG(chp, wd_lba_mi, wd_c->r_blkno >> 32);
+ WDC_WRITE_REG(chp, wd_lba_lo, wd_c->r_blkno >> 24);
+
+ /* current */
+ WDC_WRITE_REG(chp, wd_features, 0);
+ WDC_WRITE_REG(chp, wd_seccnt, wd_c->r_count);
+ WDC_WRITE_REG(chp, wd_lba_hi, wd_c->r_blkno >> 16);
+ WDC_WRITE_REG(chp, wd_lba_mi, wd_c->r_blkno >> 8);
+ WDC_WRITE_REG(chp, wd_lba_lo, wd_c->r_blkno);
+
+ /* Send command. */
+ WDC_WRITE_REG(chp, wd_command, wd_c->r_command);
+
+ if (wdc_wait_for_ready(chp) != 0)
+ 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));
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+/*
+ * Issue 'device identify' command.
+ */
+int
+wdc_exec_identify(wd, data)
+ struct wd_softc *wd;
+ void *data;
+{
+ int error;
+ struct wdc_command wd_c;
+
+ memset(&wd_c, 0, sizeof(wd_c));
+
+ wd_c.drive = wd->sc_unit;
+ wd_c.r_command = WDCC_IDENTIFY;
+ wd_c.bcount = DEV_BSIZE;
+ wd_c.data = data;
+
+ if ( (error = wdccommand(wd, &wd_c)) != 0)
+ return (error);
+
+ return wdc_read_block(wd, &wd_c);
+}
+
+/*
+ * Issue 'read' command.
+ */
+int
+wdc_exec_read(wd, cmd, blkno, data)
+ struct wd_softc *wd;
+ u_int8_t cmd;
+ daddr_t blkno;
+ void *data;
+{
+ int error;
+ struct wdc_command wd_c;
+
+ memset(&wd_c, 0, sizeof(wd_c));
+
+ if (wd->sc_flags & WDF_LBA48) {
+ /* LBA48 */
+ wd_c.r_blkno = blkno;
+ } else if (wd->sc_flags & WDF_LBA) {
+ /* LBA */
+ wd_c.r_sector = (blkno >> 0) & 0xff;
+ wd_c.r_cyl = (blkno >> 8) & 0xffff;
+ wd_c.r_head = (blkno >> 24) & 0x0f;
+ wd_c.r_head |= WDSD_LBA;
+ } else {
+ /* LHS */
+ wd_c.r_sector = blkno % wd->sc_label.d_nsectors;
+ wd_c.r_sector++; /* Sectors begin with 1, not 0. */
+ blkno /= wd->sc_label.d_nsectors;
+ wd_c.r_head = blkno % wd->sc_label.d_ntracks;
+ blkno /= wd->sc_label.d_ntracks;
+ wd_c.r_cyl = blkno;
+ wd_c.r_head |= WDSD_CHS;
+ }
+
+ wd_c.data = data;
+ wd_c.r_count = 1;
+ wd_c.drive = wd->sc_unit;
+ wd_c.r_command = cmd;
+ wd_c.bcount = wd->sc_label.d_secsize;
+
+ if (wd->sc_flags & WDF_LBA48)
+ error = wdccommandext(wd, &wd_c);
+ else
+ error = wdccommand(wd, &wd_c);
+
+ if (error != 0)
+ 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
new file mode 100644
index 00000000000..57e9076b941
--- /dev/null
+++ b/sys/arch/armish/stand/boot/wdvar.h
@@ -0,0 +1,103 @@
+/* $OpenBSD: wdvar.h,v 1.1 2006/07/28 17:12:06 kettenis Exp $ */
+/* $NetBSD: wdvar.h,v 1.6 2005/12/11 12:17:06 christos Exp $ */
+
+/*-
+ * Copyright (c) 2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 2001 Dynarc AB, Sweden. All rights reserved.
+ *
+ * This code is derived from software written by Anders Magnusson,
+ * ragge@ludd.luth.se
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _STAND_WDVAR_H
+#define _STAND_WDVAR_H
+
+#include <dev/ic/wdcreg.h>
+#include <dev/ata/atareg.h>
+#include <dev/pci/pciidereg.h>
+
+#include <sys/disklabel.h>
+
+#define WDC_TIMEOUT 2000000
+#define PCIIDE_CHANNEL_NDEV 2
+#define NUNITS (PCIIDE_CHANNEL_NDEV * PCIIDE_NUM_CHANNELS)
+#define WDC_NPORTS 8 /* XXX */
+#define WDC_NSHADOWREG 2 /* XXX */
+
+struct wdc_channel {
+ volatile u_int8_t *c_cmdbase;
+ volatile u_int8_t *c_ctlbase;
+ volatile u_int8_t *c_cmdreg[WDC_NPORTS + WDC_NSHADOWREG];
+ volatile u_int16_t *c_data;
+
+ u_int8_t compatchan;
+};
+
+#define WDC_READ_REG(chp, reg) *(chp)->c_cmdreg[(reg)]
+#define WDC_WRITE_REG(chp, reg, val) *(chp)->c_cmdreg[(reg)] = (val)
+#define WDC_READ_CTLREG(chp, reg) (chp)->c_ctlbase[(reg)]
+#define WDC_WRITE_CTLREG(chp, reg, val) (chp)->c_ctlbase[(reg)] = (val)
+#define WDC_READ_DATA(chp) *(chp)->c_data
+
+struct wd_softc {
+#define WDF_LBA 0x0001
+#define WDF_LBA48 0x0002
+ u_int16_t sc_flags;
+
+ u_int sc_part;
+ u_int sc_unit;
+
+ u_int64_t sc_capacity;
+
+ struct ataparams sc_params;
+ struct disklabel sc_label;
+ struct wdc_channel sc_channel;
+};
+
+struct wdc_command {
+ u_int8_t drive; /* drive id */
+
+ u_int8_t r_command; /* Parameters to upload to registers */
+ u_int8_t r_head;
+ u_int16_t r_cyl;
+ u_int8_t r_sector;
+ u_int8_t r_count;
+ u_int8_t r_precomp;
+
+ u_int16_t bcount;
+ void *data;
+
+ u_int64_t r_blkno;
+};
+
+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*);
+
+#endif /* _STAND_WDVAR_H */