Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sandpoint/stand/altboot Support PATA drive configur...



details:   https://anonhg.NetBSD.org/src/rev/6fb769a26f90
branches:  trunk
changeset: 772955:6fb769a26f90
user:      phx <phx%NetBSD.org@localhost>
date:      Sun Jan 22 13:08:16 2012 +0000

description:
Support PATA drive configuration option (ide:N[N...]).
Wait until drives are ready after cold-start.
Wake up drives from standby mode.
A default command line can be saved to flash as initrd image.

diffstat:

 sys/arch/sandpoint/stand/altboot/dsk.c     |   56 +++++++-----
 sys/arch/sandpoint/stand/altboot/globals.h |   13 ++-
 sys/arch/sandpoint/stand/altboot/main.c    |  124 ++++++++++++++--------------
 sys/arch/sandpoint/stand/altboot/pciide.c  |   32 ++++++-
 sys/arch/sandpoint/stand/altboot/siisata.c |   73 +++++++++++++---
 sys/arch/sandpoint/stand/altboot/version   |    3 +
 6 files changed, 193 insertions(+), 108 deletions(-)

diffs (truncated from 468 to 300 lines):

diff -r 39bc4607223e -r 6fb769a26f90 sys/arch/sandpoint/stand/altboot/dsk.c
--- a/sys/arch/sandpoint/stand/altboot/dsk.c    Sun Jan 22 12:54:26 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/dsk.c    Sun Jan 22 13:08:16 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dsk.c,v 1.12 2012/01/19 07:38:05 nisimura Exp $ */
+/* $NetBSD: dsk.c,v 1.13 2012/01/22 13:08:16 phx Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -179,34 +179,46 @@
 perform_atareset(struct dkdev_ata *l, int n)
 {
        struct dvata_chan *chan = &l->chan[n];
+//     int retries;
 
-       CSR_WRITE_1(chan->ctl, ATA_DREQ);
-       delay(10);
-       CSR_WRITE_1(chan->ctl, ATA_SRST|ATA_DREQ);
-       delay(10);
-       CSR_WRITE_1(chan->ctl, ATA_DREQ);
+//     for (retries = 0; retries < 10; retries++) {
+               CSR_WRITE_1(chan->ctl, ATA_DREQ);
+               delay(10);
+               CSR_WRITE_1(chan->ctl, ATA_SRST|ATA_DREQ);
+               delay(10);
+               CSR_WRITE_1(chan->ctl, ATA_DREQ);
+//             if (spinwait_unbusy(l, n, 1000/*250*/, NULL) != 0)
+//                     return 1;
+//             delay(1000 * 1000);
+//     }
+       return spinwait_unbusy(l, n, 1000/*250*/, NULL);
+}
 
-       return spinwait_unbusy(l, n, 250, NULL);
+/* clear idle and standby timers to spin up the drive */
+void
+wakeup_drive(struct dkdev_ata *l, int n)
+{
+       struct dvata_chan *chan = &l->chan[n];
+
+       CSR_WRITE_1(chan->cmd + _NSECT, 0);
+       CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_IDLE);
+       (void)CSR_READ_1(chan->alt);
+       delay(10 * 1000);
+       CSR_WRITE_1(chan->cmd + _NSECT, 0);
+       CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_STANDBY);
+       (void)CSR_READ_1(chan->alt);
+       delay(10 * 1000);
 }
 
 int
-satapresense(struct dkdev_ata *l, int n)
+atachkpwr(struct dkdev_ata *l, int n)
 {
-#define VND_CH(n) (((n&02)<<8)+((n&01)<<7))
-#define VND_SC(n) (0x100+VND_CH(n))
-#define VND_SS(n) (0x104+VND_CH(n))
+       struct dvata_chan *chan = &l->chan[n];
 
-       uint32_t sc = l->bar[5] + VND_SC(n);
-       uint32_t ss = l->bar[5] + VND_SS(n);
-       unsigned val;
-
-       val = (00 << 4) | (03 << 8);    /* any speed, no pwrmgt */
-       CSR_WRITE_4(sc, val | 01);      /* perform init */
-       delay(50 * 1000);
-       CSR_WRITE_4(sc, val);
-       delay(50 * 1000);       
-       val = CSR_READ_4(ss);           /* has completed */
-       return ((val & 03) == 03);      /* active drive found */
+       CSR_WRITE_1(chan->cmd + _CMD, ATA_CMD_CHKPWR);
+       (void)CSR_READ_1(chan->alt);
+       delay(10 * 1000);
+       return CSR_READ_1(chan->cmd + _NSECT);
 }
 
 static int
