revert between 56095 -> 55830 in arch
[AROS.git] / arch / .unmaintained / ppc-native / boot / bootstrap.c
blobc8ab89c8eb02aaa2b4f13846b400c3da999949fc
1 /*
2 ** linux/arch/m68k/boot/amiga/bootstrap.c -- This program loads the Linux/m68k
3 ** kernel into an Amiga and launches
4 ** it.
5 **
6 ** Copyright 1993,1994 by Hamish Macdonald, Greg Harp
7 **
8 ** Modified 11-May-94 by Geert Uytterhoeven
9 ** (Geert.Uytterhoeven@cs.kuleuven.ac.be)
10 ** - A3640 MapROM check
11 ** Modified 31-May-94 by Geert Uytterhoeven
12 ** - Memory thrash problem solved
13 ** Modified 07-March-95 by Geert Uytterhoeven
14 ** - Memory block sizes are rounded to a multiple of 256K instead of 1M
15 ** This _requires_ >0.9pl5 to work!
16 ** (unless all block sizes are multiples of 1M :-)
17 ** Modified 11-July-95 by Andreas Schwab
18 ** - Support for ELF kernel (untested!)
19 ** Modified 10-Jan-96 by Geert Uytterhoeven
20 ** - The real Linux/m68k boot code moved to linuxboot.[ch]
21 ** Modified 9-Sep-96 by Geert Uytterhoeven
22 ** - Rewritten option parsing
23 ** - New parameter passing to linuxboot() (linuxboot_args)
24 ** Modified 6-Oct-96 by Geert Uytterhoeven
25 ** - Updated for the new boot information structure
26 ** Modified 26-Feb-98 by Jesper Skov
27 ** - Added support for booting APUS systems.
29 ** This file is subject to the terms and conditions of the GNU General Public
30 ** License. See the file COPYING in the main directory of this archive
31 ** for more details.
35 #include <stddef.h>
36 #include <stdlib.h>
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <string.h>
40 #include <sys/file.h>
41 #include <sys/types.h>
42 #include <unistd.h>
44 /* required Linux/m68k include files */
45 #include <linux/a.out.h>
46 #include <linux/elf.h>
47 #include <asm/amigahw.h>
48 #include <asm/page.h>
50 /* Amiga bootstrap include files */
51 #include "linuxboot.h"
52 #include "bootstrap.h"
55 /* Library Bases */
56 long __oslibversion = 36;
57 extern const struct ExecBase *SysBase;
59 static const char *memfile_name = NULL;
61 static int model = AMI_UNKNOWN;
63 static const char *ProgramName;
65 struct linuxboot_args args;
69 * Function Prototypes
72 static void Usage(void) __attribute__ ((noreturn));
73 int main(int argc, char *argv[]);
74 static void Puts(const char *str);
75 static long GetChar(void);
76 static void PutChar(char c);
77 static void Printf(const char *fmt, ...);
78 static int Open(const char *path);
79 static int Seek(int fd, int offset);
80 static int Read(int fd, char *buf, int count);
81 static void Close(int fd);
82 static int FileSize(const char *path);
83 static void Sleep(u_long micros);
86 static void Usage(void)
88 fprintf(stderr,
89 "Linux/m68k Amiga Bootstrap version " AMIBOOT_VERSION "\n\n"
90 "Usage: %s [options] [kernel command line]\n\n"
91 "Basic options:\n"
92 " -h, --help Display this usage information\n"
93 " -k, --kernel file Use kernel image `file' (default is `vmlinux')\n"
94 " -r, --ramdisk file Use ramdisk image `file'\n"
95 "Advanced options:\n"
96 " -d, --debug Enable debug mode\n"
97 " -b, --baud speed Set the serial port speed (default is 9600)\n"
98 " -m, --memfile file Use memory file `file'\n"
99 " -v, --keep-video Don't reset the video mode\n"
100 " -t, --model id Set the Amiga model to `id'\n"
101 " -p, --processor cfm Set the processor type to `cfm\n",
102 " --apus PPC boot on PowerUp\n",
103 " --checksum Make checksum of kernel image.\n\n",
104 ProgramName);
105 exit(EXIT_FAILURE);
108 struct PPCLibBase *PPCLibBasePTR = NULL;
110 int main(int argc, char *argv[])
112 int i;
113 int processor = 0, debugflag = 0, keep_video = 0;
114 int apus_boot = 0, checksum = 0;
115 u_int baud = 0;
116 const char *kernel_name = NULL;
117 const char *ramdisk_name = NULL;
118 char commandline[CL_SIZE] = "";
120 ProgramName = argv[0];
121 while (--argc) {
122 argv++;
123 if (!strcmp(argv[0], "-h") || !strcmp(argv[0], "--help"))
124 Usage();
125 else if (!strcmp(argv[0], "-k") || !strcmp(argv[0], "--kernel"))
126 if (--argc && !kernel_name) {
127 kernel_name = argv[1];
128 argv++;
129 } else
130 Usage();
131 else if (!strcmp(argv[0], "-r") || !strcmp(argv[0], "--ramdisk"))
132 if (--argc && !ramdisk_name) {
133 ramdisk_name = argv[1];
134 argv++;
135 } else
136 Usage();
137 else if (!strcmp(argv[0], "-d") || !strcmp(argv[0], "--debug"))
138 debugflag = 1;
139 else if (!strcmp(argv[0], "-b") || !strcmp(argv[0], "--baud"))
140 if (--argc && !baud) {
141 baud = atoi(argv[1]);
142 argv++;
143 } else
144 Usage();
145 else if (!strcmp(argv[0], "-m") || !strcmp(argv[0], "--memfile"))
146 if (--argc && !memfile_name) {
147 memfile_name = argv[1];
148 argv++;
149 } else
150 Usage();
151 else if (!strcmp(argv[0], "-v") || !strcmp(argv[0], "--keep-video"))
152 keep_video = 1;
153 else if (!strcmp(argv[0], "-t") || !strcmp(argv[0], "--model"))
154 if (--argc && !model) {
155 model = atoi(argv[1]);
156 argv++;
157 } else
158 Usage();
159 else if (!strcmp(argv[0], "-p") || !strcmp(argv[0], "--processor"))
160 if (--argc && !processor) {
161 processor = atoi(argv[1]);
162 argv++;
163 } else
164 Usage();
165 else if (!strcmp(argv[0], "--apus"))
166 apus_boot = 1;
167 else if (!strcmp(argv[0], "--checksum"))
168 checksum = 1;
169 else
170 break;
172 if (!kernel_name)
173 kernel_name = "vmlinux";
175 SysBase = *(struct ExecBase **)4;
177 if (apus_boot) {
178 if (!(PPCLibBasePTR = (struct PPCLibBase *)
179 OpenLibrary("ppc.library", 45))){
180 fprintf(stderr, "Cannot open ppc.library version45+\n");
181 return (FALSE);
186 * Join command line options
188 i = 0;
189 while (argc--) {
190 if ((i+strlen(*argv)+1) < CL_SIZE) {
191 i += strlen(*argv) + 1;
192 if (commandline[0])
193 strcat(commandline, " ");
194 strcat(commandline, *argv++);
198 memset(&args.bi, 0, sizeof(args.bi));
199 if (processor) {
200 int cpu = processor/100%10;
201 int fpu = processor/10%10;
202 int mmu = processor%10;
203 if (cpu)
204 args.bi.cputype = 1<<(cpu-1);
205 if (fpu)
206 args.bi.fputype = 1<<(fpu-1);
207 if (mmu)
208 args.bi.mmutype = 1<<(mmu-1);
211 * If we have a memory file, read the memory information from it
213 if (memfile_name) {
214 FILE *fp;
215 int i;
217 if ((fp = fopen(memfile_name, "r")) == NULL) {
218 perror("open memory file");
219 fprintf(stderr, "Cannot open memory file %s\n", memfile_name);
220 return(FALSE);
223 if (fscanf(fp, "%lu", &args.bi.chip_size) != 1) {
224 fprintf(stderr, "memory file does not contain chip memory size\n");
225 fclose(fp);
226 return(FALSE);
229 for (i = 0; i < NUM_MEMINFO; i++)
230 if (fscanf(fp, "%lx %lu", &args.bi.memory[i].addr,
231 &args.bi.memory[i].size) != 2)
232 break;
234 fclose(fp);
235 args.bi.num_memory = i;
237 strncpy(args.bi.command_line, commandline, CL_SIZE);
238 args.bi.command_line[CL_SIZE-1] = '\0';
239 if (model != AMI_UNKNOWN)
240 args.bi.model = model;
242 args.apus_boot = apus_boot;
243 args.checksum = checksum;
245 args.kernelname = kernel_name;
246 args.ramdiskname = ramdisk_name;
247 args.debugflag = debugflag;
248 args.keep_video = keep_video;
249 args.reset_boards = 1;
250 args.baud = baud;
251 args.puts = Puts;
252 args.getchar = GetChar;
253 args.putchar = PutChar;
254 args.printf = Printf;
255 args.open = Open;
256 args.seek = Seek;
257 args.read = Read;
258 args.close = Close;
259 args.filesize = FileSize;
260 args.sleep = Sleep;
262 /* Do The Right Stuff */
263 linuxboot(&args);
265 /* if we ever get here, something went wrong */
266 exit(EXIT_FAILURE);
271 * Routines needed by linuxboot
274 static void Puts(const char *str)
276 fputs(str, stderr);
277 fflush(stderr);
280 static long GetChar(void)
282 return(getchar());
285 static void PutChar(char c)
287 fputc(c, stderr);
288 fflush(stderr);
291 static void Printf(const char *fmt, ...)
293 va_list args;
295 va_start(args, fmt);
296 vfprintf(stderr, fmt, args);
297 va_end(args);
298 fflush(stderr);
301 static int Open(const char *path)
303 return(open(path, O_RDONLY));
306 static int Seek(int fd, int offset)
308 return(lseek(fd, offset, SEEK_SET));
312 static int Read(int fd, char *buf, int count)
314 return(read(fd, buf, count));
317 static void Close(int fd)
319 close(fd);
322 static int FileSize(const char *path)
324 int fd, size = -1;
326 if ((fd = open(path, O_RDONLY)) != -1) {
327 size = lseek(fd, 0, SEEK_END);
328 close(fd);
330 return(size);
333 static void Sleep(u_long micros)
335 struct MsgPort *TimerPort;
336 struct timerequest *TimerRequest;
338 if ((TimerPort = CreateMsgPort())) {
339 if ((TimerRequest = CreateIORequest(TimerPort,
340 sizeof(struct timerequest)))) {
341 if (!OpenDevice("timer.device", UNIT_VBLANK,
342 (struct IORequest *)TimerRequest, 0)) {
343 TimerRequest->io_Command = TR_ADDREQUEST;
344 TimerRequest->io_Flags = IOF_QUICK;
345 TimerRequest->tv_secs = micros/1000000;
346 TimerRequest->tv_micro = micros%1000000;
347 DoIO((struct IORequest *)TimerRequest);
348 CloseDevice((struct IORequest *)TimerRequest);
350 DeleteIORequest(TimerRequest);
352 DeleteMsgPort(TimerPort);