Port-x68k archive

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

memswitch on /boot



Hi all,

This is a patch that adds memswitch like command to /boot.

The new command name is 'switch'.  Of course the name was
inspired from Human68k's switch.x.
Other candidates that I thought are 'sram' or 'sw'...
I thought that 'memswitch' is too long to enter without
any shell completion and its syntax is also too complex to
implement on the bootloader.

This command is a subset of the original switch.x (and
memswitch) that specialized for required situation.  Currently
only 3 parameters are supported. i.e., boot, rom, memory.
These parameter names and values are also inspired from
'switch.x ?' help message (but not the same).

- 'boot' and 'rom' specify the boot device/address.
- 'memory' specifies the main memory size and it should
  match the actual installed memory size.

Please look at the help message (cmd_switch_help() function
in switch.c) for how to use :)

Any comments? or I will commit it few days or a week after.
---
Tetsuya Isaki <isaki%pastel-flower.jp@localhost / isaki%NetBSD.org@localhost>

Index: sys/arch/x68k/stand/boot/Makefile
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/stand/boot/Makefile,v
retrieving revision 1.23
diff -u -r1.23 Makefile
--- sys/arch/x68k/stand/boot/Makefile   6 Jul 2014 06:28:49 -0000       1.23
+++ sys/arch/x68k/stand/boot/Makefile   1 Aug 2014 09:44:12 -0000
@@ -22,7 +22,7 @@
 STRIP?=                /usr/bin/strip
 OBJCOPY?=      /usr/bin/objcopy
 
-SRCS=          srt0.S boot.c conf.c exec_image.S
+SRCS=          srt0.S boot.c conf.c switch.c exec_image.S
 S=             ${.CURDIR}/../../../..
 M=             ${.CURDIR}/../..
 COMMONDIR=     $M/stand/common
Index: sys/arch/x68k/stand/boot/boot.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/stand/boot/boot.c,v
retrieving revision 1.21
diff -u -r1.21 boot.c
--- sys/arch/x68k/stand/boot/boot.c     6 Jul 2014 08:10:21 -0000       1.21
+++ sys/arch/x68k/stand/boot/boot.c     1 Aug 2014 09:44:12 -0000
@@ -39,6 +39,7 @@
 
 #include "libx68k.h"
 #include "iocs.h"
+#include "switch.h"
 
 #include "exec_image.h"
 
@@ -122,6 +123,7 @@
 #ifndef NETBOOT
        printf("ls [dev:][directory]\n");
 #endif
+       printf("switch [show | key=val]\n");
        printf("halt\nreboot\n");
 }
 
@@ -318,6 +320,8 @@
                else if (strcmp("halt", p) == 0 ||
                         strcmp("reboot", p) == 0)
                        exit(0);
+               else if (strcmp("switch", p) == 0)
+                       cmd_switch(options);
 #ifndef NETBOOT
                else if (strcmp("ls", p) == 0)
                        cmd_ls(options);
Index: sys/arch/x68k/stand/netboot/Makefile
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/stand/netboot/Makefile,v
retrieving revision 1.3
diff -u -r1.3 Makefile
--- sys/arch/x68k/stand/netboot/Makefile        6 Jul 2014 06:28:49 -0000       
1.3
+++ sys/arch/x68k/stand/netboot/Makefile        1 Aug 2014 09:44:13 -0000
@@ -29,7 +29,7 @@
 BOOTDIR=       ${.CURDIR}/../boot
 .PATH:         ${BOOTDIR}
 
-SRCS=          srt0.S boot.c conf.c exec_image.S if_ne.c ne.c dp8390.c
+SRCS=          srt0.S boot.c conf.c switch.c exec_image.S if_ne.c ne.c dp8390.c
 S=             ${.CURDIR}/../../../..
 M=             ${.CURDIR}/../..
 COMMONDIR=     $M/stand/common