diff -r 39bc4607223e -r 6fb769a26f90 sys/arch/sandpoint/stand/altboot/globals.h
--- a/sys/arch/sandpoint/stand/altboot/globals.h        Sun Jan 22 12:54:26 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/globals.h        Sun Jan 22 13:08:16 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: globals.h,v 1.15 2012/01/07 19:57:49 phx Exp $ */
+/* $NetBSD: globals.h,v 1.16 2012/01/22 13:08:16 phx Exp $ */
 
 #ifdef DEBUG
 #define        DPRINTF(x)      printf x
@@ -42,6 +42,7 @@
 
 /* board specific support code */
 struct brdprop *brd_lookup(int);
+int get_drive_config(int);
 int tstchar(void);
 #ifdef DEBUG
 void sat_write(char *, int);
@@ -177,16 +178,23 @@
 #define ATA_STS_DRDY           0x40
 #define ATA_STS_ERR            0x01
 /* command */
+#define ATA_CMD_CHKPWR         0xe5
 #define ATA_CMD_IDENT          0xec
+#define ATA_CMD_IDLE           0xe3
 #define ATA_CMD_READ           0x20
 #define ATA_CMD_READ_EXT       0x24
 #define ATA_CMD_SETF           0xef
+#define ATA_CMD_STANDBY                0xe2
 /* device */
 #define ATA_DEV_LBA            0xe0
 #define ATA_DEV_OBS            0x90
 /* control */
 #define ATA_DREQ               0x08
 #define ATA_SRST               0x04
+/* power state */
+#define ATA_PWR_ACTIVE         0xff
+#define ATA_PWR_IDLE           0x80
+#define ATA_PWR_STANDBY                0x00
 
 #define ATA_XFER               0x03
 #define XFER_PIO4              0x0c
@@ -229,4 +237,5 @@
 
 int spinwait_unbusy(struct dkdev_ata *, int, int, const char **);
 int perform_atareset(struct dkdev_ata *, int);
-int satapresense(struct dkdev_ata *, int);
+void wakeup_drive(struct dkdev_ata *, int);
+int atachkpwr(struct dkdev_ata *, int);
diff -r 39bc4607223e -r 6fb769a26f90 sys/arch/sandpoint/stand/altboot/main.c
--- a/sys/arch/sandpoint/stand/altboot/main.c   Sun Jan 22 12:54:26 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/main.c   Sun Jan 22 13:08:16 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.16 2012/01/01 18:25:03 phx Exp $ */
+/* $NetBSD: main.c,v 1.17 2012/01/22 13:08:16 phx Exp $ */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -58,6 +58,9 @@
        { "altboot",    -1 }
 };
 
+/* default PATA drive configuration is "10": single master on first channel */
+static char *drive_config = "10";
+
 void *bootinfo; /* low memory reserved to pass bootinfo structures */
 int bi_size;   /* BOOTINFO_MAXSIZE */
 char *bi_next;
@@ -176,6 +179,44 @@
        pcisetup();
        pcifixup();
 
+       /*
+        * When argc is too big then it is probably a pointer, which could
+        * indicate that we were launched as a Linux kernel module using
+        * "bootm".
+        */
+       if (argc > MAX_ARGS) {
+               if (argv != NULL) {
+                       /*
+                        * initrd image was loaded:
+                        * check if it contains a valid altboot command line
+                        */
+                       char *p = (char *)argv;
+
+                       if (strncmp(p, "altboot:", 8) == 0) {
+                               *p = 0;
+                               for (p = p + 8; *p >= ' '; p++);
+                               argc = parse_cmdline(new_argv, MAX_ARGS,
+                                   ((char *)argv) + 8, p);
+                               argv = new_argv;
+                       } else
+                               argc = 0;       /* boot default */
+               } else {
+                       /* parse standard Linux bootargs */
+                       argc = parse_cmdline(new_argv, MAX_ARGS,
+                           bootargs_start, bootargs_end);
+                       argv = new_argv;
+               }
+       }
+
+       /* look for a PATA drive configuration string under the arguments */
+       for (n = 1; n < argc; n++) {
+               if (strncmp(argv[n], "ide:", 4) == 0 &&
+                   argv[n][4] >= '0' && argv[n][4] <= '2') {
+                       drive_config = &argv[n][4];
+                       break;
+               }
+       }
+
        /* intialize a disk driver */
        for (n = 0; n < nata; n++)
                if (dskdv_init(&lata[n]) != 0)
