home *** CD-ROM | disk | FTP | other *** search
/ ANews 2 / AnewsCD2.iso / LinuxPPC / Amiga / linuxboot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-10-08  |  50.5 KB  |  1,949 lines

  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.
  5.  *
  6.  *    Created 1996 by Geert Uytterhoeven
  7.  *
  8.  *
  9.  *  This file is based on the original bootstrap code (bootstrap.c):
  10.  *
  11.  *    Copyright (C) 1993, 1994 Hamish Macdonald
  12.  *                 Greg Harp
  13.  *
  14.  *            with work by Michael Rausch
  15.  *                 Geert Uytterhoeven
  16.  *                 Frank Neumann
  17.  *                 Andreas Schwab
  18.  *                 Jesper Skov
  19.  *
  20.  *
  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.
  24.  *
  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)
  45.  */
  46.  
  47.  
  48. #ifndef __GNUC__
  49. #error GNU CC is required to compile this program
  50. #endif /* __GNUC__ */
  51.  
  52.  
  53. #define BOOTINFO_COMPAT_1_0    /* bootinfo interface version 1.0 compatible */
  54. /* support compressed kernels? */
  55. #define ZKERNEL
  56.  
  57. #include <stddef.h>
  58. #include <string.h>
  59. #include <errno.h>
  60. #include <sys/types.h>
  61.  
  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>
  68.  
  69. #include "linuxboot.h"
  70.  
  71. #define APUS
  72. #ifdef APUS
  73.  
  74. #define INTUITION_CLASSES_H 1
  75.  
  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"
  82.  
  83. #endif
  84.  
  85. #undef custom
  86. #define custom ((*(volatile struct CUSTOM *)(CUSTOM_PHYSADDR)))
  87.  
  88. /* temporary stack size */
  89. #define TEMP_STACKSIZE    (256)
  90.  
  91. #define DEFAULT_BAUD    (9600)
  92.  
  93. extern char copyall, copyallend;
  94.  
  95. extern char getvbr, wedgie;
  96.  
  97. static struct exec kexec;
  98. static Elf32_Ehdr kexec_elf;
  99. static const struct linuxboot_args *linuxboot_args;
  100.  
  101. /* Bootinfo */
  102. struct amiga_bootinfo bi;
  103.  
  104. #ifdef BOOTINFO_COMPAT_1_0
  105. static struct compat_bootinfo compat_bootinfo;
  106. #endif /* BOOTINFO_COMPAT_1_0 */
  107.  
  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;
  114.  
  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
  121.  
  122. #define apus_boot    linuxboot_args->apus_boot
  123. #define checksum    linuxboot_args->checksum
  124.  
  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
  135.  
  136.     /*
  137.      *  Function Prototypes
  138.      */
  139.  
  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
  168.  
  169.  
  170.     /*
  171.      *    Reset functions for nasty Zorro boards
  172.      */
  173.  
  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
  183.  
  184. struct boardreset {
  185.     u_short manuf;
  186.     u_short prod;
  187.     const char *name;
  188.     void (*reset)(const struct ConfigDev *cd);
  189. };
  190.  
  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
  201. };
  202. #define NUM_BOARDRESET    sizeof(boardresetdb)/sizeof(*boardresetdb)
  203.  
  204. static void (*boardresetfuncs[ZORRO_NUM_AUTO])(const struct ConfigDev *cd);
  205.  
  206.  
  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"
  211. };
  212. const u_long first_amiga_model = AMI_500;
  213. const u_long last_amiga_model = AMI_DRACO;
  214.  
  215.  
  216. #define MASK(model)    (1<<AMI_##model)
  217.  
  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))
  221.  
  222.  
  223.     /*
  224.      *    Boot the Linux/m68k Operating System
  225.      */
  226.  
  227. u_long linuxboot(const struct linuxboot_args *args)
  228. {
  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];
  246.  
  247.     linuxboot_args = args;
  248.  
  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");
  252.  
  253.     /* Note: Initial values in bi override detected values */
  254.     bi = args->bi;
  255.  
  256.     /* machine is Amiga */
  257.     bi.machtype = MACH_AMIGA;
  258.  
  259.     /* determine chipset */
  260.     if (!bi.chipset)
  261.     bi.chipset = get_chipset();
  262.  
  263.     /* determine CPU, FPU and MMU type */
  264.     if (!bi.cputype)
  265.     get_processor(&bi.cputype, &bi.fputype, &bi.mmutype);
  266.  
  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;
  271.  
  272.     /* Memory & AutoConfig based on 'unix_boot.c' by C= */
  273.  
  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);
  286.  
  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;
  294.  
  295.     /* copy the information */
  296.     mh = *mnp;
  297.  
  298.     /* skip virtual memory */
  299.     if (!(mh.mh_Attributes & MEMF_PUBLIC))
  300.         continue;
  301.  
  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");
  313.         }
  314.  
  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");
  321.     }
  322.  
  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);
  326.  
  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;
  346.     }
  347.  
  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;
  355.  
  356.     /* serial port */
  357.     if (!bi.serper) {
  358.     realbaud = baud ? baud : DEFAULT_BAUD;
  359.     bi.serper = (5*bi.eclock+realbaud/2)/realbaud-1;
  360.     }
  361.  
  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 ");
  367.  
  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;
  387.     }
  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;
  402.     }
  403.  
  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;
  418.     }
  419.  
  420.     /* Look for PowerUp PCI bridge. Signal result to kernel in model type.
  421.      * Not pretty, but it'll do for now.
  422.      */
  423.     if (apus_boot) {
  424.         unsigned long vbr;
  425.  
  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.");
  433.         }
  434.     }
  435.  
  436.     Puts("\n\n");
  437.  
  438.     /* display the command line */
  439.     Printf("Command line is '%s'\n", bi.command_line);
  440.  
  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);
  445.  
  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;
  464.             }
  465.         }
  466.         PutChar('\n');
  467.     }
  468.     } else
  469.     Puts("No AutoConfig Devices Found\n");
  470.  
  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;
  482.     }
  483.  
  484.     /* display chip memory size */
  485.     Printf("%ldK of CHIP memory\n", bi.chip_size>>10);
  486.  
  487.     start_mem = bi.memory[0].addr;
  488.     mem_size = bi.memory[0].size;
  489.  
  490.     /* tell us where the kernel will go */
  491.     Printf("\nThe kernel will be located at 0x%08lx\n", start_mem);
  492.  
  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;
  497.     }
  498.  
  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;
  505.     }
  506.  
  507.     /* support for ramdisk */
  508.     if (ramdiskname) {
  509.     int size;
  510.  
  511.     if ((size = FileSize(ramdiskname)) == -1) {
  512.         Printf("Unable to find size of ramdisk file `%s'\n", ramdiskname);
  513.         goto Fail;
  514.     }
  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;
  521.  
  522.     /* create the bootinfo structure */
  523.     if (!create_bootinfo())
  524.     goto Fail;
  525.  
  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;
  530.     }
  531.     if (KRead(kfd, (void *)&kexec, sizeof(kexec)) != sizeof(kexec)) {
  532.     Puts("Unable to read exec header from kernel file\n");
  533.     goto Fail;
  534.     }
  535.  
  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;
  545.     }
  546.     }
  547. #endif
  548.  
  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;
  555.  
  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;
  563.  
  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;
  582.         }
  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;
  590.         }
  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;
  597.         }
  598.         break;
  599.         }
  600.         Printf("Wrong magic number 0x%08lx in kernel header\n",
  601.            N_MAGIC(kexec));
  602.         goto Fail;
  603.     }
  604.  
  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;
  609.     }
  610.  
  611.     /* Align bss size to multiple of four */
  612.     if (!elf_kernel)
  613.     kexec.a_bss = (kexec.a_bss+3) & ~3;
  614.  
  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;
  623.     }
  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;
  635.     }
  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;
  648.     }
  649.  
  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;
  656.         }
  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;
  661.         }
  662.     }
  663.     else {
  664.     if (KSeek(kfd, text_offset) == -1) {
  665.         Puts("Failed to seek to text\n");
  666.         goto Fail;
  667.     }
  668.     if (KRead(kfd, memptr, kexec.a_text) != kexec.a_text) {
  669.         Puts("Failed to read text\n");
  670.         goto Fail;
  671.     }
  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;
  676.     }
  677.     }
  678.     KClose(kfd);
  679.     kfd = -1;
  680.  
  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;
  687.  
  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 */
  696.  
  697.     default:
  698.         goto Fail;
  699.     }
  700.  
  701.     /* copy the bootinfo to the end of the kernel image */
  702.     memcpy((void *)(memptr+kernel_size), bi_ptr, bi_size);
  703.  
  704.     if (ramdiskname) {
  705.     if ((rfd = Open(ramdiskname)) == -1) {
  706.         Printf("Unable to open ramdisk file `%s'\n", ramdiskname);
  707.         goto Fail;
  708.     }
  709.     if (Read(rfd, memptr+kernel_size+bi_size, rd_size) != rd_size) {
  710.         Puts("Failed to read ramdisk file\n");
  711.         goto Fail;
  712.     }
  713.     Close(rfd);
  714.     rfd = -1;
  715.     }
  716.  
  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;
  721.     }
  722.  
  723.     /* allocate chip ram for copy of startup code */
  724.     startcodesize = ©allend-©all;
  725.     if (!(startfunc = (void (*)(void))AllocMem(startcodesize,
  726.                            MEMF_CHIP | MEMF_CLEAR))) {
  727.     Puts("Unable to allocate memory for startcode\n");
  728.     goto Fail;
  729.     }
  730.  
  731.     /* copy startup code to CHIP RAM */
  732.     memcpy(startfunc, ©all, startcodesize);
  733.  
  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);
  738.  
  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);
  754.     }
  755.     Printf("\nKernel entry is 0x%08lx\n", elf_kernel ? kexec_elf.e_entry :
  756.                                kexec.a_entry);
  757.  
  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);
  763.  
  764.     Puts("\nType a key to continue the Linux/m68k boot...");
  765.     GetChar();
  766.     PutChar('\n');
  767.     }
  768.  
  769.     /* wait for things to settle down */
  770.     Sleep(1000000);
  771.  
  772.  
  773.     {
  774.         void* PPCPort;
  775.         void* PPCMsg;
  776.  
  777. #define CHIP_PTR (0xfff00)
  778. #define INFO_SIZE (0x3000 + 0x0100)
  779.     if (apus_boot) {
  780.         /* Let the PowerPC handle the actual kernel start */
  781.     
  782.         /* Store some relevant information about the kernel image
  783.          * and RAM disk at *CHIP_PTR.
  784.          */
  785.         unsigned long boot_msg;
  786.         
  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");
  791.         }
  792.         
  793.         if (!(boot_msg = (unsigned long) AllocMem (0x200, 
  794.                                                    MEMF_REVERSE 
  795.                                                    | MEMF_CHIP 
  796.                                                    | MEMF_CLEAR))){
  797.                                                    
  798.             Puts("Unable to allocate CHIP memory for boot message\n");
  799.             goto Fail;
  800.         }
  801.  
  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;
  807.         }        
  808.  
  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 */
  820.         
  821.         /* Calculate a simple kernel checksum. */
  822.         if (checksum)
  823.         {
  824.             int i = (info[2] + info[3]) / 4;
  825.             unsigned char* k_p = (unsigned char*) info[0];
  826.             unsigned long kcs = 0;
  827.             
  828.             while (i--)
  829.             {
  830.                 unsigned long w = 0;
  831.                 
  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++;
  839.  
  840.                 
  841.                 kcs = kcs ^ i;
  842.                 kcs = kcs ^ w;
  843.             }
  844.             info[7] = kcs;
  845.         }
  846.         
  847.         /* Set LVL7 vector ("expose the top rim of our shorts") */
  848.         {
  849.             unsigned long* vbr;
  850.  
  851.             vbr = (unsigned long*) Supervisor((void*)&getvbr);
  852.             vbr[31] = (unsigned long) &wedgie;
  853.         }
  854.         
  855.         
  856.         {
  857.             void* elfObject;
  858.             void* task;
  859.             struct TagItem MyTags[2];
  860.             struct TagItem tag;
  861.             
  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;
  866.         
  867.             elfObject = (void*) PPCLoadObjectTagList(MyTags);
  868.         
  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);
  874.  
  875.             tag.ti_Tag = PPCTASKINFOTAG_MSGPORT;
  876.             if (PPCPort=(void*) PPCGetTaskAttrs(task, &tag))
  877.             {
  878.                 PPCMsg = PPCCreateMessage(NULL, 0);
  879.             }
  880.  
  881.             
  882.             if (PPCPort == 0 || PPCMsg == 0)
  883.             {
  884.                 Puts ("Didn't get contact with PPC task...\n");
  885.                 goto Fail;
  886.             }
  887.         }
  888.     }
  889.  
  890.     /* turn off caches */
  891.     CacheControl(0, ~0);
  892.     
  893.     if (!keep_video)
  894.     /* set graphics mode to a nice normal one */
  895.     LoadView(NULL);
  896.  
  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]);
  902.  
  903.     if (apus_boot && PPCPort && PPCMsg)
  904.     {
  905.         /* Notify the PPC that we are done ("bend over") */
  906.         PPCSendMessage(PPCPort, PPCMsg,    NULL, 0, 0);
  907.         for (;;) ;
  908.     }
  909.  
  910.     /* Go into supervisor state */
  911.     SuperState();
  912.  
  913.     }
  914.     /* Turn off interrupts. */
  915.     Disable();
  916.  
  917.     /* Turn off all DMA */
  918.     custom.dmacon = DMAF_ALL | DMAF_MASTER;
  919.     
  920.     /* turn off any mmu translation */
  921.     disable_mmu();
  922.  
  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);
  926.  
  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);
  942. }
  943.  
  944.  
  945.     /*
  946.      *    Determine the Chipset
  947.      */
  948.  
  949. static u_long get_chipset(void)
  950. {
  951.     u_char cs;
  952.     u_long chipset;
  953.  
  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);
  967. }
  968.  
  969.  
  970.     /*
  971.      *    Determine the CPU Type
  972.      */
  973.  
  974. static void get_processor(u_long *cpu, u_long *fpu, u_long *mmu)
  975. {
  976.     *cpu = *fpu = 0;
  977.  
  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;
  986.  
  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;
  994.  
  995.     *mmu = *cpu;
  996. }
  997.  
  998.     /*
  999.      *    Determine the Amiga Model
  1000.      */
  1001.  
  1002. static u_long get_model(u_long chipset)
  1003. {
  1004.     u_long model = AMI_UNKNOWN;
  1005.  
  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;
  1019.  
  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;
  1029.  
  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;
  1045.  
  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;
  1060.     }
  1061.     }
  1062.     if (debugflag) {
  1063.     Puts("\nType a key to continue...");
  1064.     GetChar();
  1065.     Puts("\n\n");
  1066.     }
  1067.     return(model);
  1068. }
  1069.  
  1070.     
  1071.     /*
  1072.      *    Probe for a Resident Modules
  1073.      */
  1074.  
  1075. static int probe_resident(const char *name)
  1076. {
  1077.     const struct Resident *res;
  1078.  
  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);
  1088. }
  1089.  
  1090.  
  1091.     /*
  1092.      *    Probe for an available Resource
  1093.      */
  1094.  
  1095. static int probe_resource(const char *name)
  1096. {
  1097.     const void *res;
  1098.  
  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);
  1108. }
  1109.  
  1110.  
  1111.     /*
  1112.      *  Create the Bootinfo structure
  1113.      */
  1114.  
  1115. static int create_bootinfo(void)
  1116. {
  1117.     int i;
  1118.     struct bi_record *record;
  1119.  
  1120.     /* Initialization */
  1121.     bi_size = 0;
  1122.  
  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);
  1140.  
  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);
  1160.  
  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);
  1165.  
  1166.     return(1);
  1167. }
  1168.  
  1169.  
  1170.     /*
  1171.      *  Add a Record to the Bootinfo Structure
  1172.      */
  1173.  
  1174. static int add_bi_record(u_short tag, u_short size, const void *data)
  1175. {
  1176.     struct bi_record *record;
  1177.     u_int size2;
  1178.  
  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);
  1183.     }
  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);
  1190. }
  1191.  
  1192.  
  1193.     /*
  1194.      *  Add a String Record to the Bootinfo Structure
  1195.      */
  1196.  
  1197. static int add_bi_string(u_short tag, const u_char *s)
  1198. {
  1199.     return(add_bi_record(tag, strlen(s)+1, (void *)s));
  1200. }
  1201.  
  1202.  
  1203. #ifdef BOOTINFO_COMPAT_1_0
  1204.  
  1205.     /*
  1206.      *  Create the Bootinfo structure for backwards compatibility mode
  1207.      */
  1208.  
  1209. static int create_compat_bootinfo(void)
  1210. {
  1211.     u_int i;
  1212.  
  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);
  1225.     }
  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);
  1237.     }
  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;
  1243.     }
  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;
  1247.     }
  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;
  1254.     }
  1255.     strncpy(compat_bootinfo.command_line, bi.command_line, COMPAT_CL_SIZE);
  1256.     compat_bootinfo.command_line[COMPAT_CL_SIZE-1] = '\0';
  1257.  
  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;
  1264.     }
  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);
  1274. }
  1275. #endif /* BOOTINFO_COMPAT_1_0 */
  1276.  
  1277.  
  1278.     /*
  1279.      *  Compare the Bootstrap and Kernel Versions
  1280.      */
  1281.  
  1282. static int check_bootinfo_version(const char *memptr)
  1283. {
  1284.     const struct bootversion *bv = (struct bootversion *)memptr;
  1285.     unsigned long version = 0;
  1286.     int i, kernel_major, kernel_minor, boots_major, boots_minor;
  1287.  
  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;
  1293.         }
  1294.     if (!version)
  1295.     Puts("Kernel has no bootinfo version info, assuming 0.0\n");
  1296.  
  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);
  1305.  
  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");
  1312.         }
  1313.         break;
  1314.  
  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 */
  1320.  
  1321.     default:
  1322.         Printf("\nThis bootstrap is too %s for this kernel!\n",
  1323.            boots_major < kernel_major ? "old" : "new");
  1324.         return(0);
  1325.     }
  1326.     return(kernel_major);
  1327. }
  1328.  
  1329.  
  1330.     /*
  1331.      *    Call the copy-and-go-code
  1332.      */
  1333.  
  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)
  1337. {
  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;
  1346.  
  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 (;;);
  1355. }
  1356.  
  1357. asm(".text\n"
  1358. ".align 4\n"
  1359. SYMBOL_NAME_STR(_getvbr) ":
  1360.  movec vbr,d0
  1361.  rte
  1362. ");
  1363.  
  1364.  
  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
  1372. ");
  1373.  
  1374.  
  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
  1384.  
  1385.     leal        0xfffe0000,a1
  1386.     nop
  1387.     movel        a1@,d2
  1388.     nop
  1389.     swap        d2
  1390.     andil        #0xff,d2
  1391.     bne         20f
  1392.  
  1393.     nop
  1394.     clrl        a1@(0x30)
  1395.     nop
  1396.     movel        a1@,d2
  1397.     nop
  1398.     andil        #3,d2
  1399.     bne         20f
  1400.  
  1401.     nop
  1402.     movel        #3,a1@(0x30)
  1403.     nop
  1404.     movel        a1@,d2
  1405.     nop
  1406.     andil        #3,d2
  1407.     cmpw        #3,d2
  1408.     bne         20f
  1409.  
  1410. 10:    movel        d1,a0@(8)
  1411.     moveml         a7@+,d2/a5/a6
  1412.     rts
  1413.  
  1414. 20:    moveq        #0,d0
  1415.     bra         10b
  1416.  
  1417. 99:    addql        #2,a7@(2)
  1418.     moveq        #0,d0
  1419.     rte
  1420. ");
  1421.  
  1422.     /*
  1423.      *    This assembler code is copied to chip ram, and then executed.
  1424.      *    It copies the kernel to it's final resting place.
  1425.      *
  1426.      *    It is called with:
  1427.      *
  1428.      *        a3 = memptr
  1429.      *        a4 = start_mem
  1430.      *        d0 = mem_size
  1431.      *        d1 = rd_size
  1432.      *        d2 = kernel_size
  1433.      *        d3 = bi_size
  1434.      */
  1435.  
  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
  1448. 2:
  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++
  1456.  
  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
  1470. 2:
  1471.                 | /* jump to start of kernel */
  1472.     movel    a4,a0        | jump_to (start_mem);
  1473.     jmp    a0@
  1474. "
  1475. SYMBOL_NAME_STR(_copyallend) ":
  1476. ");
  1477.  
  1478.  
  1479.     /*
  1480.      *    Test for a MapROMmed A3640 Board
  1481.      */
  1482.  
  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
  1530.     rte
  1531. ");
  1532.  
  1533.  
  1534.     /*
  1535.      *    Reset functions for nasty Zorro boards
  1536.      */
  1537.  
  1538. static void reset_rb3(const struct ConfigDev *cd)
  1539. {
  1540.     volatile u_char *rb3_reg = (u_char *)(cd->cd_BoardAddr+0x01002000);
  1541.  
  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). */
  1545.  
  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;
  1552. }
  1553.  
  1554. static void reset_piccolo(const struct ConfigDev *cd)
  1555. {
  1556.     volatile u_char *piccolo_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
  1557.  
  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. */
  1562.  
  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;
  1569. }
  1570.  
  1571. static void reset_sd64(const struct ConfigDev *cd)
  1572. {
  1573.     volatile u_char *sd64_reg = (u_char *)(cd->cd_BoardAddr+0x8000);
  1574.  
  1575.     /* FN: the same stuff as above, for the SD64 board. */
  1576.     /* just as on the Piccolo, this also resets the monitor switch */
  1577.  
  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;
  1584. }
  1585.  
  1586. static void reset_a2065(const struct ConfigDev *cd)
  1587. {
  1588.     volatile u_short *lance_rdp = (u_short *)(cd->cd_BoardAddr+0x4000);
  1589.     volatile u_short *lance_rap = (u_short *)(cd->cd_BoardAddr+0x4002);
  1590.  
  1591.     Disable();
  1592.  
  1593.     /* Stop the card */
  1594.     *lance_rap = 0; /* PCnet-ISA Controller Status (CSR0) */
  1595.     *lance_rdp = 4; /* STOP */
  1596.  
  1597.     Enable();
  1598. }
  1599.     
  1600. static void reset_ariadne(const struct ConfigDev *cd)
  1601. {
  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);
  1605.  
  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);
  1611.  
  1612.     u_short in;
  1613.  
  1614.     Disable();
  1615.  
  1616.     /*
  1617.      *    Reset the Ethernet part (Am79C960 PCnet-ISA)
  1618.      */
  1619.  
  1620.     in = *lance_reset;   /* Reset Chip on Read Access */
  1621.     *lance_rap = 0x0000; /* PCnet-ISA Controller Status (CSR0) */
  1622.     *lance_rdp = 0x0400; /* STOP */
  1623.  
  1624.     /*
  1625.      *    Reset the Parallel part (MC68230 PI/T)
  1626.      */
  1627.  
  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 */
  1633.  
  1634.     Enable();
  1635. }
  1636.  
  1637. static void reset_hydra(const struct ConfigDev *cd)
  1638. {
  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;
  1642.  
  1643.     Disable();
  1644.  
  1645.     *nic_cr = 0x21;    /* nic command register: software reset etc. */
  1646.     while (((*nic_isr & 0x80) == 0) && --n)  /* wait for reset to complete */
  1647.     ;
  1648.  
  1649.     Enable();
  1650. }
  1651.  
  1652. #if 0
  1653. static void reset_a2060(const struct ConfigDev *cd)
  1654. {
  1655. #error reset_a2060: not yet implemented
  1656. }
  1657. #endif
  1658.  
  1659.  
  1660. #ifdef ZKERNEL
  1661.  
  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)
  1666.  
  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;
  1672.  
  1673. static int Zinfd = 0;         /* fd of compressed file */
  1674.  
  1675. /*
  1676.  * gzip declarations
  1677.  */
  1678.  
  1679. #define OF(args)  args
  1680.  
  1681. #define memzero(s, n)     memset ((s), 0, (n))
  1682.  
  1683. typedef unsigned char  uch;
  1684. typedef unsigned short ush;
  1685. typedef unsigned long  ulg;
  1686.  
  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 */
  1690.  
  1691. static uch *inbuf;
  1692. static uch *window;
  1693.  
  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;
  1699.  
  1700. #define get_byte()  (inptr < insize ? inbuf[inptr++] : fill_inbuf())
  1701.         
  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)
  1709.  
  1710. #define STATIC static
  1711.  
  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 **);
  1717.  
  1718. #define malloc(x)    AllocVec(x, MEMF_FAST | MEMF_PUBLIC)
  1719. #define free(x)        FreeVec(x)
  1720.  
  1721. #ifdef LILO
  1722. #include "inflate.c"
  1723. #else
  1724. #include "../../../../lib/inflate.c"
  1725. #endif
  1726.  
  1727. static void gzip_mark(void **ptr)
  1728. {
  1729. }
  1730.  
  1731. static void gzip_release(void **ptr)
  1732. {
  1733. }
  1734.  
  1735.  
  1736. /*
  1737.  * Fill the input buffer. This is called only when the buffer is empty
  1738.  * and at least one byte is really needed.
  1739.  */
  1740. static int fill_inbuf(void)
  1741. {
  1742.     if (exit_code)
  1743.     return -1;
  1744.  
  1745.     insize = Read(Zinfd, inbuf, INBUFSIZ);
  1746.     if (insize <= 0)
  1747.     return -1;
  1748.  
  1749.     inptr = 1;
  1750.     return(inbuf[0]);
  1751. }
  1752.  
  1753. /*
  1754.  * Write the output window window[0..outcnt-1] and update crc and bytes_out.
  1755.  * (Used for the decompressed data only.)
  1756.  */
  1757. static void flush_window(void)
  1758. {
  1759.     ulg c = crc;         /* temporary variable */
  1760.     unsigned n;
  1761.     uch *in, ch;
  1762.     int chunk = Zwpos >> ZFILE_CHUNK_BITS;
  1763.  
  1764.     if (exit_code)
  1765.     return;
  1766.  
  1767.     if (chunk >= ZFILE_N_CHUNKS) {
  1768.     error("Compressed image too large! Aborting.\n");
  1769.     return;
  1770.     }
  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;
  1776.     }
  1777.     }
  1778.     memcpy(ZFile[chunk] + (Zwpos & ZFILE_CHUNK_MASK), window, outcnt);
  1779.     Zwpos += outcnt;
  1780.     
  1781. #define    DISPLAY_BITS 10
  1782.     if ((Zwpos & ((1 << DISPLAY_BITS)-1)) == 0)
  1783.     PutChar('.');
  1784.     
  1785.     in = window;
  1786.     for (n = 0; n < outcnt; n++) {
  1787.     ch = *in++;
  1788.     c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
  1789.     }
  1790.     crc = c;
  1791.     bytes_out += (ulg)outcnt;
  1792.     outcnt = 0;
  1793. }
  1794.  
  1795. static void error(char *x)
  1796. {
  1797.     Printf("\n%s", x);
  1798.     exit_code = 1;
  1799. }
  1800.  
  1801. static inline int call_sub(int (*func)(void), void *stackp)
  1802. {
  1803.     register int _res __asm("d0");
  1804.     register int (*a0)(void) __asm("a0") = func;
  1805.     register int (*a1)(void) __asm("a1") = stackp;
  1806.  
  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);
  1815. }
  1816.  
  1817. static int load_zkernel(int fd)
  1818. {
  1819.     int i, err = -1;
  1820. #define ZSTACKSIZE    (16384)
  1821.     u_long *zstack;
  1822.     
  1823.     for (i = 0; i < ZFILE_N_CHUNKS; ++i)
  1824.     ZFile[i] = NULL;
  1825.     Zinfd = fd;
  1826.     Seek(fd, 0);
  1827.     
  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);
  1844.         }
  1845.         FreeMem(window, WSIZE);
  1846.         window = NULL;
  1847.     }
  1848.     FreeMem(inbuf, INBUFSIZ);
  1849.     inbuf = NULL;
  1850.     }
  1851.     Close(Zinfd);    /* input file not needed anymore */
  1852.     return(err);
  1853. }
  1854.  
  1855.  
  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)
  1862.  */
  1863.  
  1864. static int KRead(int fd, void *buf, int cnt)
  1865. {
  1866.     unsigned done = 0;
  1867.     
  1868.     if (!ZFileSize)
  1869.     return(Read(fd, buf, cnt));
  1870.     
  1871.     if (ZFpos + cnt > ZFileSize)
  1872.     cnt = ZFileSize - ZFpos;
  1873.     
  1874.     while (cnt > 0) {
  1875.     unsigned chunk = ZFpos >> ZFILE_CHUNK_BITS;
  1876.     unsigned endchunk = (chunk+1) << ZFILE_CHUNK_BITS;
  1877.     unsigned n = cnt;
  1878.  
  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;
  1886.  
  1887.     if (ZFpos == endchunk) {
  1888.         FreeMem(ZFile[chunk], ZFILE_CHUNK_SIZE);
  1889.         ZFile[chunk] = NULL;
  1890.     }
  1891.     }
  1892.  
  1893.     return(done);
  1894. }
  1895.  
  1896.  
  1897. static int KSeek(int fd, int offset)
  1898. {
  1899.     unsigned oldpos, oldchunk, newchunk;
  1900.  
  1901.     if (!ZFileSize)
  1902.     return(Seek(fd, offset));
  1903.  
  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);
  1912.     }
  1913.  
  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;
  1921.     }
  1922.     ++oldchunk;
  1923.     }
  1924.     return(ZFpos);
  1925. }
  1926.  
  1927.  
  1928. static void free_zfile(void)
  1929. {
  1930.     int i;
  1931.  
  1932.     for (i = 0; i < ZFILE_N_CHUNKS; ++i)
  1933.     if (ZFile[i]) {
  1934.         FreeMem(ZFile[i], ZFILE_CHUNK_SIZE);
  1935.         ZFile[i] = NULL;
  1936.     }
  1937. }
  1938.  
  1939. static int KClose(int fd)
  1940. {
  1941.     if (ZFileSize) {
  1942.     free_zfile();
  1943.     ZFileSize = 0;
  1944.     } else
  1945.     Close(fd);
  1946.     return(0);
  1947. }
  1948. #endif /* ZKERNEL */
  1949.