--- /dev/null   2014-08-01 18:55:01.000000000 +0900
+++ sys/arch/x68k/stand/boot/switch.c   2014-08-01 18:59:49.000000000 +0900
@@ -0,0 +1,333 @@
+/*     $NetBSD$        */
+
+/*
+ * Copyright (c) 2014 Tetsuya Isaki. 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.
+ *
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <lib/libsa/stand.h>
+#include <lib/libkern/libkern.h>
+
+#include "switch.h"
+
+#define SRAM_MEMSIZE   (*((volatile uint32_t *)0x00ed0008))
+#define SRAM_ROMADDR   (*((volatile uint32_t *)0x00ed000c))
+#define SRAM_RAMADDR   (*((volatile uint32_t *)0x00ed0010))
+#define SRAM_BOOTDEV   (*((volatile uint16_t *)0x00ed0018))
+
+#define SYSPORT_SRAM_WP        (*((volatile uint8_t *)0x00e8e00d))
+
+static int hextoi(const char *);
+static void cmd_switch_help(void);
+static void cmd_switch_show(void);
+static void cmd_switch_show_boot(void);
+static void cmd_switch_show_rom(void);
+static void cmd_switch_show_memory(void);
+static const char *romaddr_tostr(uint32_t);
+static const char *get_romaddr_name(uint32_t);
+static void cmd_switch_boot(const char *);
+static void cmd_switch_rom(const char *);
+static void cmd_switch_memory(const char *);
+
+static inline void
+sram_write_enable(void)
+{
+       SYSPORT_SRAM_WP = 0x31;
+}
+
+static inline void
+sram_write_disable(void)
+{
+       SYSPORT_SRAM_WP = 0;
+}
+
+/* XXX atoi is dumb copy from i386/stand/lib/bootmenu.c ... */
+#define isnum(c) ((c) >= '0' && (c) <= '9')
+static int
+atoi(const char *in)
+{
+       char *c;
+       int ret;
+
+       ret = 0;
+       c = (char *)in;
+       if (*c == '-')
+               c++;
+       for (; isnum(*c); c++)
+               ret = (ret * 10) + (*c - '0');
+
+       return (*in == '-') ? -ret : ret;
+}
+
+#define isxdigit(c) (isnum(c) || (((c) | 0x20) >= 'a' && ((c) | 0x20) <= 'f'))
+static int
+hextoi(const char *in)
+{
+       char *c;
+       int ret;
+
+       ret = 0;
+       c = (char *)in;
+       for (; isxdigit(*c); c++) {
+               ret = (ret * 16) +
+                     (*c > '9' ? ((*c | 0x20) - 'a' + 10) : *c - '0');
+       }
+       return ret;
+}
+
+static void
+cmd_switch_help(void)
+{
+       printf(
+               "usage: switch <key>=<val>\n"
+               "         boot=[std | inscsi<N> | exscsi<N> | fd<N> | rom ]\n"
+               "         rom=[ inscsi<N> | exscsi<N> | $<addr> ]\n"
+               "         memory=<1..12> (unit:MB)\n"
+               "       switch show\n"
+       );
+}
+
+void
+cmd_switch(char *arg)
+{
+       char *val;
+
+       if (strcmp(arg, "show") == 0) {
+               cmd_switch_show();
+               return;
+       }
+
+       val = strchr(arg, '=');
+       if (val == NULL) {
+               cmd_switch_help();
+               return;
+       }
+       *val++ = '\0';
+
+       if (strcmp(arg, "boot") == 0) {
+               cmd_switch_boot(val);
+       } else if (strcmp(arg, "rom") == 0) {
+               cmd_switch_rom(val);
+       } else if (strcmp(arg, "memory") == 0) {
+               cmd_switch_memory(val);
+       } else {
+               cmd_switch_help();
+       }
+}
+
+static void
+cmd_switch_show(void)
+{
+       cmd_switch_show_boot();
+       cmd_switch_show_rom();
+       cmd_switch_show_memory();
+}
+
+static void
+cmd_switch_show_boot(void)
+{
+       uint32_t romaddr;
+       uint16_t bootdev;
+       const char *name;
+
+       bootdev = SRAM_BOOTDEV;
+       romaddr = SRAM_ROMADDR;
+
+       /*
+        * $0000: std
+        * $8n00: sasi<N>
+        * $9n70: fd<N>
+        * $a000: ROM
+        * $b000: RAM
+        */
+       printf("boot=");
+       switch (bootdev >> 12) {
+       default:
+       case 0x0:
+               /*
+                * The real order is fd->sasi->rom->ram
+                * but it is a bit redundant..
+                */
+               printf("std (fd -> ");
+               name = get_romaddr_name(romaddr);
+               if (name)
+                       printf("%s)", name);
+               else
+                       printf("rom$%x)", romaddr);
+               break;
+       case 0x8:
+               printf("sasi%d", (bootdev >> 8) & 15);
+               break;
+       case 0x9:
+               printf("fd%d", (bootdev >> 8) & 3);
+               break;
+       case 0xa:
+               printf("rom%s", romaddr_tostr(romaddr));
+               break;
+       case 0xb:
+               printf("ram$%x", SRAM_RAMADDR);
+               break;
+       }
+       printf("\n");
+}
+
+static void
+cmd_switch_show_rom(void)
+{
+       uint32_t romaddr;
+
+       romaddr = SRAM_ROMADDR;
+       printf("rom=%s\n", romaddr_tostr(romaddr));
+}
+
+static void
+cmd_switch_show_memory(void)
+{
+       printf("memory=%d MB\n", SRAM_MEMSIZE / (1024 * 1024));
+}
+
+/* return rom address as string with name if any */
+static const char *
+romaddr_tostr(uint32_t addr)
+{
+       static char buf[32];
+       const char *name;
+
+       name = get_romaddr_name(addr);
+       if (name)
+               snprintf(buf, sizeof(buf), "$%x (%s)", addr, name);
+       else
+               snprintf(buf, sizeof(buf), "$%x", addr);
+
+       return buf;
+}
+
+/*
+ * return "inscsiN" / "exscsiN" if addr is in range of SCSI boot.
+ * Otherwise return NULL.
+ */
+static const char *
+get_romaddr_name(uint32_t addr)
+{
+       static char buf[8];
+
+       if (0xfc0000 <= addr && addr < 0xfc0020 && addr % 4 == 0) {
+               snprintf(buf, sizeof(buf), "inscsi%d", (addr >> 2) & 7);
+       } else if (0xea0020 <= addr && addr < 0xea0040 && addr % 4 == 0) {
+               snprintf(buf, sizeof(buf), "exscsi%d", (addr >> 2) & 7);
+       } else {
+               return NULL;
+       }
+       return buf;
+}
+
+static void
+cmd_switch_boot(const char *arg)
+{
+       int id;
+       uint32_t romaddr;
+       uint16_t bootdev;
+
+       romaddr = 0xffffffff;
+
+       if (strcmp(arg, "std") == 0) {
+               bootdev = 0x0000;
+
+       } else if (strcmp(arg, "rom") == 0) {
+               bootdev = 0xa000;
+
+       } else if (strncmp(arg, "inscsi", 6) == 0) {
+               id = (arg[6] - '0') & 7;
+               bootdev = 0xa000;
+               romaddr = 0xfc0000 + id * 4;
+
+       } else if (strncmp(arg, "exscsi", 6) == 0) {
+               id = (arg[6] - '0') & 7;
+               bootdev = 0xa000;
+               romaddr = 0xea0020 + id * 4;
+
+       } else if (strncmp(arg, "fd", 2) == 0) {
+               id = (arg[2] - '0') & 3;
+               bootdev = 0x9070 | (id << 8);
+
+       } else {
+               cmd_switch_help();
+               return;
+       }
+
+       sram_write_enable();
+       SRAM_BOOTDEV = bootdev;
+       if (romaddr != 0xffffffff)
+               SRAM_ROMADDR = romaddr;
+       sram_write_disable();
+
+       cmd_switch_show_boot();
+}
+
+static void
+cmd_switch_rom(const char *arg)
+{
+       int id;
+       uint32_t romaddr;
+
+       if (strncmp(arg, "inscsi", 6) == 0) {
+               id = (arg[6] - '0') & 7;
+               romaddr = 0xfc0000 + id * 4;
+
+       } else if (strncmp(arg, "exscsi", 6) == 0) {
+               id = (arg[6] - '0') & 7;
+               romaddr = 0xea0020 + id * 4;
+
+       } else if (*arg == '$') {
+               romaddr = hextoi(arg + 1);
+
+       } else {
+               cmd_switch_help();
+               return;
+       }
+
+       sram_write_enable();
+       SRAM_ROMADDR = romaddr;
+       sram_write_disable();
+
+       cmd_switch_show_rom();
+}
+
+static void
+cmd_switch_memory(const char *arg)
+{
+       int num;
+
+       num = atoi(arg);
+       if (num < 1 || num > 12) {
+               cmd_switch_help();
+               return;
+       }
+
+       sram_write_enable();
+       SRAM_MEMSIZE = num * (1024 * 1024);
+       sram_write_disable();
+
+       cmd_switch_show_memory();
+}
--- /dev/null   2014-08-01 18:55:01.000000000 +0900
+++ sys/arch/x68k/stand/boot/switch.h   2014-08-01 14:39:22.000000000 +0900
@@ -0,0 +1,28 @@
+/*     $NetBSD$        */
+
+/*
+ * Copyright (c) 2014 Tetsuya Isaki. 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.
+ *
+ * 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.
+ */
+
+extern void cmd_switch(char *);


Home | Main Index | Thread Index | Old Index