xref: /netbsd-src/sys/arch/x68k/stand/boot/switch.c (revision 7b2cf7659d8dbede27b957757f7961e46f2b0af7)
1 /*	$NetBSD: switch.c,v 1.2 2014/08/10 07:40:50 isaki Exp $	*/
2 
3 /*
4  * Copyright (c) 2014 Tetsuya Isaki. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
20  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
22  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/param.h>
29 #include <lib/libsa/stand.h>
30 #include <lib/libkern/libkern.h>
31 
32 #include "switch.h"
33 
34 #define SRAM_MEMSIZE	(*((volatile uint32_t *)0x00ed0008))
35 #define SRAM_ROMADDR	(*((volatile uint32_t *)0x00ed000c))
36 #define SRAM_RAMADDR	(*((volatile uint32_t *)0x00ed0010))
37 #define SRAM_BOOTDEV	(*((volatile uint16_t *)0x00ed0018))
38 
39 #define SYSPORT_SRAM_WP	(*((volatile uint8_t *)0x00e8e00d))
40 
41 static int hextoi(const char *);
42 static void cmd_switch_help(void);
43 static void cmd_switch_show(void);
44 static void cmd_switch_show_boot(void);
45 static void cmd_switch_show_rom(void);
46 static void cmd_switch_show_memory(void);
47 static const char *romaddr_tostr(uint32_t);
48 static const char *get_romaddr_name(uint32_t);
49 static void cmd_switch_boot(const char *);
50 static void cmd_switch_rom(const char *);
51 static void cmd_switch_memory(const char *);
52 
53 static inline void
sram_write_enable(void)54 sram_write_enable(void)
55 {
56 	SYSPORT_SRAM_WP = 0x31;
57 }
58 
59 static inline void
sram_write_disable(void)60 sram_write_disable(void)
61 {
62 	SYSPORT_SRAM_WP = 0;
63 }
64 
65 static int
hextoi(const char * in)66 hextoi(const char *in)
67 {
68 	char *c;
69 	int ret;
70 
71 	ret = 0;
72 	c = (char *)in;
73 	for (; isxdigit(*c); c++) {
74 		ret = (ret * 16) +
75 		      (*c > '9' ? ((*c | 0x20) - 'a' + 10) : *c - '0');
76 	}
77 	return ret;
78 }
79 
80 static void
cmd_switch_help(void)81 cmd_switch_help(void)
82 {
83 	printf(
84 		"usage: switch <key>=<val>\n"
85 		"         boot=[std | inscsi<N> | exscsi<N> | fd<N> | rom ]\n"
86 		"         rom=[ inscsi<N> | exscsi<N> | $<addr> ]\n"
87 		"         memory=<1..12> (unit:MB)\n"
88 		"       switch show\n"
89 	);
90 }
91 
92 void
cmd_switch(char * arg)93 cmd_switch(char *arg)
94 {
95 	char *val;
96 
97 	if (strcmp(arg, "show") == 0) {
98 		cmd_switch_show();
99 		return;
100 	}
101 
102 	val = strchr(arg, '=');
103 	if (val == NULL) {
104 		cmd_switch_help();
105 		return;
106 	}
107 	*val++ = '\0';
108 
109 	if (strcmp(arg, "boot") == 0) {
110 		cmd_switch_boot(val);
111 	} else if (strcmp(arg, "rom") == 0) {
112 		cmd_switch_rom(val);
113 	} else if (strcmp(arg, "memory") == 0) {
114 		cmd_switch_memory(val);
115 	} else {
116 		cmd_switch_help();
117 	}
118 }
119 
120 static void
cmd_switch_show(void)121 cmd_switch_show(void)
122 {
123 	cmd_switch_show_boot();
124 	cmd_switch_show_rom();
125 	cmd_switch_show_memory();
126 }
127 
128 static void
cmd_switch_show_boot(void)129 cmd_switch_show_boot(void)
130 {
131 	uint32_t romaddr;
132 	uint16_t bootdev;
133 	const char *name;
134 
135 	bootdev = SRAM_BOOTDEV;
136 	romaddr = SRAM_ROMADDR;
137 
138 	/*
139 	 * $0000: std
140 	 * $8n00: sasi<N>
141 	 * $9n70: fd<N>
142 	 * $a000: ROM
143 	 * $b000: RAM
144 	 */
145 	printf("boot=");
146 	switch (bootdev >> 12) {
147 	default:
148 	case 0x0:
149 		/*
150 		 * The real order is fd->sasi->rom->ram
151 		 * but it is a bit redundant..
152 		 */
153 		printf("std (fd -> ");
154 		name = get_romaddr_name(romaddr);
155 		if (name)
156 			printf("%s)", name);
157 		else
158 			printf("rom$%x)", romaddr);
159 		break;
160 	case 0x8:
161 		printf("sasi%d", (bootdev >> 8) & 15);
162 		break;
163 	case 0x9:
164 		printf("fd%d", (bootdev >> 8) & 3);
165 		break;
166 	case 0xa:
167 		printf("rom%s", romaddr_tostr(romaddr));
168 		break;
169 	case 0xb:
170 		printf("ram$%x", SRAM_RAMADDR);
171 		break;
172 	}
173 	printf("\n");
174 }
175 
176 static void
cmd_switch_show_rom(void)177 cmd_switch_show_rom(void)
178 {
179 	uint32_t romaddr;
180 
181 	romaddr = SRAM_ROMADDR;
182 	printf("rom=%s\n", romaddr_tostr(romaddr));
183 }
184 
185 static void
cmd_switch_show_memory(void)186 cmd_switch_show_memory(void)
187 {
188 	printf("memory=%d MB\n", SRAM_MEMSIZE / (1024 * 1024));
189 }
190 
191 /* return rom address as string with name if any */
192 static const char *
romaddr_tostr(uint32_t addr)193 romaddr_tostr(uint32_t addr)
194 {
195 	static char buf[32];
196 	const char *name;
197 
198 	name = get_romaddr_name(addr);
199 	if (name)
200 		snprintf(buf, sizeof(buf), "$%x (%s)", addr, name);
201 	else
202 		snprintf(buf, sizeof(buf), "$%x", addr);
203 
204 	return buf;
205 }
206 
207 /*
208  * return "inscsiN" / "exscsiN" if addr is in range of SCSI boot.
209  * Otherwise return NULL.
210  */
211 static const char *
get_romaddr_name(uint32_t addr)212 get_romaddr_name(uint32_t addr)
213 {
214 	static char buf[8];
215 
216 	if (0xfc0000 <= addr && addr < 0xfc0020 && addr % 4 == 0) {
217 		snprintf(buf, sizeof(buf), "inscsi%d", (addr >> 2) & 7);
218 	} else if (0xea0020 <= addr && addr < 0xea0040 && addr % 4 == 0) {
219 		snprintf(buf, sizeof(buf), "exscsi%d", (addr >> 2) & 7);
220 	} else {
221 		return NULL;
222 	}
223 	return buf;
224 }
225 
226 static void
cmd_switch_boot(const char * arg)227 cmd_switch_boot(const char *arg)
228 {
229 	int id;
230 	uint32_t romaddr;
231 	uint16_t bootdev;
232 
233 	romaddr = 0xffffffff;
234 
235 	if (strcmp(arg, "std") == 0) {
236 		bootdev = 0x0000;
237 
238 	} else if (strcmp(arg, "rom") == 0) {
239 		bootdev = 0xa000;
240 
241 	} else if (strncmp(arg, "inscsi", 6) == 0) {
242 		id = (arg[6] - '0') & 7;
243 		bootdev = 0xa000;
244 		romaddr = 0xfc0000 + id * 4;
245 
246 	} else if (strncmp(arg, "exscsi", 6) == 0) {
247 		id = (arg[6] - '0') & 7;
248 		bootdev = 0xa000;
249 		romaddr = 0xea0020 + id * 4;
250 
251 	} else if (strncmp(arg, "fd", 2) == 0) {
252 		id = (arg[2] - '0') & 3;
253 		bootdev = 0x9070 | (id << 8);
254 
255 	} else {
256 		cmd_switch_help();
257 		return;
258 	}
259 
260 	sram_write_enable();
261 	SRAM_BOOTDEV = bootdev;
262 	if (romaddr != 0xffffffff)
263 		SRAM_ROMADDR = romaddr;
264 	sram_write_disable();
265 
266 	cmd_switch_show_boot();
267 }
268 
269 static void
cmd_switch_rom(const char * arg)270 cmd_switch_rom(const char *arg)
271 {
272 	int id;
273 	uint32_t romaddr;
274 
275 	if (strncmp(arg, "inscsi", 6) == 0) {
276 		id = (arg[6] - '0') & 7;
277 		romaddr = 0xfc0000 + id * 4;
278 
279 	} else if (strncmp(arg, "exscsi", 6) == 0) {
280 		id = (arg[6] - '0') & 7;
281 		romaddr = 0xea0020 + id * 4;
282 
283 	} else if (*arg == '$') {
284 		romaddr = hextoi(arg + 1);
285 
286 	} else {
287 		cmd_switch_help();
288 		return;
289 	}
290 
291 	sram_write_enable();
292 	SRAM_ROMADDR = romaddr;
293 	sram_write_disable();
294 
295 	cmd_switch_show_rom();
296 }
297 
298 static void
cmd_switch_memory(const char * arg)299 cmd_switch_memory(const char *arg)
300 {
301 	int num;
302 
303 	num = atoi(arg);
304 	if (num < 1 || num > 12) {
305 		cmd_switch_help();
306 		return;
307 	}
308 
309 	sram_write_enable();
310 	SRAM_MEMSIZE = num * (1024 * 1024);
311 	sram_write_disable();
312 
313 	cmd_switch_show_memory();
314 }
315