Test initialisation of MUIA_List_AdjustWidth and MUIA_List_AdjustHeight, and
[AROS.git] / arch / .unmaintained / ppc-native / boot / linuxboot.c
blobfd3c045b438c2904e3797fd06276c356079872ce
1 /*
2 * linux/arch/m68k/boot/amiga/linuxboot.c -- Generic routine to boot Linux/m68k
3 * on Amiga, used by both Amiboot and
4 * Amiga-Lilo.
6 * Created 1996 by Geert Uytterhoeven
9 * This file is based on the original bootstrap code (bootstrap.c):
11 * Copyright (C) 1993, 1994 Hamish Macdonald
12 * Greg Harp
14 * with work by Michael Rausch
15 * Geert Uytterhoeven
16 * Frank Neumann
17 * Andreas Schwab
18 * Jesper Skov
21 * This file is subject to the terms and conditions of the GNU General Public
22 * License. See the file COPYING in the main directory of this archive
23 * for more details.
25 * History:
26 * 26 Feb 1998 Added support for booting APUS systems.
27 * 27 Mar 1997 FPU-less machines couldn't boot kernels that use bootinfo
28 * interface version 1.0 (Geert)
29 * 03 Feb 1997 Implemented kernel decompression (Geert, based on Roman's
30 * code for ataboot)
31 * 30 Dec 1996 Reverted the CPU detection to the old scheme
32 * New boot parameter override scheme (Geert)
33 * 27 Nov 1996 Compatibility with bootinfo interface version 1.0 (Geert)
34 * 9 Sep 1996 Rewritten option parsing
35 * New parameter passing to linuxboot() (linuxboot_args)
36 * (Geert)
37 * 18 Aug 1996 Updated for the new boot information structure (Geert)
38 * 10 Jan 1996 The real Linux/m68k boot code moved to linuxboot.[ch]
39 * (Geert)
40 * 11 Jul 1995 Support for ELF kernel (untested!) (Andreas)
41 * 7 Mar 1995 Memory block sizes are rounded to a multiple of 256K
42 * instead of 1M (Geert)
43 * 31 May 1994 Memory thrash problem solved (Geert)
44 * 11 May 1994 A3640 MapROM check (Geert)
48 #ifndef __GNUC__
49 #error GNU CC is required to compile this program
50 #endif /* __GNUC__ */
53 #define BOOTINFO_COMPAT_1_0 /* bootinfo interface version 1.0 compatible */
54 /* support compressed kernels? */
55 #define ZKERNEL
57 #include <stddef.h>
58 #include <string.h>
59 #include <errno.h>
60 #include <sys/types.h>
62 #include <linux/a.out.h>
63 #include <linux/elf.h>
64 #include <linux/linkage.h>
65 #include <asm/bootinfo.h>
66 #include <asm/amigahw.h>
67 #include <asm/page.h>
69 #include "linuxboot.h"
71 #define APUS
72 #ifdef APUS
74 #define INTUITION_CLASSES_H 1
76 #include <powerup/ppclib/interface.h>
77 /*#include <powerup/gcclib/powerup_protos.h>*/
78 #include <powerup/ppclib/message.h>
79 #include <powerup/ppclib/tasks.h>
80 #include <powerup/ppclib/object.h>
81 #include "ppcboot_elf.h"
83 #endif
85 #undef custom
86 #define custom ((*(volatile struct CUSTOM *)(CUSTOM_PHYSADDR)))
88 /* temporary stack size */
89 #define TEMP_STACKSIZE (256)
91 #define DEFAULT_BAUD (9600)
93 extern char copyall, copyallend;
95 extern char getvbr, wedgie;
97 static struct exec kexec;
98 static Elf32_Ehdr kexec_elf;
99 static const struct linuxboot_args *linuxboot_args;
101 /* Bootinfo */
102 struct amiga_bootinfo bi;
104 #ifdef BOOTINFO_COMPAT_1_0
105 static struct compat_bootinfo compat_bootinfo;
106 #endif /* BOOTINFO_COMPAT_1_0 */
108 #define MAX_BI_SIZE (4096)
109 static u_long bi_size;
110 static union {
111 struct bi_record record;
112 u_char fake[MAX_BI_SIZE];
113 } bi_union;
115 #define kernelname linuxboot_args->kernelname
116 #define ramdiskname linuxboot_args->ramdiskname
117 #define debugflag linuxboot_args->debugflag
118 #define keep_video linuxboot_args->keep_video
119 #define reset_boards linuxboot_args->reset_boards
120 #define baud linuxboot_args->baud
122 #define apus_boot linuxboot_args->apus_boot
123 #define checksum linuxboot_args->checksum
125 #define Puts linuxboot_args->puts
126 #define GetChar linuxboot_args->getchar
127 #define PutChar linuxboot_args->putchar
128 #define Printf linuxboot_args->printf
129 #define Open linuxboot_args->open
130 #define Seek linuxboot_args->seek
131 #define Read linuxboot_args->read
132 #define Close linuxboot_args->close
133 #define FileSize linuxboot_args->filesize
134 #define Sleep linuxboot_args->sleep
137 * Function Prototypes
140 static u_long get_chipset(void);
141 static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu);
142 static u_long get_model(u_long chipset);
143 static int probe_resident(const char *name);
144 static int probe_resource(const char *name);
145 static int create_bootinfo(void);
146 #ifdef BOOTINFO_COMPAT_1_0
147 static int create_compat_bootinfo(void);
148 #endif /* BOOTINFO_COMPAT_1_0 */
149 static int add_bi_record(u_short tag, u_short size, const void *data);
150 static int add_bi_string(u_short tag, const u_char *s);
151 static int check_bootinfo_version(const char *memptr);
152 static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
153 u_long start_mem, u_long mem_size, u_long rd_size,
154 u_long kernel_size) __attribute__ ((noreturn));
155 asmlinkage u_long probe_powerup(u_long);
156 asmlinkage u_long maprommed(void);
157 asmlinkage u_long check346(void);
158 #ifdef ZKERNEL
159 static int load_zkernel(int fd);
160 static int KRead(int fd, void *buf, int cnt);
161 static int KSeek(int fd, int offset);
162 static int KClose(int fd);
163 #else
164 #define KRead Read
165 #define KSeek Seek
166 #define KClose Close
167 #endif
171 * Reset functions for nasty Zorro boards
174 static void reset_rb3(const struct ConfigDev *cd);
175 static void reset_piccolo(const struct ConfigDev *cd);
176 static void reset_sd64(const struct ConfigDev *cd);
177 static void reset_a2065(const struct ConfigDev *cd);
178 static void reset_ariadne(const struct ConfigDev *cd);
179 static void reset_hydra(const struct ConfigDev *cd);
180 #if 0
181 static void reset_a2060(const struct ConfigDev *cd);
182 #endif
184 struct boardreset {
185 u_short manuf;
186 u_short prod;
187 const char *name;
188 void (*reset)(const struct ConfigDev *cd);
191 static struct boardreset boardresetdb[] = {
192 { MANUF_HELFRICH1, PROD_RAINBOW3, "Rainbow 3", reset_rb3 },
193 { MANUF_HELFRICH2, PROD_PICCOLO_REG, "Piccolo", reset_piccolo },
194 { MANUF_HELFRICH2, PROD_SD64_REG, "SD64", reset_sd64 },
195 { MANUF_COMMODORE, PROD_A2065, "A2065", reset_a2065 },
196 { MANUF_VILLAGE_TRONIC, PROD_ARIADNE, "Ariadne", reset_ariadne },
197 { MANUF_HYDRA_SYSTEMS, PROD_AMIGANET, "Hydra", reset_hydra },
198 #if 0
199 { MANUF_COMMODORE, PROD_A2060, "A2060", reset_a2060 },
200 #endif
202 #define NUM_BOARDRESET sizeof(boardresetdb)/sizeof(*boardresetdb)
204 static void (*boardresetfuncs[ZORRO_NUM_AUTO])(const struct ConfigDev *cd);
207 const char *amiga_models[] = {
208 "Amiga 500", "Amiga 500+", "Amiga 600", "Amiga 1000", "Amiga 1200",
209 "Amiga 2000", "Amiga 2500", "Amiga 3000", "Amiga 3000T", "Amiga 3000+",
210 "Amiga 4000", "Amiga 4000T", "CDTV", "CD32", "Draco"
212 const u_long first_amiga_model = AMI_500;
213 const u_long last_amiga_model = AMI_DRACO;
216 #define MASK(model) (1<<AMI_##model)
218 #define CLASS_A3000 (MASK(3000) | MASK(3000T))
219 #define CLASS_A4000 (MASK(4000) | MASK(4000T))
220 #define CLASS_ZKICK (MASK(500) | MASK(1000) | MASK(2000) | MASK(2500))
224 * Boot the Linux/m68k Operating System
227 u_long linuxboot(const struct linuxboot_args *args)
229 int kfd = -1, rfd = -1, elf_kernel = 0, do_fast, do_chip;
230 int i, j;
231 const struct MemHeader *mnp;
232 struct ConfigDev *cdp = NULL;
233 char *memptr = NULL;
234 u_long *stack = NULL;
235 u_long fast_total, model_mask, startcodesize, start_mem, mem_size, rd_size;
236 u_long kernel_size;
237 u_int realbaud;
238 u_long memreq = 0, text_offset = 0;
239 Elf32_Phdr *kernel_phdrs = NULL;
240 void (*startfunc)(void);
241 u_short manuf;
242 u_char prod;
243 void *bi_ptr;
244 unsigned long* info;
245 struct ConfigDev *zdevs[ZORRO_NUM_AUTO];
247 linuxboot_args = args;
249 /* print the greet message */
250 Puts("\nLinux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n");
251 Puts("Copyright 1993,1994 by Hamish Macdonald and Greg Harp\n\n");
253 /* Note: Initial values in bi override detected values */
254 bi = args->bi;
256 /* machine is Amiga */
257 bi.machtype = MACH_AMIGA;
259 /* determine chipset */
260 if (!bi.chipset)
261 bi.chipset = get_chipset();
263 /* determine CPU, FPU and MMU type */
264 if (!bi.cputype)
265 get_processor(&bi.cputype, &bi.fputype, &bi.mmutype);
267 /* determine Amiga model */
268 if (!bi.model)
269 bi.model = get_model(bi.chipset);
270 model_mask = (bi.model != AMI_UNKNOWN) ? 1<<bi.model : 0;
272 /* Memory & AutoConfig based on 'unix_boot.c' by C= */
274 /* find all of the autoconfig boards in the system */
275 if (!bi.num_autocon)
276 for (i = 0; (cdp = (struct ConfigDev *)FindConfigDev(cdp, -1, -1)); i++)
277 if (bi.num_autocon < ZORRO_NUM_AUTO) {
278 zdevs[i] = cdp;
279 /* copy the contents of each structure into our boot info and
280 count this device */
281 memcpy(&bi.autocon[bi.num_autocon++], cdp,
282 sizeof(struct ConfigDev));
283 } else
284 Printf("Warning: too many AutoConfig devices. Ignoring device "
285 "at 0x%08lx\n", cdp->cd_BoardAddr);
287 do_fast = bi.num_memory ? 0 : 1;
288 do_chip = bi.chip_size ? 0 : 1;
289 /* find out the memory in the system */
290 for (mnp = (struct MemHeader *)SysBase->MemList.lh_Head;
291 mnp->mh_Node.ln_Succ;
292 mnp = (struct MemHeader *)mnp->mh_Node.ln_Succ) {
293 struct MemHeader mh;
295 /* copy the information */
296 mh = *mnp;
298 /* skip virtual memory */
299 if (!(mh.mh_Attributes & MEMF_PUBLIC))
300 continue;
302 /* if we suspect that Kickstart is shadowed in an A3000,
303 modify the entry to show 512K more at the top of RAM
304 Check first for a MapROMmed A3640 board: overwriting the
305 Kickstart image causes an infinite lock-up on reboot! */
306 if ((mh.mh_Upper == (void *)0x07f80000) &&
307 (model_mask & (CLASS_A3000 | CLASS_A4000)))
308 if ((bi.cputype & CPU_68040) && Supervisor(maprommed))
309 Puts("A3640 MapROM detected.\n");
310 else if (model_mask & CLASS_A3000) {
311 mh.mh_Upper = (void *)0x08000000;
312 Puts("A3000 shadowed Kickstart detected.\n");
315 /* if we suspect that Kickstart is zkicked,
316 modify the entry to show 512K more at the botton of RAM */
317 if ((mh.mh_Lower == (void *)0x00280020) &&
318 (model_mask & CLASS_ZKICK)) {
319 mh.mh_Lower = (void *)0x00200000;
320 Puts("ZKick detected.\n");
323 /* mask the memory limit values */
324 mh.mh_Upper = (void *)((u_long)mh.mh_Upper & 0xfffff000);
325 mh.mh_Lower = (void *)((u_long)mh.mh_Lower & 0xfffff000);
327 /* if fast memory */
328 if (do_fast && mh.mh_Attributes & MEMF_FAST) {
329 /* set the size value to the size of this block and mask off to a
330 256K increment */
331 u_long size = ((u_long)mh.mh_Upper-(u_long)mh.mh_Lower)&0xfffc0000;
332 if (size > 0)
333 if (bi.num_memory < NUM_MEMINFO) {
334 /* record the start and size */
335 bi.memory[bi.num_memory].addr = (u_long)mh.mh_Lower;
336 bi.memory[bi.num_memory].size = size;
337 /* count this block */
338 bi.num_memory++;
339 } else
340 Printf("Warning: too many memory blocks. Ignoring block "
341 "of %ldK at 0x%08x\n", size>>10,
342 (u_long)mh.mh_Lower);
343 } else if (do_chip && mh.mh_Attributes & MEMF_CHIP)
344 /* if CHIP memory, record the size */
345 bi.chip_size = (u_long)mh.mh_Upper;
348 /* get info from ExecBase */
349 if (!bi.vblank)
350 bi.vblank = SysBase->VBlankFrequency;
351 if (!bi.psfreq)
352 bi.psfreq = SysBase->PowerSupplyFrequency;
353 if (!bi.eclock)
354 bi.eclock = SysBase->ex_EClockFrequency;
356 /* serial port */
357 if (!bi.serper) {
358 realbaud = baud ? baud : DEFAULT_BAUD;
359 bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1;
362 /* display Amiga model */
363 if (bi.model >= first_amiga_model && bi.model <= last_amiga_model)
364 Printf("%s ", amiga_models[bi.model-first_amiga_model]);
365 else
366 Puts("Amiga ");
368 /* display the CPU type */
369 Puts("CPU: ");
370 switch (bi.cputype) {
371 case CPU_68020:
372 Puts("68020 (Do you have an MMU?)");
373 break;
374 case CPU_68030:
375 Puts("68030");
376 break;
377 case CPU_68040:
378 Puts("68040");
379 break;
380 case CPU_68060:
381 Puts("68060");
382 break;
383 default:
384 Puts("Insufficient for Linux. Aborting...\n");
385 Printf("SysBase->AttnFlags = 0x%08lx\n", SysBase->AttnFlags);
386 goto Fail;
388 switch (bi.fputype) {
389 case FPU_68881:
390 Puts(" with 68881 FPU");
391 break;
392 case FPU_68882:
393 Puts(" with 68882 FPU");
394 break;
395 case FPU_68040:
396 case FPU_68060:
397 Puts(" with internal FPU");
398 break;
399 default:
400 Puts(" without FPU");
401 break;
404 /* display the chipset */
405 switch (bi.chipset) {
406 case CS_STONEAGE:
407 Puts(", old or unknown chipset");
408 break;
409 case CS_OCS:
410 Puts(", OCS");
411 break;
412 case CS_ECS:
413 Puts(", ECS");
414 break;
415 case CS_AGA:
416 Puts(", AGA chipset");
417 break;
420 /* Look for PowerUp PCI bridge. Signal result to kernel in model type.
421 * Not pretty, but it'll do for now.
423 if (apus_boot) {
424 unsigned long vbr;
426 Puts("\n\n");
427 vbr = (unsigned long) Supervisor((void*)&getvbr);
428 if (probe_powerup(vbr)) {
429 Puts("APUS: PCI Bridge detected.");
430 bi.model += 0x100;
431 } else {
432 Puts("APUS: No PCI Bridge detected.");
436 Puts("\n\n");
438 /* display the command line */
439 Printf("Command line is '%s'\n", bi.command_line);
441 /* display the clock statistics */
442 Printf("Vertical Blank Frequency: %ldHz\n", bi.vblank);
443 Printf("Power Supply Frequency: %ldHz\n", bi.psfreq);
444 Printf("EClock Frequency: %ldHz\n\n", bi.eclock);
446 /* display autoconfig devices */
447 if (bi.num_autocon) {
448 Printf("Found %ld AutoConfig Device%s\n", bi.num_autocon,
449 bi.num_autocon > 1 ? "s" : "");
450 for (i = 0; i < bi.num_autocon; i++) {
451 Printf("Device %ld: addr = 0x%08lx", i,
452 (u_long)zdevs[i]->cd_BoardAddr);
453 boardresetfuncs[i] = NULL;
454 if (reset_boards) {
455 manuf = zdevs[i]->cd_Rom.er_Manufacturer;
456 prod = zdevs[i]->cd_Rom.er_Product;
457 for (j = 0; j < NUM_BOARDRESET; j++)
458 if ((manuf == boardresetdb[j].manuf) &&
459 (prod == boardresetdb[j].prod)) {
460 Printf(" [%s - will be reset at kernel boot time]",
461 boardresetdb[j].name);
462 boardresetfuncs[i] = boardresetdb[j].reset;
463 break;
466 PutChar('\n');
468 } else
469 Puts("No AutoConfig Devices Found\n");
471 /* display memory */
472 if (bi.num_memory) {
473 Printf("\nFound %ld Block%sof Memory\n", bi.num_memory,
474 bi.num_memory > 1 ? "s " : " ");
475 for (i = 0; i < bi.num_memory; i++)
476 Printf("Block %ld: 0x%08lx to 0x%08lx (%ldK)\n", i,
477 bi.memory[i].addr, bi.memory[i].addr+bi.memory[i].size,
478 bi.memory[i].size>>10);
479 } else {
480 Puts("No memory found?! Aborting...\n");
481 goto Fail;
484 /* display chip memory size */
485 Printf("%ldK of CHIP memory\n", bi.chip_size>>10);
487 start_mem = bi.memory[0].addr;
488 mem_size = bi.memory[0].size;
490 /* tell us where the kernel will go */
491 Printf("\nThe kernel will be located at 0x%08lx\n", start_mem);
493 /* verify that there is enough Chip RAM */
494 if (bi.chip_size < 512*1024) {
495 Puts("Not enough Chip RAM in this system. Aborting...\n");
496 goto Fail;
499 /* verify that there is enough Fast RAM */
500 for (fast_total = 0, i = 0; i < bi.num_memory; i++)
501 fast_total += bi.memory[i].size;
502 if (fast_total < 2*1024*1024) {
503 Puts("Not enough Fast RAM in this system. Aborting...\n");
504 goto Fail;
507 /* support for ramdisk */
508 if (ramdiskname) {
509 int size;
511 if ((size = FileSize(ramdiskname)) == -1) {
512 Printf("Unable to find size of ramdisk file `%s'\n", ramdiskname);
513 goto Fail;
515 /* record ramdisk size */
516 bi.ramdisk.size = size;
517 } else
518 bi.ramdisk.size = 0;
519 rd_size = bi.ramdisk.size;
520 bi.ramdisk.addr = (u_long)start_mem+mem_size-rd_size;
522 /* create the bootinfo structure */
523 if (!create_bootinfo())
524 goto Fail;
526 /* open kernel executable and read exec header */
527 if ((kfd = Open(kernelname)) == -1) {
528 Printf("Unable to open kernel file `%s'\n", kernelname);
529 goto Fail;
531 if (KRead(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) {
532 Puts("Unable to read exec header from kernel file\n");
533 goto Fail;
536 #ifdef ZKERNEL
537 if (((unsigned char *)&kexec)[0] == 037 &&
538 (((unsigned char *)&kexec)[1] == 0213 ||
539 ((unsigned char *)&kexec)[1] == 0236)) {
540 /* That's a compressed kernel */
541 Puts("Kernel is compressed\n");
542 if (load_zkernel(kfd)) {
543 Puts("Decompression error -- aborting\n");
544 goto Fail;
547 #endif
549 switch (N_MAGIC(kexec)) {
550 case ZMAGIC:
551 if (debugflag)
552 Puts("\nLoading a.out (ZMAGIC) Linux/m68k kernel...\n");
553 text_offset = N_TXTOFF(kexec);
554 break;
556 case QMAGIC:
557 if (debugflag)
558 Puts("\nLoading a.out (QMAGIC) Linux/m68k kernel...\n");
559 text_offset = sizeof(kexec);
560 /* the text size includes the exec header; remove this */
561 kexec.a_text -= sizeof(kexec);
562 break;
564 default:
565 /* Try to parse it as an ELF header */
566 KSeek(kfd, 0);
567 if ((KRead(kfd, (void *)&kexec_elf, sizeof(kexec_elf)) ==
568 sizeof(kexec_elf)) &&
569 (memcmp(&kexec_elf.e_ident[EI_MAG0], ELFMAG, SELFMAG) == 0)) {
570 elf_kernel = 1;
571 if (debugflag)
572 Puts("\nLoading ELF Linux/m68k kernel...\n");
573 /* A few plausibility checks */
574 if ((kexec_elf.e_type != ET_EXEC) ||
575 (kexec_elf.e_machine != EM_PPC && apus_boot) ||
576 (kexec_elf.e_machine != EM_68K && !apus_boot) ||
577 (kexec_elf.e_version != EV_CURRENT)) {
578 Puts("Invalid ELF header contents in kernel\n");
579 Printf("machine : %d, type: %d, version: %d\n",
580 kexec_elf.e_machine, kexec_elf.e_type, kexec_elf.e_version);
581 goto Fail;
583 /* Load the program headers */
584 if (!(kernel_phdrs =
585 (Elf32_Phdr *)AllocMem(kexec_elf.e_phnum*sizeof(Elf32_Phdr),
586 MEMF_FAST | MEMF_PUBLIC |
587 MEMF_CLEAR))) {
588 Puts("Unable to allocate memory for program headers\n");
589 goto Fail;
591 KSeek(kfd, kexec_elf.e_phoff);
592 if (KRead(kfd, (void *)kernel_phdrs,
593 kexec_elf.e_phnum*sizeof(*kernel_phdrs)) !=
594 kexec_elf.e_phnum*sizeof(*kernel_phdrs)) {
595 Puts("Unable to read program headers from kernel file\n");
596 goto Fail;
598 break;
600 Printf("Wrong magic number 0x%08lx in kernel header\n",
601 N_MAGIC(kexec));
602 goto Fail;
605 /* Load the kernel at one page after start of mem */
606 if (!apus_boot) {
607 start_mem += PAGE_SIZE;
608 mem_size -= PAGE_SIZE;
611 /* Align bss size to multiple of four */
612 if (!elf_kernel)
613 kexec.a_bss = (kexec.a_bss+3) & ~3;
615 /* calculate the total required amount of memory */
616 if (elf_kernel) {
617 u_long min_addr = 0xffffffff, max_addr = 0;
618 for (i = 0; i < kexec_elf.e_phnum; i++) {
619 if (min_addr > kernel_phdrs[i].p_vaddr)
620 min_addr = kernel_phdrs[i].p_vaddr;
621 if (max_addr < kernel_phdrs[i].p_vaddr+kernel_phdrs[i].p_memsz)
622 max_addr = kernel_phdrs[i].p_vaddr+kernel_phdrs[i].p_memsz;
624 /* This is needed for newer linkers that include the header in
625 the first segment. */
626 if (apus_boot) {
627 /* Avoid ugly hacks further down. */
628 kernel_phdrs[0].p_vaddr = PAGE_SIZE;
629 } else if (min_addr == 0) {
630 min_addr = PAGE_SIZE;
631 kernel_phdrs[0].p_vaddr += PAGE_SIZE;
632 kernel_phdrs[0].p_offset += PAGE_SIZE;
633 kernel_phdrs[0].p_filesz -= PAGE_SIZE;
634 kernel_phdrs[0].p_memsz -= PAGE_SIZE;
636 kernel_size = max_addr-min_addr;
637 } else
638 kernel_size = kexec.a_text+kexec.a_data+kexec.a_bss;
639 memreq = kernel_size+bi_size+rd_size;
640 #ifdef BOOTINFO_COMPAT_1_0
641 if (sizeof(compat_bootinfo) > bi_size)
642 memreq = kernel_size+sizeof(compat_bootinfo)+rd_size;
643 #endif /* BOOTINFO_COMPAT_1_0 */
644 if (!(memptr = (char *)AllocMem(memreq, MEMF_FAST | MEMF_PUBLIC |
645 MEMF_CLEAR))) {
646 Puts("Unable to allocate memory\n");
647 goto Fail;
650 /* read the text and data segments from the kernel image */
651 if (elf_kernel)
652 for (i = 0; i < kexec_elf.e_phnum; i++) {
653 if (KSeek(kfd, kernel_phdrs[i].p_offset) == -1) {
654 Printf("Failed to seek to segment %ld\n", i);
655 goto Fail;
657 if (KRead(kfd, memptr+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
658 kernel_phdrs[i].p_filesz) != kernel_phdrs[i].p_filesz) {
659 Printf("Failed to read segment %ld\n", i);
660 goto Fail;
663 else {
664 if (KSeek(kfd, text_offset) == -1) {
665 Puts("Failed to seek to text\n");
666 goto Fail;
668 if (KRead(kfd, memptr, kexec.a_text) != kexec.a_text) {
669 Puts("Failed to read text\n");
670 goto Fail;
672 /* data follows immediately after text */
673 if (KRead(kfd, memptr+kexec.a_text, kexec.a_data) != kexec.a_data) {
674 Puts("Failed to read data\n");
675 goto Fail;
678 KClose(kfd);
679 kfd = -1;
681 /* Check kernel's bootinfo version */
682 switch (apus_boot ? BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION) :
683 check_bootinfo_version(memptr)) {
684 case BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION):
685 bi_ptr = &bi_union.record;
686 break;
688 #ifdef BOOTINFO_COMPAT_1_0
689 case BI_VERSION_MAJOR(COMPAT_AMIGA_BOOTI_VERSION):
690 if (!create_compat_bootinfo())
691 goto Fail;
692 bi_ptr = &compat_bootinfo;
693 bi_size = sizeof(compat_bootinfo);
694 break;
695 #endif /* BOOTINFO_COMPAT_1_0 */
697 default:
698 goto Fail;
701 /* copy the bootinfo to the end of the kernel image */
702 memcpy((void *)(memptr+kernel_size), bi_ptr, bi_size);
704 if (ramdiskname) {
705 if ((rfd = Open(ramdiskname)) == -1) {
706 Printf("Unable to open ramdisk file `%s'\n", ramdiskname);
707 goto Fail;
709 if (Read(rfd, memptr+kernel_size+bi_size, rd_size) != rd_size) {
710 Puts("Failed to read ramdisk file\n");
711 goto Fail;
713 Close(rfd);
714 rfd = -1;
717 /* allocate temporary chip ram stack */
718 if (!(stack = (u_long *)AllocMem(TEMP_STACKSIZE, MEMF_CHIP | MEMF_CLEAR))) {
719 Puts("Unable to allocate memory for stack\n");
720 goto Fail;
723 /* allocate chip ram for copy of startup code */
724 startcodesize = &copyallend-&copyall;
725 if (!(startfunc = (void (*)(void))AllocMem(startcodesize,
726 MEMF_CHIP | MEMF_CLEAR))) {
727 Puts("Unable to allocate memory for startcode\n");
728 goto Fail;
731 /* copy startup code to CHIP RAM */
732 memcpy(startfunc, &copyall, startcodesize);
734 if (debugflag) {
735 if (bi.ramdisk.size)
736 Printf("RAM disk at 0x%08lx, size is %ldK\n",
737 (u_long)memptr+kernel_size, bi.ramdisk.size>>10);
739 if (elf_kernel) {
740 PutChar('\n');
741 for (i = 0; i < kexec_elf.e_phnum; i++)
742 Printf("Kernel segment %ld at 0x%08lx, size %ld\n", i,
743 start_mem+kernel_phdrs[i].p_vaddr-PAGE_SIZE,
744 kernel_phdrs[i].p_memsz);
745 Printf("Boot info at 0x%08lx\n", start_mem+kernel_size);
746 } else {
747 Printf("\nKernel text at 0x%08lx, code size 0x%08lx\n", start_mem,
748 kexec.a_text);
749 Printf("Kernel data at 0x%08lx, data size 0x%08lx\n",
750 start_mem+kexec.a_text, kexec.a_data);
751 Printf("Kernel bss at 0x%08lx, bss size 0x%08lx\n",
752 start_mem+kexec.a_text+kexec.a_data, kexec.a_bss);
753 Printf("Boot info at 0x%08lx\n", start_mem+kernel_size);
755 Printf("\nKernel entry is 0x%08lx\n", elf_kernel ? kexec_elf.e_entry :
756 kexec.a_entry);
758 Printf("ramdisk dest top is 0x%08lx\n", start_mem+mem_size);
759 Printf("ramdisk lower limit is 0x%08lx\n",
760 (u_long)(memptr+kernel_size));
761 Printf("ramdisk src top is 0x%08lx\n",
762 (u_long)(memptr+kernel_size)+rd_size);
764 Puts("\nType a key to continue the Linux/m68k boot...");
765 GetChar();
766 PutChar('\n');
769 /* wait for things to settle down */
770 Sleep(1000000);
774 void* PPCPort;
775 void* PPCMsg;
777 #define CHIP_PTR (0xfff00)
778 #define INFO_SIZE (0x3000 + 0x0100)
779 if (apus_boot) {
780 /* Let the PowerPC handle the actual kernel start */
782 /* Store some relevant information about the kernel image
783 * and RAM disk at *CHIP_PTR.
785 unsigned long boot_msg;
787 /* Make sure the CHIP_PTR will not be destroyed. */
788 if (!AllocAbs (0x10, CHIP_PTR)){
789 Puts("Unable to allocate CHIP memory at 0xfff00.\n"
790 "Try booting with a smaller resolution.\n");
793 if (!(boot_msg = (unsigned long) AllocMem (0x200,
794 MEMF_REVERSE
795 | MEMF_CHIP
796 | MEMF_CLEAR))){
798 Puts("Unable to allocate CHIP memory for boot message\n");
799 goto Fail;
802 if (!(info = (unsigned long*) AllocMem (INFO_SIZE,
803 MEMF_CHIP | MEMF_CLEAR))){
804 Puts("Unable to allocate CHIP memory for info table and"
805 " reloc code\n");
806 goto Fail;
809 /* Leave the pointer in chip mem at address CHIP_PTR. */
810 *((unsigned long*) CHIP_PTR) = (unsigned long) info;
811 info[0] = (unsigned long) (memptr+kernel_phdrs[0].p_vaddr-PAGE_SIZE);
812 info[1] = start_mem;
813 info[2] = kernel_size;
814 info[3] = bi_size;
815 info[4] = rd_size;
816 info[5] = mem_size;
817 info[6] = boot_msg + 0x100;
818 info[7] = 0; /* checksum */
819 info[8] = (unsigned long)info + 0x2000; /* stack */
821 /* Calculate a simple kernel checksum. */
822 if (checksum)
824 int i = (info[2] + info[3]) / 4;
825 unsigned char* k_p = (unsigned char*) info[0];
826 unsigned long kcs = 0;
828 while (i--)
830 unsigned long w = 0;
832 w |= *k_p++;
833 w <<= 8;
834 w |= *k_p++;
835 w <<= 8;
836 w |= *k_p++;
837 w <<= 8;
838 w |= *k_p++;
841 kcs = kcs ^ i;
842 kcs = kcs ^ w;
844 info[7] = kcs;
847 /* Set LVL7 vector ("expose the top rim of our shorts") */
849 unsigned long* vbr;
851 vbr = (unsigned long*) Supervisor((void*)&getvbr);
852 vbr[31] = (unsigned long) &wedgie;
857 void* elfObject;
858 void* task;
859 struct TagItem MyTags[2];
860 struct TagItem tag;
862 /* Load PPC elf object. */
863 MyTags[0].ti_Tag = PPCELFLOADTAG_ELFADDRESS;
864 MyTags[0].ti_Data = (u_long)myppc_boot;
865 MyTags[1].ti_Tag = TAG_DONE;
867 elfObject = (void*) PPCLoadObjectTagList(MyTags);
869 /* Start PPC code, asking for a MSGPORT to be created. */
870 MyTags[0].ti_Tag = PPCTASKTAG_MSGPORT;
871 MyTags[0].ti_Data = TRUE;
872 MyTags[1].ti_Tag = TAG_DONE;
873 task = PPCCreateTask(elfObject, MyTags);
875 tag.ti_Tag = PPCTASKINFOTAG_MSGPORT;
876 if (PPCPort=(void*) PPCGetTaskAttrs(task, &tag))
878 PPCMsg = PPCCreateMessage(NULL, 0);
882 if (PPCPort == 0 || PPCMsg == 0)
884 Puts ("Didn't get contact with PPC task...\n");
885 goto Fail;
890 /* turn off caches */
891 CacheControl(0, ~0);
893 if (!keep_video)
894 /* set graphics mode to a nice normal one */
895 LoadView(NULL);
897 /* reset nasty Zorro boards */
898 if (reset_boards)
899 for (i = 0; i < bi.num_autocon; i++)
900 if (boardresetfuncs[i])
901 boardresetfuncs[i](zdevs[i]);
903 if (apus_boot && PPCPort && PPCMsg)
905 /* Notify the PPC that we are done ("bend over") */
906 PPCSendMessage(PPCPort, PPCMsg, NULL, 0, 0);
907 for (;;) ;
910 /* Go into supervisor state */
911 SuperState();
914 /* Turn off interrupts. */
915 Disable();
917 /* Turn off all DMA */
918 custom.dmacon = DMAF_ALL | DMAF_MASTER;
920 /* turn off any mmu translation */
921 disable_mmu();
923 /* execute the copy-and-go code (from CHIP RAM) */
924 start_kernel(startfunc, (char *)stack+TEMP_STACKSIZE, memptr, start_mem,
925 mem_size, rd_size, kernel_size);
927 /* Clean up and exit in case of a failure */
928 Fail:
929 if (kfd != -1)
930 KClose(kfd);
931 if (rfd != -1)
932 Close(rfd);
933 if (info)
934 FreeMem((void *) info, INFO_SIZE);
935 if (memptr)
936 FreeMem((void *)memptr, memreq);
937 if (stack)
938 FreeMem((void *)stack, TEMP_STACKSIZE);
939 if (kernel_phdrs)
940 FreeMem((void *)kernel_phdrs, kexec_elf.e_phnum*sizeof(Elf32_Phdr));
941 return(FALSE);
946 * Determine the Chipset
949 static u_long get_chipset(void)
951 u_char cs;
952 u_long chipset;
954 if (GfxBase->Version >= 39)
955 cs = SetChipRev(SETCHIPREV_BEST);
956 else
957 cs = GfxBase->ChipRevBits0;
958 if ((cs & GFXG_AGA) == GFXG_AGA)
959 chipset = CS_AGA;
960 else if ((cs & GFXG_ECS) == GFXG_ECS)
961 chipset = CS_ECS;
962 else if ((cs & GFXG_OCS) == GFXG_OCS)
963 chipset = CS_OCS;
964 else
965 chipset = CS_STONEAGE;
966 return(chipset);
971 * Determine the CPU Type
974 static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu)
976 *cpu = *fpu = 0;
978 if (SysBase->AttnFlags & AFF_68060)
979 *cpu = CPU_68060;
980 else if (SysBase->AttnFlags & AFF_68040)
981 *cpu = CPU_68040;
982 else if (SysBase->AttnFlags & AFF_68030)
983 *cpu = CPU_68030;
984 else if (SysBase->AttnFlags & AFF_68020)
985 *cpu = CPU_68020;
987 if (*cpu == CPU_68040 || *cpu == CPU_68060) {
988 if (SysBase->AttnFlags & AFF_FPU40)
989 *fpu = *cpu;
990 } else if (SysBase->AttnFlags & AFF_68882)
991 *fpu = FPU_68882;
992 else if (SysBase->AttnFlags & AFF_68881)
993 *fpu = FPU_68881;
995 *mmu = *cpu;
999 * Determine the Amiga Model
1002 static u_long get_model(u_long chipset)
1004 u_long model = AMI_UNKNOWN;
1006 if (debugflag)
1007 Puts("Amiga model identification:\n");
1008 if (probe_resource("draco.resource"))
1009 model = AMI_DRACO;
1010 else {
1011 if (debugflag)
1012 Puts(" Chipset: ");
1013 switch (chipset) {
1014 case CS_STONEAGE:
1015 if (debugflag)
1016 Puts("Old or unknown\n");
1017 goto OCS;
1018 break;
1020 case CS_OCS:
1021 if (debugflag)
1022 Puts("OCS\n");
1023 OCS: if (probe_resident("cd.device"))
1024 model = AMI_CDTV;
1025 else
1026 /* let's call it an A2000 (may be A500, A1000, A2500) */
1027 model = AMI_2000;
1028 break;
1030 case CS_ECS:
1031 if (debugflag)
1032 Puts("ECS\n");
1033 if (probe_resident("Magic 36.7") ||
1034 probe_resident("kickad 36.57") ||
1035 probe_resident("A3000 Bonus") ||
1036 probe_resident("A3000 bonus"))
1037 /* let's call it an A3000 (may be A3000T) */
1038 model = AMI_3000;
1039 else if (probe_resource("card.resource"))
1040 model = AMI_600;
1041 else
1042 /* let's call it an A2000 (may be A500[+], A1000, A2500) */
1043 model = AMI_2000;
1044 break;
1046 case CS_AGA:
1047 if (debugflag)
1048 Puts("AGA\n");
1049 if (probe_resident("A1000 Bonus") ||
1050 probe_resident("A4000 bonus"))
1051 model = probe_resident("NCR scsi.device") ? AMI_4000T :
1052 AMI_4000;
1053 else if (probe_resource("card.resource"))
1054 model = AMI_1200;
1055 else if (probe_resident("cd.device"))
1056 model = AMI_CD32;
1057 else
1058 model = AMI_3000PLUS;
1059 break;
1062 if (debugflag) {
1063 Puts("\nType a key to continue...");
1064 GetChar();
1065 Puts("\n\n");
1067 return(model);
1072 * Probe for a Resident Modules
1075 static int probe_resident(const char *name)
1077 const struct Resident *res;
1079 if (debugflag)
1080 Printf(" Module `%s': ", name);
1081 res = FindResident(name);
1082 if (debugflag)
1083 if (res)
1084 Printf("0x%08lx\n", res);
1085 else
1086 Puts("not present\n");
1087 return(res ? TRUE : FALSE);
1092 * Probe for an available Resource
1095 static int probe_resource(const char *name)
1097 const void *res;
1099 if (debugflag)
1100 Printf(" Resource `%s': ", name);
1101 res = OpenResource(name);
1102 if (debugflag)
1103 if (res)
1104 Printf("0x%08lx\n", res);
1105 else
1106 Puts("not present\n");
1107 return(res ? TRUE : FALSE);
1112 * Create the Bootinfo structure
1115 static int create_bootinfo(void)
1117 int i;
1118 struct bi_record *record;
1120 /* Initialization */
1121 bi_size = 0;
1123 /* Generic tags */
1124 if (!add_bi_record(BI_MACHTYPE, sizeof(bi.machtype), &bi.machtype))
1125 return(0);
1126 if (!add_bi_record(BI_CPUTYPE, sizeof(bi.cputype), &bi.cputype))
1127 return(0);
1128 if (!add_bi_record(BI_FPUTYPE, sizeof(bi.fputype), &bi.fputype))
1129 return(0);
1130 if (!add_bi_record(BI_MMUTYPE, sizeof(bi.mmutype), &bi.mmutype))
1131 return(0);
1132 for (i = 0; i < bi.num_memory; i++)
1133 if (!add_bi_record(BI_MEMCHUNK, sizeof(bi.memory[i]), &bi.memory[i]))
1134 return(0);
1135 if (bi.ramdisk.size)
1136 if (!add_bi_record(BI_RAMDISK, sizeof(bi.ramdisk), &bi.ramdisk))
1137 return(0);
1138 if (!add_bi_string(BI_COMMAND_LINE, bi.command_line))
1139 return(0);
1141 /* Amiga tags */
1142 if (!add_bi_record(BI_AMIGA_MODEL, sizeof(bi.model), &bi.model))
1143 return(0);
1144 for (i = 0; i < bi.num_autocon; i++)
1145 if (!add_bi_record(BI_AMIGA_AUTOCON, sizeof(bi.autocon[i]),
1146 &bi.autocon[i]))
1147 return(0);
1148 if (!add_bi_record(BI_AMIGA_CHIP_SIZE, sizeof(bi.chip_size), &bi.chip_size))
1149 return(0);
1150 if (!add_bi_record(BI_AMIGA_VBLANK, sizeof(bi.vblank), &bi.vblank))
1151 return(0);
1152 if (!add_bi_record(BI_AMIGA_PSFREQ, sizeof(bi.psfreq), &bi.psfreq))
1153 return(0);
1154 if (!add_bi_record(BI_AMIGA_ECLOCK, sizeof(bi.eclock), &bi.eclock))
1155 return(0);
1156 if (!add_bi_record(BI_AMIGA_CHIPSET, sizeof(bi.chipset), &bi.chipset))
1157 return(0);
1158 if (!add_bi_record(BI_AMIGA_SERPER, sizeof(bi.serper), &bi.serper))
1159 return(0);
1161 /* Trailer */
1162 record = (struct bi_record *)((u_long)&bi_union.record+bi_size);
1163 record->tag = BI_LAST;
1164 bi_size += sizeof(bi_union.record.tag);
1166 return(1);
1171 * Add a Record to the Bootinfo Structure
1174 static int add_bi_record(u_short tag, u_short size, const void *data)
1176 struct bi_record *record;
1177 u_int size2;
1179 size2 = (sizeof(struct bi_record)+size+3)&-4;
1180 if (bi_size+size2+sizeof(bi_union.record.tag) > MAX_BI_SIZE) {
1181 Puts("Can't add bootinfo record. Ask a wizard to enlarge me.\n");
1182 return(0);
1184 record = (struct bi_record *)((u_long)&bi_union.record+bi_size);
1185 record->tag = tag;
1186 record->size = size2;
1187 memcpy(record->data, data, size);
1188 bi_size += size2;
1189 return(1);
1194 * Add a String Record to the Bootinfo Structure
1197 static int add_bi_string(u_short tag, const u_char *s)
1199 return(add_bi_record(tag, strlen(s)+1, (void *)s));
1203 #ifdef BOOTINFO_COMPAT_1_0
1206 * Create the Bootinfo structure for backwards compatibility mode
1209 static int create_compat_bootinfo(void)
1211 u_int i;
1213 compat_bootinfo.machtype = bi.machtype;
1214 if (bi.cputype & CPU_68020)
1215 compat_bootinfo.cputype = COMPAT_CPU_68020;
1216 else if (bi.cputype & CPU_68030)
1217 compat_bootinfo.cputype = COMPAT_CPU_68030;
1218 else if (bi.cputype & CPU_68040)
1219 compat_bootinfo.cputype = COMPAT_CPU_68040;
1220 else if (bi.cputype & CPU_68060)
1221 compat_bootinfo.cputype = COMPAT_CPU_68060;
1222 else {
1223 Printf("CPU type 0x%08lx not supported by kernel\n", bi.cputype);
1224 return(0);
1226 if (bi.fputype & FPU_68881)
1227 compat_bootinfo.cputype |= COMPAT_FPU_68881;
1228 else if (bi.fputype & FPU_68882)
1229 compat_bootinfo.cputype |= COMPAT_FPU_68882;
1230 else if (bi.fputype & FPU_68040)
1231 compat_bootinfo.cputype |= COMPAT_FPU_68040;
1232 else if (bi.fputype & FPU_68060)
1233 compat_bootinfo.cputype |= COMPAT_FPU_68060;
1234 else if (bi.fputype) {
1235 Printf("FPU type 0x%08lx not supported by kernel\n", bi.fputype);
1236 return(0);
1238 compat_bootinfo.num_memory = bi.num_memory;
1239 if (compat_bootinfo.num_memory > COMPAT_NUM_MEMINFO) {
1240 Printf("Warning: using only %ld blocks of memory\n",
1241 COMPAT_NUM_MEMINFO);
1242 compat_bootinfo.num_memory = COMPAT_NUM_MEMINFO;
1244 for (i = 0; i < compat_bootinfo.num_memory; i++) {
1245 compat_bootinfo.memory[i].addr = bi.memory[i].addr;
1246 compat_bootinfo.memory[i].size = bi.memory[i].size;
1248 if (bi.ramdisk.size) {
1249 compat_bootinfo.ramdisk_size = (bi.ramdisk.size+1023)/1024;
1250 compat_bootinfo.ramdisk_addr = bi.ramdisk.addr;
1251 } else {
1252 compat_bootinfo.ramdisk_size = 0;
1253 compat_bootinfo.ramdisk_addr = 0;
1255 strncpy(compat_bootinfo.command_line, bi.command_line, COMPAT_CL_SIZE);
1256 compat_bootinfo.command_line[COMPAT_CL_SIZE-1] = '\0';
1258 compat_bootinfo.bi_amiga.model = bi.model;
1259 compat_bootinfo.bi_amiga.num_autocon = bi.num_autocon;
1260 if (compat_bootinfo.bi_amiga.num_autocon > COMPAT_NUM_AUTO) {
1261 Printf("Warning: using only %ld AutoConfig devices\n",
1262 COMPAT_NUM_AUTO);
1263 compat_bootinfo.bi_amiga.num_autocon = COMPAT_NUM_AUTO;
1265 for (i = 0; i < compat_bootinfo.bi_amiga.num_autocon; i++)
1266 compat_bootinfo.bi_amiga.autocon[i] = bi.autocon[i];
1267 compat_bootinfo.bi_amiga.chip_size = bi.chip_size;
1268 compat_bootinfo.bi_amiga.vblank = bi.vblank;
1269 compat_bootinfo.bi_amiga.psfreq = bi.psfreq;
1270 compat_bootinfo.bi_amiga.eclock = bi.eclock;
1271 compat_bootinfo.bi_amiga.chipset = bi.chipset;
1272 compat_bootinfo.bi_amiga.hw_present = 0;
1273 return(1);
1275 #endif /* BOOTINFO_COMPAT_1_0 */
1279 * Compare the Bootstrap and Kernel Versions
1282 static int check_bootinfo_version(const char *memptr)
1284 const struct bootversion *bv = (struct bootversion *)memptr;
1285 unsigned long version = 0;
1286 int i, kernel_major, kernel_minor, boots_major, boots_minor;
1288 if (bv->magic == BOOTINFOV_MAGIC)
1289 for (i = 0; bv->machversions[i].machtype != 0; ++i)
1290 if (bv->machversions[i].machtype == MACH_AMIGA) {
1291 version = bv->machversions[i].version;
1292 break;
1294 if (!version)
1295 Puts("Kernel has no bootinfo version info, assuming 0.0\n");
1297 kernel_major = BI_VERSION_MAJOR(version);
1298 kernel_minor = BI_VERSION_MINOR(version);
1299 boots_major = BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION);
1300 boots_minor = BI_VERSION_MINOR(AMIGA_BOOTI_VERSION);
1301 Printf("Bootstrap's bootinfo version: %ld.%ld\n", boots_major,
1302 boots_minor);
1303 Printf("Kernel's bootinfo version : %ld.%ld\n", kernel_major,
1304 kernel_minor);
1306 switch (kernel_major) {
1307 case BI_VERSION_MAJOR(AMIGA_BOOTI_VERSION):
1308 if (kernel_minor > boots_minor) {
1309 Puts("Warning: Bootinfo version of bootstrap and kernel "
1310 "differ!\n");
1311 Puts(" Certain features may not work.\n");
1313 break;
1315 #ifdef BOOTINFO_COMPAT_1_0
1316 case BI_VERSION_MAJOR(COMPAT_AMIGA_BOOTI_VERSION):
1317 Puts("(using backwards compatibility mode)\n");
1318 break;
1319 #endif /* BOOTINFO_COMPAT_1_0 */
1321 default:
1322 Printf("\nThis bootstrap is too %s for this kernel!\n",
1323 boots_major < kernel_major ? "old" : "new");
1324 return(0);
1326 return(kernel_major);
1331 * Call the copy-and-go-code
1334 static void start_kernel(void (*startfunc)(), char *stackp, char *memptr,
1335 u_long start_mem, u_long mem_size, u_long rd_size,
1336 u_long kernel_size)
1338 register void (*a0)() __asm("a0") = startfunc;
1339 register char *a2 __asm("a2") = stackp;
1340 register char *a3 __asm("a3") = memptr;
1341 register u_long a4 __asm("a4") = start_mem;
1342 register u_long d0 __asm("d0") = mem_size;
1343 register u_long d1 __asm("d1") = rd_size;
1344 register u_long d2 __asm("d2") = kernel_size;
1345 register u_long d3 __asm("d3") = bi_size;
1347 __asm __volatile ("movel a2,sp;"
1348 "jmp a0@"
1349 : /* no outputs */
1350 : "r" (a0), "r" (a2), "r" (a3), "r" (a4), "r" (d0),
1351 "r" (d1), "r" (d2), "r" (d3)
1352 /* no return */);
1353 /* fake a noreturn */
1354 for (;;);
1357 asm(".text\n"
1358 ".align 4\n"
1359 SYMBOL_NAME_STR(_getvbr) ":
1360 movec vbr,d0
1365 /* LPSTOP cannot be used on the 68060. Apparently the
1366 CyberStorm bus design cannot cope with it.*/
1367 /* Just let the 68k hang for now. */
1368 asm(".text\n"
1369 ".align 4\n"
1370 SYMBOL_NAME_STR(_wedgie) ":
1371 stop #0x2700
1375 asm(".text\n"
1376 ".align 4\n"
1377 SYMBOL_NAME_STR(_probe_powerup) ":
1378 moveml d2/a5/a6,a7@-
1379 movel d0,a0
1380 leal 99f,a1
1381 movel a0@(8),d1
1382 movel a1,a0@(8)
1383 moveq #1,d0
1385 leal 0xfffe0000,a1
1387 movel a1@,d2
1389 swap d2
1390 andil #0xff,d2
1391 bne 20f
1394 clrl a1@(0x30)
1396 movel a1@,d2
1398 andil #3,d2
1399 bne 20f
1402 movel #3,a1@(0x30)
1404 movel a1@,d2
1406 andil #3,d2
1407 cmpw #3,d2
1408 bne 20f
1410 10: movel d1,a0@(8)
1411 moveml a7@+,d2/a5/a6
1414 20: moveq #0,d0
1415 bra 10b
1417 99: addql #2,a7@(2)
1418 moveq #0,d0
1423 * This assembler code is copied to chip ram, and then executed.
1424 * It copies the kernel to it's final resting place.
1426 * It is called with:
1428 * a3 = memptr
1429 * a4 = start_mem
1430 * d0 = mem_size
1431 * d1 = rd_size
1432 * d2 = kernel_size
1433 * d3 = bi_size
1436 asm(".text\n"
1437 ".align 4\n"
1438 SYMBOL_NAME_STR(_copyall) ":
1439 | /* copy kernel text and data */
1440 movel a3,a0 | src = (u_long *)memptr;
1441 movel a0,a2 | limit = (u_long *)(memptr+kernel_size);
1442 addl d2,a2
1443 movel a4,a1 | dest = (u_long *)start_mem;
1444 1: cmpl a0,a2
1445 jeq 2f | while (src < limit)
1446 moveb a0@+,a1@+ | *dest++ = *src++;
1447 jra 1b
1449 | /* copy bootinfo to end of bss */
1450 movel a3,a0 | src = (u_long *)(memptr+kernel_size);
1451 addl d2,a0 | dest = end of bss (already in a1)
1452 movel d3,d7 | count = bi_size
1453 subql #1,d7
1454 1: moveb a0@+,a1@+ | while (--count > -1)
1455 dbra d7,1b | *dest++ = *src++
1457 | /* copy the ramdisk to the top of memory */
1458 | /* (from back to front) */
1459 movel a4,a1 | dest = (u_long *)(start_mem+mem_size);
1460 addl d0,a1
1461 movel a3,a2 | limit = (u_long *)(memptr+kernel_size +
1462 addl d2,a2 | bi_size);
1463 addl d3,a2
1464 movel a2,a0 | src = (u_long *)((u_long)limit+rd_size);
1465 addl d1,a0
1466 1: cmpl a0,a2
1467 beqs 2f | while (src > limit)
1468 moveb a0@-,a1@- | *--dest = *--src;
1469 bras 1b
1471 | /* jump to start of kernel */
1472 movel a4,a0 | jump_to (start_mem);
1473 jmp a0@
1475 SYMBOL_NAME_STR(_copyallend) ":
1480 * Test for a MapROMmed A3640 Board
1483 asm(".text\n"
1484 ".align 4\n"
1485 SYMBOL_NAME_STR(_maprommed) ":
1486 oriw #0x0700,sr
1487 moveml #0x3f20,sp@-
1488 | /* Save cache settings */
1489 .long 0x4e7a1002 | movec cacr,d1 */
1490 | /* Save MMU settings */
1491 .long 0x4e7a2003 | movec tc,d2
1492 .long 0x4e7a3004 | movec itt0,d3
1493 .long 0x4e7a4005 | movec itt1,d4
1494 .long 0x4e7a5006 | movec dtt0,d5
1495 .long 0x4e7a6007 | movec dtt1,d6
1496 moveq #0,d0
1497 movel d0,a2
1498 | /* Disable caches */
1499 .long 0x4e7b0002 | movec d0,cacr
1500 | /* Disable MMU */
1501 .long 0x4e7b0003 | movec d0,tc
1502 .long 0x4e7b0004 | movec d0,itt0
1503 .long 0x4e7b0005 | movec d0,itt1
1504 .long 0x4e7b0006 | movec d0,dtt0
1505 .long 0x4e7b0007 | movec d0,dtt1
1506 lea 0x07f80000,a0
1507 lea 0x00f80000,a1
1508 movel a0@,d7
1509 cmpl a1@,d7
1510 jne 1f
1511 movel d7,d0
1512 notl d0
1513 movel d0,a0@
1514 nop | /* Thanks to Jörg Mayer! */
1515 cmpl a1@,d0
1516 jne 1f
1517 moveq #-1,d0 | /* MapROMmed A3640 present */
1518 movel d0,a2
1519 1: movel d7,a0@
1520 | /* Restore MMU settings */
1521 .long 0x4e7b2003 | movec d2,tc
1522 .long 0x4e7b3004 | movec d3,itt0
1523 .long 0x4e7b4005 | movec d4,itt1
1524 .long 0x4e7b5006 | movec d5,dtt0
1525 .long 0x4e7b6007 | movec d6,dtt1
1526 | /* Restore cache settings */
1527 .long 0x4e7b1002 | movec d1,cacr
1528 movel a2,d0
1529 moveml sp@+,#0x04fc
1535 * Reset functions for nasty Zorro boards
1538 static void reset_rb3(const struct ConfigDev *cd)
1540 volatile u_char *rb3_reg = (u_char *)(cd->cd_BoardAddr+0x01002000);
1542 /* FN: If a Rainbow III board is present, reset it to disable */
1543 /* its (possibly activated) vertical blank interrupts as the */
1544 /* kernel is not yet prepared to handle them (level 6). */
1546 /* set RESET bit in special function register */
1547 *rb3_reg = 0x01;
1548 /* actually, only a few cycles delay are required... */
1549 Sleep(1000000);
1550 /* clear reset bit */
1551 *rb3_reg = 0x00;
1554 static void reset_piccolo(const struct ConfigDev *cd)
1556 volatile u_char *piccolo_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
1558 /* FN: the same stuff as above, for the Piccolo board. */
1559 /* this also has the side effect of resetting the board's */
1560 /* output selection logic to use the Amiga's display in single */
1561 /* monitor systems - which is currently what we want. */
1563 /* set RESET bit in special function register */
1564 *piccolo_reg = 0x01;
1565 /* actually, only a few cycles delay are required... */
1566 Sleep(1000000);
1567 /* clear reset bit */
1568 *piccolo_reg = 0x51;
1571 static void reset_sd64(const struct ConfigDev *cd)
1573 volatile u_char *sd64_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
1575 /* FN: the same stuff as above, for the SD64 board. */
1576 /* just as on the Piccolo, this also resets the monitor switch */
1578 /* set RESET bit in special function register */
1579 *sd64_reg = 0x1f;
1580 /* actually, only a few cycles delay are required... */
1581 Sleep(1000000);
1582 /* clear reset bit AND switch monitor bit (0x20) */
1583 *sd64_reg = 0x4f;
1586 static void reset_a2065(const struct ConfigDev *cd)
1588 volatile u_short *lance_rdp = (u_short *)(cd->cd_BoardAddr+0x4000);
1589 volatile u_short *lance_rap = (u_short *)(cd->cd_BoardAddr+0x4002);
1591 Disable();
1593 /* Stop the card */
1594 *lance_rap = 0; /* PCnet-ISA Controller Status (CSR0) */
1595 *lance_rdp = 4; /* STOP */
1597 Enable();
1600 static void reset_ariadne(const struct ConfigDev *cd)
1602 volatile u_short *lance_rdp = (u_short *)(cd->cd_BoardAddr+0x0370);
1603 volatile u_short *lance_rap = (u_short *)(cd->cd_BoardAddr+0x0372);
1604 volatile u_short *lance_reset = (u_short *)(cd->cd_BoardAddr+0x0374);
1606 volatile u_char *pit_paddr = (u_char *)(cd->cd_BoardAddr+0x1004);
1607 volatile u_char *pit_pbddr = (u_char *)(cd->cd_BoardAddr+0x1006);
1608 volatile u_char *pit_pacr = (u_char *)(cd->cd_BoardAddr+0x100b);
1609 volatile u_char *pit_pbcr = (u_char *)(cd->cd_BoardAddr+0x100e);
1610 volatile u_char *pit_psr = (u_char *)(cd->cd_BoardAddr+0x101a);
1612 u_short in;
1614 Disable();
1617 * Reset the Ethernet part (Am79C960 PCnet-ISA)
1620 in = *lance_reset; /* Reset Chip on Read Access */
1621 *lance_rap = 0x0000; /* PCnet-ISA Controller Status (CSR0) */
1622 *lance_rdp = 0x0400; /* STOP */
1625 * Reset the Parallel part (MC68230 PI/T)
1628 *pit_pacr &= 0xfd; /* Port A Control Register */
1629 *pit_pbcr &= 0xfd; /* Port B Control Register */
1630 *pit_psr = 0x05; /* Port Status Register */
1631 *pit_paddr = 0x00; /* Port A Data Direction Register */
1632 *pit_pbddr = 0x00; /* Port B Data Direction Register */
1634 Enable();
1637 static void reset_hydra(const struct ConfigDev *cd)
1639 volatile u_char *nic_cr = (u_char *)(cd->cd_BoardAddr+0xffe1);
1640 volatile u_char *nic_isr = (u_char *)(cd->cd_BoardAddr+0xffe1 + 14);
1641 int n = 5000;
1643 Disable();
1645 *nic_cr = 0x21; /* nic command register: software reset etc. */
1646 while (((*nic_isr & 0x80) == 0) && --n) /* wait for reset to complete */
1649 Enable();
1652 #if 0
1653 static void reset_a2060(const struct ConfigDev *cd)
1655 #error reset_a2060: not yet implemented
1657 #endif
1660 #ifdef ZKERNEL
1662 #define ZFILE_CHUNK_BITS 16 /* chunk is 64 KB */
1663 #define ZFILE_CHUNK_SIZE (1 << ZFILE_CHUNK_BITS)
1664 #define ZFILE_CHUNK_MASK (ZFILE_CHUNK_SIZE-1)
1665 #define ZFILE_N_CHUNKS (2*1024*1024/ZFILE_CHUNK_SIZE)
1667 /* variables for storing the uncompressed data */
1668 static char *ZFile[ZFILE_N_CHUNKS];
1669 static int ZFileSize = 0;
1670 static int ZFpos = 0;
1671 static int Zwpos = 0;
1673 static int Zinfd = 0; /* fd of compressed file */
1676 * gzip declarations
1679 #define OF(args) args
1681 #define memzero(s, n) memset ((s), 0, (n))
1683 typedef unsigned char uch;
1684 typedef unsigned short ush;
1685 typedef unsigned long ulg;
1687 #define INBUFSIZ 4096
1688 #define WSIZE 0x8000 /* window size--must be a power of two, and */
1689 /* at least 32K for zip's deflate method */
1691 static uch *inbuf;
1692 static uch *window;
1694 static unsigned insize = 0; /* valid bytes in inbuf */
1695 static unsigned inptr = 0; /* index of next byte to be processed in inbuf */
1696 static unsigned outcnt = 0; /* bytes in output buffer */
1697 static int exit_code = 0;
1698 static long bytes_out = 0;
1700 #define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
1702 /* Diagnostic functions (stubbed out) */
1703 #define Assert(cond,msg)
1704 #define Trace(x)
1705 #define Tracev(x)
1706 #define Tracevv(x)
1707 #define Tracec(c,x)
1708 #define Tracecv(c,x)
1710 #define STATIC static
1712 static int fill_inbuf(void);
1713 static void flush_window(void);
1714 static void error(char *m);
1715 static void gzip_mark(void **);
1716 static void gzip_release(void **);
1718 #define malloc(x) AllocVec(x, MEMF_FAST | MEMF_PUBLIC)
1719 #define free(x) FreeVec(x)
1721 #ifdef LILO
1722 #include "inflate.c"
1723 #else
1724 #include "../../../../lib/inflate.c"
1725 #endif
1727 static void gzip_mark(void **ptr)
1731 static void gzip_release(void **ptr)
1737 * Fill the input buffer. This is called only when the buffer is empty
1738 * and at least one byte is really needed.
1740 static int fill_inbuf(void)
1742 if (exit_code)
1743 return -1;
1745 insize = Read(Zinfd, inbuf, INBUFSIZ);
1746 if (insize <= 0)
1747 return -1;
1749 inptr = 1;
1750 return(inbuf[0]);
1754 * Write the output window window[0..outcnt-1] and update crc and bytes_out.
1755 * (Used for the decompressed data only.)
1757 static void flush_window(void)
1759 ulg c = crc; /* temporary variable */
1760 unsigned n;
1761 uch *in, ch;
1762 int chunk = Zwpos >> ZFILE_CHUNK_BITS;
1764 if (exit_code)
1765 return;
1767 if (chunk >= ZFILE_N_CHUNKS) {
1768 error("Compressed image too large! Aborting.\n");
1769 return;
1771 if (!ZFile[chunk]) {
1772 if (!(ZFile[chunk] = (char *)AllocMem(ZFILE_CHUNK_SIZE,
1773 MEMF_FAST | MEMF_PUBLIC))) {
1774 error("Out of memory for decompresing kernel image\n");
1775 return;
1778 memcpy(ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt);
1779 Zwpos += outcnt;
1781 #define DISPLAY_BITS 10
1782 if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0)
1783 PutChar('.');
1785 in = window;
1786 for (n = 0; n < outcnt; n++) {
1787 ch = *in++;
1788 c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
1790 crc = c;
1791 bytes_out += (ulg)outcnt;
1792 outcnt = 0;
1795 static void error(char *x)
1797 Printf("\n%s", x);
1798 exit_code = 1;
1801 static inline int call_sub(int (*func)(void), void *stackp)
1803 register int _res __asm("d0");
1804 register int (*a0)(void) __asm("a0") = func;
1805 register int (*a1)(void) __asm("a1") = stackp;
1807 __asm __volatile ("movel sp,a2;"
1808 "movel a1,sp;"
1809 "jsr a0@;"
1810 "movel a2,sp"
1811 : "=r" (_res)
1812 : "r" (a0), "r" (a1)
1813 : "a0", "a1", "a2", "d0", "d1", "memory");
1814 return(_res);
1817 static int load_zkernel(int fd)
1819 int i, err = -1;
1820 #define ZSTACKSIZE (16384)
1821 u_long *zstack;
1823 for (i = 0; i < ZFILE_N_CHUNKS; ++i)
1824 ZFile[i] = NULL;
1825 Zinfd = fd;
1826 Seek(fd, 0);
1828 if (!(inbuf = (uch *)AllocMem(INBUFSIZ, MEMF_FAST | MEMF_PUBLIC)))
1829 Puts("Couldn't allocate gunzip buffer\n");
1830 else {
1831 if (!(window = (uch *)AllocMem(WSIZE, MEMF_FAST | MEMF_PUBLIC)))
1832 Puts("Couldn't allocate gunzip window\n");
1833 else {
1834 if (!(zstack = (u_long *)AllocMem(ZSTACKSIZE,
1835 MEMF_FAST | MEMF_PUBLIC)))
1836 Puts("Couldn't allocate gunzip stack\n");
1837 else {
1838 Puts("Uncompressing kernel image ");
1839 makecrc();
1840 if (!(err = call_sub(gunzip, (char *)zstack+ZSTACKSIZE)))
1841 Puts("done\n");
1842 ZFileSize = Zwpos;
1843 FreeMem(zstack, ZSTACKSIZE);
1845 FreeMem(window, WSIZE);
1846 window = NULL;
1848 FreeMem(inbuf, INBUFSIZ);
1849 inbuf = NULL;
1851 Close(Zinfd); /* input file not needed anymore */
1852 return(err);
1856 /* Note about the read/lseek wrapper and its memory management: It assumes
1857 * that all seeks are only forward, and thus data already read or skipped can
1858 * be freed. This is true for current organization of bootstrap and kernels.
1859 * Little exception: The struct kexec at the start of the file. After reading
1860 * it, there may be a seek back to the end of the file. But this currently
1861 * doesn't hurt. (Roman)
1864 static int KRead(int fd, void *buf, int cnt)
1866 unsigned done = 0;
1868 if (!ZFileSize)
1869 return(Read(fd, buf, cnt));
1871 if (ZFpos + cnt > ZFileSize)
1872 cnt = ZFileSize - ZFpos;
1874 while (cnt > 0) {
1875 unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS;
1876 unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS;
1877 unsigned n = cnt;
1879 if (ZFpos + n > endchunk)
1880 n = endchunk - ZFpos;
1881 memcpy(buf, ZFile[chunk] + (ZFpos & ZFILE_CHUNK_MASK), n);
1882 cnt -= n;
1883 buf += n;
1884 done += n;
1885 ZFpos += n;
1887 if (ZFpos == endchunk) {
1888 FreeMem(ZFile[chunk], ZFILE_CHUNK_SIZE);
1889 ZFile[chunk] = NULL;
1893 return(done);
1897 static int KSeek(int fd, int offset)
1899 unsigned oldpos, oldchunk, newchunk;
1901 if (!ZFileSize)
1902 return(Seek(fd, offset));
1904 oldpos = ZFpos;
1905 ZFpos = offset;
1906 if (ZFpos < 0) {
1907 ZFpos = 0;
1908 return(-1);
1909 } else if (ZFpos > ZFileSize) {
1910 ZFpos = ZFileSize;
1911 return(-1);
1914 /* free memory of skipped-over data */
1915 oldchunk = oldpos >> ZFILE_CHUNK_BITS;
1916 newchunk = ZFpos >> ZFILE_CHUNK_BITS;
1917 while(oldchunk < newchunk) {
1918 if (ZFile[oldchunk]) {
1919 FreeMem(ZFile[oldchunk], ZFILE_CHUNK_SIZE);
1920 ZFile[oldchunk] = NULL;
1922 ++oldchunk;
1924 return(ZFpos);
1928 static void free_zfile(void)
1930 int i;
1932 for (i = 0; i < ZFILE_N_CHUNKS; ++i)
1933 if (ZFile[i]) {
1934 FreeMem(ZFile[i], ZFILE_CHUNK_SIZE);
1935 ZFile[i] = NULL;
1939 static int KClose(int fd)
1941 if (ZFileSize) {
1942 free_zfile();
1943 ZFileSize = 0;
1944 } else
1945 Close(fd);
1946 return(0);
1948 #endif /* ZKERNEL */