xref: /netbsd/sys/arch/next68k/next68k/nextrom.c (revision bf9ec67e)
1 /*	$NetBSD: nextrom.c,v 1.12 2001/05/12 22:35:30 chs Exp $	*/
2 /*
3  * Copyright (c) 1998 Darrin B. Jewell
4  * 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  * 3. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *      This product includes software developed by Darrin B. Jewell
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 #include "opt_ddb.h"
33 
34 #include <sys/types.h>
35 #include <machine/cpu.h>
36 
37 #include <next68k/next68k/seglist.h>
38 #include <next68k/next68k/nextrom.h>
39 
40 #ifdef DDB
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/proc.h>
44 #define ELFSIZE 32
45 #include <sys/exec_elf.h>
46 #endif
47 
48 void    next68k_bootargs __P((unsigned char *args[]));
49 
50 int mon_getc(void);
51 int mon_putc(int c);
52 
53 extern char etext[], edata[], end[];
54 int nsym;
55 char *ssym, *esym;
56 
57 volatile struct mon_global *mg;
58 
59 
60 #define	MON(type, off) (*(type *)((u_int) (mg) + off))
61 
62 #define RELOC(v, t)	(*((t *)((u_int)&(v) + NEXT_RAMBASE)))
63 
64 #define	MONRELOC(type, off) \
65      (*(volatile type *)((u_int) RELOC(mg,volatile struct mon_global *) + off))
66 
67 
68 typedef int (*getcptr)(void);
69 typedef int (*putcptr)(int);
70 
71 /*
72  * Print a string on the rom console before the MMU is turned on
73  */
74 
75 /* #define DISABLE_ROM_PRINT 1 */
76 
77 #ifdef DISABLE_ROM_PRINT
78 #define ROM_PUTS(xs) /* nop */
79 #define ROM_PUTX(v)  /* nop */
80 #else
81 
82 #define ROM_PUTS(xs) \
83   do { volatile char *_s = xs + NEXT_RAMBASE; \
84      while(_s && *_s) (*MONRELOC(putcptr,MG_putc))(*_s++); \
85 	} while(0)
86 
87 /* Print a hex byte on the rom console */
88 
89 #if 1
90 static char romprint_hextable[] = "0123456789abcdef@";
91 #define ROM_PUTX(v) \
92   do { \
93     (*MONRELOC(putcptr,MG_putc)) \
94 			 ((romprint_hextable+NEXT_RAMBASE)[((v)>>4)&0xf]); \
95     (*MONRELOC(putcptr,MG_putc)) \
96 			 ((romprint_hextable+NEXT_RAMBASE)[(v)&0xf]); \
97 	} while(0);
98 #else
99 #define lookup_hex(v)  ((v)>9?('a'+(v)-0xa):('0'+(v)))
100 #define ROM_PUTX(v) \
101   do { \
102     (*MONRELOC(putcptr,MG_putc)) \
103 			 (lookup_hex(((v)>>4)&0xf)); \
104     (*MONRELOC(putcptr,MG_putc)) \
105 			 (lookup_hex((v)&0xf)); \
106 	} while(0);
107 #endif
108 #endif
109 
110 u_char rom_enetaddr[6];
111 u_char rom_boot_dev[20];
112 u_char rom_boot_arg[20];
113 u_char rom_boot_info[20];
114 u_char rom_boot_file[20];
115 u_char rom_bootfile[MG_boot_how-MG_bootfile];
116 char rom_machine_type;
117 
118 u_char *rom_return_sp;
119 u_int rom_mon_stack;
120 u_char rom_image[0x2000];
121 vm_offset_t rom_image_base;
122 u_int rom_vbr;;
123 
124 paddr_t rom_reboot_vect;
125 
126 void
127 next68k_bootargs(args)
128      unsigned char *args[];
129 {
130 #ifdef DDB
131 	int i;
132 	Elf_Ehdr *ehdr;
133 	Elf_Shdr *shp;
134 	vaddr_t minsym, maxsym;
135 	char *reloc_end, *reloc_elfmag;
136 #endif
137 
138 	RELOC(rom_return_sp,u_char *) = args[0];
139 	RELOC(mg,char *) = args[1];
140 
141 	ROM_PUTS("Welcome to NetBSD/next68k\r\n");
142 
143 #ifdef DDB
144 
145 	/*
146 	 * Check the ELF headers.
147 	 */
148 
149 	reloc_end = end + NEXT_RAMBASE;
150 	reloc_elfmag = ELFMAG + NEXT_RAMBASE;
151 	ehdr = (void *)reloc_end;
152 
153 	for (i = 0; i < SELFMAG; i++) {
154 		if (ehdr->e_ident[i] != reloc_elfmag[i]) {
155 			ROM_PUTS("save_symtab: bad ELF magic\n");
156 			goto ddbdone;
157 		}
158 	}
159 	if (ehdr->e_ident[EI_CLASS] != ELFCLASS32) {
160 		ROM_PUTS("save_symtab: bad ELF magic\n");
161 		goto ddbdone;
162 	}
163 
164 	/*
165 	 * Find the end of the symbols and strings.
166 	 */
167 
168 	maxsym = 0;
169 	minsym = ~maxsym;
170 	shp = (Elf_Shdr *)(reloc_end + ehdr->e_shoff);
171 	for (i = 0; i < ehdr->e_shnum; i++) {
172 		if (shp[i].sh_type != SHT_SYMTAB &&
173 		    shp[i].sh_type != SHT_STRTAB) {
174 			continue;
175 		}
176 		minsym = MIN(minsym, (vaddr_t)reloc_end + shp[i].sh_offset);
177 		maxsym = MAX(maxsym, (vaddr_t)reloc_end + shp[i].sh_offset +
178 			     shp[i].sh_size);
179 	}
180 	RELOC(nsym, int) = 1;
181 	RELOC(ssym, char *) = end;
182 	RELOC(esym, char *) = (char *)maxsym - NEXT_RAMBASE;
183 
184 	ROM_PUTS("nsym ");
185 	ROM_PUTX(RELOC(nsym, int));
186 	ROM_PUTS(" ssym ");
187 	ROM_PUTX((vaddr_t)RELOC(ssym, char *));
188 	ROM_PUTS(" esym ");
189 	ROM_PUTX((vaddr_t)RELOC(esym, char *));
190 	ROM_PUTS("\r\n");
191 
192 ddbdone:
193 #endif
194 
195 	ROM_PUTS("Constructing the segment list...\r\n");
196 
197 	ROM_PUTS("machine type = 0x");
198 	ROM_PUTX(MONRELOC(char,MG_machine_type));
199 	ROM_PUTS("\r\nboard rev = 0x");
200 	ROM_PUTX(MONRELOC(char,MG_board_rev));
201 	ROM_PUTS("\r\ndmachip = 0x");
202 	ROM_PUTX(MONRELOC(int,MG_dmachip)>>24&0xff);
203 	ROM_PUTX(MONRELOC(int,MG_dmachip)>>16&0xff);
204 	ROM_PUTX(MONRELOC(int,MG_dmachip)>>8&0xff);
205 	ROM_PUTX(MONRELOC(int,MG_dmachip)>>0&0xff);
206 	ROM_PUTS("\r\ndiskchip = 0x");
207 	ROM_PUTX(MONRELOC(int,MG_diskchip)>>24&0xff);
208 	ROM_PUTX(MONRELOC(int,MG_diskchip)>>16&0xff);
209 	ROM_PUTX(MONRELOC(int,MG_diskchip)>>8&0xff);
210 	ROM_PUTX(MONRELOC(int,MG_diskchip)>>0&0xff);
211 	ROM_PUTS("\r\n");
212 
213 
214   /* Construct the segment list */
215   {
216 		u_int msize16;
217 		u_int msize4;
218 		u_int msize1;
219     int i;
220     int j = 0;
221 
222 		if (MONRELOC(char,MG_machine_type) == NeXT_X15) {
223 			msize16 = 0x1000000;
224 			msize4  = 0x400000;
225 			msize1  = 0x100000;
226 			ROM_PUTS("Looks like a NeXT_X15\r\n");
227 		} else if (MONRELOC(char,MG_machine_type) == NeXT_WARP9C) {
228 			msize16 = 0x800000;
229 			msize4  = 0x200000;
230 			msize1  = 0x80000;				/* ? */
231 			ROM_PUTS("Looks like a NeXT_WARP9C\r\n");
232 		} else if (MONRELOC(char,MG_machine_type) == NeXT_WARP9) {
233 			msize16 = 0x1000000;
234 			msize4  = 0x400000;
235 			msize1  = 0x100000;
236 			ROM_PUTS("Looks like a NeXT_WARP9\r\n");
237 		} else if (MONRELOC(char,MG_machine_type) == NeXT_TURBO_COLOR) {
238 			msize16 = 0x2000000;
239 			msize4  = 0x800000;
240 			msize1  = 0x200000;
241 			ROM_PUTS("Looks like a NeXT_TURBO_COLOR\r\n");
242 		} else {
243 			msize16 = 0x100000;
244 			msize4  = 0x100000;
245 			msize1  = 0x100000;
246 			ROM_PUTS("Unrecognized machine_type\r\n");
247 		}
248 
249 		RELOC(rom_machine_type, char) = MONRELOC(char, MG_machine_type);
250 
251     for (i=0;i<N_SIMM;i++) {
252 
253 			ROM_PUTS("Memory bank 0x");
254 			ROM_PUTX(i);
255 			ROM_PUTS(" has value 0x");
256 			ROM_PUTX(MONRELOC(char,MG_simm+i))
257 			ROM_PUTS("\r\n");
258 
259       if ((MONRELOC(char,MG_simm+i) & SIMM_SIZE) != SIMM_SIZE_EMPTY) {
260         RELOC(phys_seg_list[j].ps_start, vm_offset_t)
261           = NEXT_RAMBASE+(i*msize16);
262       }
263       if ((MONRELOC(char,MG_simm+i) & SIMM_SIZE) == SIMM_SIZE_16MB) {
264         RELOC(phys_seg_list[j].ps_end, vm_offset_t) =
265           RELOC(phys_seg_list[j].ps_start, vm_offset_t) +
266 						msize16;
267         j++;
268       }
269       if ((MONRELOC(char,MG_simm+i) & SIMM_SIZE) == SIMM_SIZE_4MB) {
270         RELOC(phys_seg_list[j].ps_end, vm_offset_t) =
271           RELOC(phys_seg_list[j].ps_start, vm_offset_t) +
272 						msize4;
273         j++;
274       }
275       if ((MONRELOC(char,MG_simm+i) & SIMM_SIZE) == SIMM_SIZE_1MB) {
276         RELOC(phys_seg_list[j].ps_end, vm_offset_t) =
277           RELOC(phys_seg_list[j].ps_start, vm_offset_t) +
278 						msize1;
279         j++;
280       }
281     }
282 
283 		/* The NeXT ROM or something appears to reserve the very
284 		 * top of memory
285 		 */
286 		RELOC(phys_seg_list[j-1].ps_end, vm_offset_t) -= 0x2000;
287 		RELOC(rom_image_base, vm_offset_t) = RELOC(phys_seg_list[j-1].ps_end, vm_offset_t);
288 
289     /* pmap is unhappy if it is not null terminated */
290     for(;j<MAX_PHYS_SEGS;j++) {
291       RELOC(phys_seg_list[j].ps_start, vm_offset_t) = 0;
292       RELOC(phys_seg_list[j].ps_end, vm_offset_t) = 0;
293     }
294   }
295 
296 	{
297 		int i;
298 		ROM_PUTS("Memory segments found:\r\n");
299 		for (i=0;RELOC(phys_seg_list[i].ps_start, vm_offset_t);i++) {
300 			ROM_PUTS("\t0x");
301 			ROM_PUTX((RELOC(phys_seg_list[i].ps_start, vm_offset_t)>>24)&0xff);
302 			ROM_PUTX((RELOC(phys_seg_list[i].ps_start, vm_offset_t)>>16)&0xff);
303 			ROM_PUTX((RELOC(phys_seg_list[i].ps_start, vm_offset_t)>>8)&0xff);
304 			ROM_PUTX((RELOC(phys_seg_list[i].ps_start, vm_offset_t)>>0)&0xff);
305 			ROM_PUTS(" - 0x");
306 			ROM_PUTX((RELOC(phys_seg_list[i].ps_end, vm_offset_t)>>24)&0xff);
307 			ROM_PUTX((RELOC(phys_seg_list[i].ps_end, vm_offset_t)>>16)&0xff);
308 			ROM_PUTX((RELOC(phys_seg_list[i].ps_end, vm_offset_t)>>8)&0xff);
309 			ROM_PUTX((RELOC(phys_seg_list[i].ps_end, vm_offset_t)>>0)&0xff);
310 			ROM_PUTS("\r\n");
311 		}
312 	}
313 
314   /* Read the ethernet address from rom, this should be done later
315    * in device driver somehow.
316    */
317   {
318     int i;
319 		ROM_PUTS("Ethernet address: ");
320     for(i=0;i<6;i++) {
321       RELOC(rom_enetaddr[i], u_char) = MONRELOC(u_char *, MG_clientetheraddr)[i];
322 			ROM_PUTX(RELOC(rom_enetaddr[i],u_char));
323 			if (i < 5) ROM_PUTS(":");
324     }
325 		ROM_PUTS("\r\n");
326   }
327 
328 	/* Read the boot args
329 	 */
330 	{
331 		int i;
332 		for(i=0;i<sizeof(rom_bootfile);i++) {
333 			RELOC(rom_bootfile[i], u_char) = MONRELOC(u_char, MG_bootfile+i);
334 		}
335 
336 		for(i=0;i<sizeof(rom_boot_dev);i++) {
337 			RELOC(rom_boot_dev[i], u_char) = MONRELOC(u_char *, MG_boot_dev)[i];
338 			if (MONRELOC(u_char *, MG_boot_dev)[i] == '\0') break;
339 		}
340 		RELOC(rom_boot_dev[sizeof(rom_boot_dev)-1], u_char) = 0;
341 
342 		for(i=0;i<sizeof(rom_boot_arg);i++) {
343 			RELOC(rom_boot_arg[i], u_char) = MONRELOC(u_char *, MG_boot_arg)[i];
344 			if (MONRELOC(u_char *, MG_boot_arg)[i] == '\0') break;
345 		}
346 		RELOC(rom_boot_arg[sizeof(rom_boot_arg)-1], u_char) = 0;
347 
348 		for(i=0;i<sizeof(rom_boot_info);i++) {
349 			RELOC(rom_boot_info[i], u_char) = MONRELOC(u_char *, MG_boot_info)[i];
350 			if (MONRELOC(u_char *, MG_boot_info)[i] == '\0') break;
351 		}
352 		RELOC(rom_boot_info[sizeof(rom_boot_info)-1], u_char) = 0;
353 
354 		for(i=0;i<sizeof(rom_boot_file);i++) {
355 			RELOC(rom_boot_file[i], u_char) = MONRELOC(u_char *, MG_boot_file)[i];
356 			if (MONRELOC(u_char *, MG_boot_file)[i] == '\0') break;
357 		}
358 		RELOC(rom_boot_file[sizeof(rom_boot_file)-1], u_char) = 0;
359 
360 		RELOC(rom_mon_stack, u_int) = MONRELOC(u_int, MG_mon_stack);
361 		RELOC(rom_vbr, u_int) = MONRELOC(u_int, MG_vbr);
362 		RELOC(rom_reboot_vect, paddr_t) = MONRELOC(paddr_t *, MG_vbr)[45]; /* trap #13 */
363 
364 		for(i=0;i<sizeof(rom_image);i++) {
365 			RELOC(rom_image[i], u_char) = *(u_char *)(RELOC(rom_image_base, vm_offset_t) + i);
366 		}
367 	}
368 
369 	ROM_PUTS("Check serial port A for console.\r\n");
370 }
371