diff options
-rw-r--r-- | sys/arch/armish/stand/boot/Makefile | 20 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/boot.c | 75 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/clock.c | 5 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/conf.c | 22 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/dev_armish.c | 115 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/devopen.c | 67 | ||||
-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.c | 69 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/ns16550.c | 38 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/pciide.c | 54 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/time.c | 12 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/wd.c | 63 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/wdc.c | 70 | ||||
-rw-r--r-- | sys/arch/armish/stand/boot/wdvar.h | 41 |
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 */ |