@@ -190,26 +231,6 @@
        if (n >= nnif)
                printf("no NET device driver was found\n");
 
-       /*
-        * When argc is too big then it is probably a pointer, which could
-        * indicate that we were launched as a Linux kernel module using
-        * "bootm".
-        */
-       if (argc > MAX_ARGS) {
-               if (argv != NULL) {
-                       /*
-                        * initrd image was loaded: assume extremely
-                        * restricted firmware and boot default
-                        */
-                       argc = 0;
-               } else {
-                       /* parse standard Linux bootargs */
-                       argc = parse_cmdline(new_argv, MAX_ARGS,
-                           bootargs_start, bootargs_end);
-                       argv = new_argv;
-               }
-       }
-
        /* wait 2s for user to enter interactive mode */
        for (n = 200; n >= 0; n--) {
                if (n % 100 == 0)
@@ -239,6 +260,9 @@
 
        /* get boot options and determine bootname */
        for (n = 1; n < argc; n++) {
+               if (strncmp(argv[n], "ide:", 4) == 0)
+                       continue; /* ignore drive configuration argument */
+
                for (i = 0; i < sizeof(bootargs) / sizeof(bootargs[0]); i++) {
                        if (strncasecmp(argv[n], bootargs[i].name,
                            strlen(bootargs[i].name)) == 0) {
@@ -491,52 +515,24 @@
        return fd;
 }
 
-#if 0
-static const char *cmdln[] = {
-       "console=ttyS0,115200 root=/dev/sda1 rw initrd=0x200000,2M",
-       "console=ttyS0,115200 root=/dev/nfs ip=dhcp"
-};
-
-void
-mkatagparams(unsigned addr, char *kcmd)
+/*
+ * Return the drive configuration for the requested channel 'ch'.
+ * Channel 2 is the first channel of the next IDE controller.
+ * 0: for no drive present on channel
+ * 1: for master drive present on channel, no slave
+ * 2: for master and slave drive present
+ */
+int
+get_drive_config(int ch)
 {
-       struct tag {
-               unsigned siz;
-               unsigned tag;
-               unsigned val[1];
-       };
-       struct tag *p;
-#define ATAG_CORE      0x54410001
-#define ATAG_MEM       0x54410002
-#define ATAG_INITRD    0x54410005
-#define ATAG_CMDLINE   0x54410009
-#define ATAG_NONE      0x00000000
-#define tagnext(p) (struct tag *)((unsigned *)(p) + (p)->siz)
-#define tagsize(n) (2 + (n))
-
-       p = (struct tag *)addr;
-       p->tag = ATAG_CORE;
-       p->siz = tagsize(3);
-       p->val[0] = 0;          /* flags */
-       p->val[1] = 0;          /* pagesize */
-       p->val[2] = 0;          /* rootdev */
-       p = tagnext(p);
-       p->tag = ATAG_MEM;
-       p->siz = tagsize(2);
-       p->val[0] = 64 * 1024 * 1024;
-       p->val[1] = 0;          /* start */
-       p = tagnext(p);
-       if (kcmd != NULL) {
-               p = tagnext(p);
-               p->tag = ATAG_CMDLINE;
-               p->siz = tagsize((strlen(kcmd) + 1 + 3) >> 2);
-               strcpy((void *)p->val, kcmd);
+       if (drive_config != NULL) {
+               if (strlen(drive_config) <= ch)
+                       return 0;       /* an unspecified channel is unused */
+               if (drive_config[ch] >= '0' && drive_config[ch] <= '2')
+                       return drive_config[ch] - '0';
        }
-       p = tagnext(p);
-       p->tag = ATAG_NONE;
-       p->siz = 0;
+       return -1;
 }
-#endif
 
 void *
 allocaligned(size_t size, size_t align)
diff -r 39bc4607223e -r 6fb769a26f90 sys/arch/sandpoint/stand/altboot/pciide.c
--- a/sys/arch/sandpoint/stand/altboot/pciide.c Sun Jan 22 12:54:26 2012 +0000
+++ b/sys/arch/sandpoint/stand/altboot/pciide.c Sun Jan 22 13:08:16 2012 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pciide.c,v 1.11 2011/11/13 00:06:54 phx Exp $ */
+/* $NetBSD: pciide.c,v 1.12 2012/01/22 13:08:16 phx Exp $ */



Home | Main Index | Thread Index | Old Index