2 * linux/arch/m68k/boot/amiga/linuxboot.h -- Generic routine to boot Linux/m68k
3 * on Amiga, used by both Amiboot and
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
14 * with work by Michael Rausch
20 * This file is subject to the terms and conditions of the GNU General Public
21 * License. See the file COPYING in the main directory of this archive
26 #include <asm/setup.h>
27 #include <linux/zorro.h>
34 #define AMIBOOT_VERSION "5.5"
38 * Amiga Bootinfo Definitions
40 * All limits herein are `soft' limits, i.e. they don't put constraints
41 * on the actual parameters in the kernel.
44 struct amiga_bootinfo
{
45 u_long machtype
; /* machine type = MACH_AMIGA */
46 u_long cputype
; /* system CPU */
47 u_long fputype
; /* system FPU */
48 u_long mmutype
; /* system MMU */
49 int num_memory
; /* # of memory blocks found */
50 struct mem_info memory
[NUM_MEMINFO
];/* memory description */
51 struct mem_info ramdisk
; /* ramdisk description */
52 char command_line
[CL_SIZE
]; /* kernel command line parameters */
53 u_long model
; /* Amiga Model */
54 int num_autocon
; /* # of autoconfig devices found */
55 struct ConfigDev autocon
[ZORRO_NUM_AUTO
]; /* autoconfig devices */
56 u_long chip_size
; /* size of chip memory (bytes) */
57 u_char vblank
; /* VBLANK frequency */
58 u_char psfreq
; /* power supply frequency */
60 u_long eclock
; /* EClock frequency */
61 u_long chipset
; /* native chipset present */
62 u_short serper
; /* serial port period */
67 * Parameters passed to linuxboot()
70 struct linuxboot_args
{
71 struct amiga_bootinfo bi
; /* Initial values override detected values */
72 const char *kernelname
;
73 const char *ramdiskname
;
78 void (*puts
)(const char *str
);
79 long (*getchar
)(void);
80 void (*putchar
)(char c
);
81 void (*printf
)(const char *fmt
, ...);
82 int (*open
)(const char *path
);
83 int (*seek
)(int fd
, int offset
);
84 int (*read
)(int fd
, char *buf
, int count
);
85 void (*close
)(int fd
);
86 int (*filesize
)(const char *path
);
87 void (*sleep
)(u_long micros
);
94 * Boot the Linux/m68k Operating System
97 extern u_long
linuxboot(const struct linuxboot_args
*args
);
104 extern const char *amiga_models
[];
105 extern const u_long first_amiga_model
;
106 extern const u_long last_amiga_model
;
110 * Exec Library Definitions
118 struct Node
*lh_Head
;
119 struct Node
*lh_Tail
;
120 struct Node
*lh_TailPred
;
126 struct MemChunk
*mc_Next
; /* pointer to next chunk */
127 u_long mc_Bytes
; /* chunk byte size */
130 #define MEMF_PUBLIC (1<<0)
131 #define MEMF_CHIP (1<<1)
132 #define MEMF_FAST (1<<2)
133 #define MEMF_LOCAL (1<<8)
134 #define MEMF_CLEAR (1<<16)
135 #define MEMF_REVERSE (1<<18)
139 u_short mh_Attributes
; /* characteristics of this region */
140 struct MemChunk
*mh_First
; /* first free region */
141 void *mh_Lower
; /* lower memory bound */
142 void *mh_Upper
; /* upper memory bound+1 */
143 u_long mh_Free
; /* total number of free bytes */
154 u_char VBlankFrequency
;
155 u_char PowerSupplyFrequency
;
157 u_long ex_EClockFrequency
;
161 #define AFB_68020 (1)
162 #define AFF_68020 (1<<AFB_68020)
163 #define AFB_68030 (2)
164 #define AFF_68030 (1<<AFB_68030)
165 #define AFB_68040 (3)
166 #define AFF_68040 (1<<AFB_68040)
167 #define AFB_68881 (4)
168 #define AFF_68881 (1<<AFB_68881)
169 #define AFB_68882 (5)
170 #define AFF_68882 (1<<AFB_68882)
171 #define AFB_FPU40 (6) /* ONLY valid if AFB_68040 or AFB_68060 */
172 #define AFF_FPU40 (1<<AFB_FPU40) /* is set; also set for 68060 FPU */
173 #define AFB_68060 (7)
174 #define AFF_68060 (1<<AFB_68060)
180 * Graphics Library Definitions
187 u_short NormalDisplayRows
;
188 u_short NormalDisplayColumns
;
194 #define GFXB_HR_AGNUS (0)
195 #define GFXF_HR_AGNUS (1<<GFXB_HR_AGNUS)
196 #define GFXB_HR_DENISE (1)
197 #define GFXF_HR_DENISE (1<<GFXB_HR_DENISE)
198 #define GFXB_AA_ALICE (2)
199 #define GFXF_AA_ALICE (1<<GFXB_AA_ALICE)
200 #define GFXB_AA_LISA (3)
201 #define GFXF_AA_LISA (1<<GFXB_AA_LISA)
204 * HiRes(=Big) Agnus present; i.e.
205 * 1MB chipmem, big blits (none of interest so far) and programmable sync
207 #define GFXG_OCS (GFXF_HR_AGNUS)
209 * HiRes Agnus/Denise present; we are running on ECS
211 #define GFXG_ECS (GFXF_HR_AGNUS|GFXF_HR_DENISE)
213 * Alice and Lisa present; we are running on AGA
215 #define GFXG_AGA (GFXF_AA_ALICE|GFXF_AA_LISA)
217 #define SETCHIPREV_BEST (0xffffffff)
218 #define HIRES (0x8000)
224 * Amiga Shared Library/Device Functions
227 extern const struct ExecBase
*SysBase
;
229 #define LVOAllocMem (-0xc6)
230 #define LVOAllocVec (-0x2ac)
231 #define LVOCacheControl (-0x288)
232 #define LVODisable (-0x78)
233 #define LVOEnable (-0x7e)
234 #define LVOFindResident (-0x60)
235 #define LVOFreeMem (-0xd2)
236 #define LVOFreeVec (-0x2b2)
237 #define LVOOpenresource (-0x1f2)
238 #define LVOSuperState (-0x96)
239 #define LVOSupervisor (-0x1e)
241 static __inline
void *AllocMem(u_long byteSize
, u_long requirements
)
243 register void *_res
__asm("d0");
244 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
245 register u_long d0
__asm("d0") = byteSize
;
246 register u_long d1
__asm("d1") = requirements
;
248 __asm
__volatile ("jsr a6@(-0xc6)"
250 : "r" (_base
), "r" (d0
), "r" (d1
)
251 : "a0", "a1", "d0", "d1", "memory");
255 static __inline
void *AllocVec(u_long byteSize
, u_long requirements
)
257 register void *_res
__asm("d0");
258 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
259 register u_long d0
__asm("d0") = byteSize
;
260 register u_long d1
__asm("d1") = requirements
;
262 __asm
__volatile ("jsr a6@(-0x2ac)"
264 : "r" (_base
), "r" (d0
), "r" (d1
)
265 : "a0", "a1", "d0", "d1", "memory");
269 static __inline u_long
CacheControl(u_long cacheBits
, u_long cacheMask
)
271 register u_long _res
__asm("d0");
272 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
273 register u_long d0
__asm("d0") = cacheBits
;
274 register u_long d1
__asm("d1") = cacheMask
;
276 __asm
__volatile ("jsr a6@(-0x288)"
278 : "r" (_base
), "r" (d0
), "r" (d1
)
279 : "a0", "a1", "d0", "d1", "memory");
283 static __inline
void Disable(void)
285 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
287 __asm
__volatile ("jsr a6@(-0x78)"
290 : "a0", "a1", "d0", "d1", "memory");
293 static __inline
void Enable(void)
295 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
297 __asm
__volatile ("jsr a6@(-0x7e)"
300 : "a0", "a1", "d0", "d1", "memory");
303 static __inline
struct Resident
*FindResident(const u_char
*name
)
305 register struct Resident
*_res
__asm("d0");
306 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
307 register const u_char
*a1
__asm("a1") = name
;
309 __asm
__volatile ("jsr a6@(-0x60)"
311 : "r" (_base
), "r" (a1
)
312 : "a0", "a1", "d0", "d1", "memory");
316 static __inline
void FreeMem(void *memoryBlock
, u_long byteSize
)
318 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
319 register void *a1
__asm("a1") = memoryBlock
;
320 register u_long d0
__asm("d0") = byteSize
;
322 __asm
__volatile ("jsr a6@(-0xd2)"
324 : "r" (_base
), "r" (a1
), "r" (d0
)
325 : "a0", "a1", "d0", "d1", "memory");
328 static __inline
void FreeVec(void *memoryBlock
)
330 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
331 register void *a1
__asm("a1") = memoryBlock
;
333 __asm
__volatile ("jsr a6@(-0x2b2)"
335 : "r" (_base
), "r" (a1
)
336 : "a0", "a1", "d0", "d1", "memory");
339 static __inline
void *OpenResource(const u_char
*resName
)
341 register void *_res
__asm("d0");
342 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
343 register const u_char
*a1
__asm("a1") = resName
;
345 __asm
__volatile ("jsr a6@(-0x1f2)"
347 : "r" (_base
), "r" (a1
)
348 : "a0", "a1", "d0", "d1", "memory");
352 static __inline
void *SuperState(void)
354 register void *_res
__asm("d0");
355 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
357 __asm
__volatile ("jsr a6@(-0x96)"
360 : "a0", "a1", "d0", "d1", "memory");
364 static __inline u_long
Supervisor(u_long (*userfunc
)(void))
366 register u_long _res
__asm("d0");
367 register const struct ExecBase
*_base
__asm("a6") = SysBase
;
368 register u_long (*d7
)() __asm("d7") = userfunc
;
370 __asm
__volatile ("exg d7,a5;"
374 : "r" (_base
), "r" (d7
)
375 : "a0", "a1", "d0", "d1", "memory");
380 extern const struct ExpansionBase
*ExpansionBase
;
382 #define LVOFindConfigDev (-0x48)
384 static __inline
struct ConfigDev
*FindConfigDev(struct ConfigDev
*oldConfigDev
,
385 long manufacturer
, long product
)
387 register struct ConfigDev
*_res
__asm("d0");
388 register const struct ExpansionBase
*_base
__asm("a6") = ExpansionBase
;
389 register struct ConfigDev
*a0
__asm("a0") = oldConfigDev
;
390 register long d0
__asm("d0") = manufacturer
;
391 register long d1
__asm("d1") = product
;
393 __asm
__volatile ("jsr a6@(-0x48)"
395 : "r" (_base
), "r" (a0
), "r" (d0
), "r" (d1
)
396 : "a0", "a1", "d0", "d1", "memory");
401 extern const struct GfxBase
*GfxBase
;
403 #define LVOLoadView (-0xde)
404 #define LVOSetChipRev (-0x378)
406 static __inline
void LoadView(struct View
*view
)
408 register const struct GfxBase
*_base
__asm("a6") = GfxBase
;
409 register struct View
*a1
__asm("a1") = view
;
411 __asm
__volatile ("jsr a6@(-0xde)"
413 : "r" (_base
), "r" (a1
)
414 : "a0", "a1", "d0", "d1", "memory");
417 static __inline u_long
SetChipRev(u_long want
)
419 register u_long _res
__asm("d0");
420 register const struct GfxBase
*_base
__asm("a6") = GfxBase
;
421 register u_long d0
__asm("d0") = want
;
423 __asm
__volatile ("jsr a6@(-0x378)"
425 : "r" (_base
), "r" (d0
)
426 : "a0", "a1", "d0", "d1", "memory");
441 extern struct PPCLibBase
*PPCLibBasePTR
;
443 static __inline
void* PPCRunObject(void* object
, void* args
)
445 register void *_res
__asm("d0");
446 register const struct PPCLibBase
*_base
__asm("a6") = PPCLibBasePTR
;
447 register void *a0
__asm("a0") = object
;
448 register void *a1
__asm("a1") = args
;
450 __asm
__volatile ("jsr a6@(-0x2a)"
452 : "r" (_base
), "r" (a0
), "r" (a1
)
453 : "a0", "a1", "d0", "d1", "memory");
457 static __inline
void* PPCCreateTask(void* object
, void* tags
)
459 register void *_res
__asm("d0");
460 register const struct PPCLibBase
*_base
__asm("a6") = PPCLibBasePTR
;
461 register void *a0
__asm("a0") = object
;
462 register void *a1
__asm("a1") = tags
;
464 __asm
__volatile ("jsr a6@(-0x54)"
466 : "r" (_base
), "r" (a0
), "r" (a1
)
467 : "a0", "a1", "d0", "d1", "memory");
471 static __inline
void PPCUnloadObject(void* object
)
473 register const struct PPCLibBase
*_base
__asm("a6") = PPCLibBasePTR
;
474 register const u_char
*a0
__asm("a0") = object
;
476 __asm
__volatile ("jsr a6@(-0x24)"
478 : "r" (_base
), "r" (a0
)
479 : "a0", "a1", "d0", "d1", "memory");
482 #include <utility/tagitem.h>
484 static __inline
void* PPCLoadObjectTagList(struct TagItem
*Tags
)
487 register void *_res
__asm("d0");
488 register const struct PPCLibBase
*_base
__asm("a6") = PPCLibBasePTR
;
489 register struct TagItem
*a0
__asm("a0") = Tags
;
490 __asm
volatile ("jsr a6@(-0x198:W)"
492 : "r" (_base
), "r" (a0
)
493 : "d0", "d1", "a0", "a1", "fp0", "fp1", "cc", "memory");
497 static __inline
void* PPCGetTaskAttrs(void* task
, struct TagItem
* attr
)
499 register const struct PPCLibBase
*_base
__asm("a6") = PPCLibBasePTR
;
500 register void *a0
__asm("a0") = task
;
501 register void *a1
__asm("a1") = attr
;
503 __asm
__volatile ("jsr a6@(-0x84)\n\t"
506 : "r" (_base
), "r" (a0
), "r" (a1
)
507 : "a0", "a1", "d0", "d1", "memory");
512 static __inline
void* PPCCreateMessage(void* body
, int len
)
514 register const struct PPCLibBase
*_base
__asm("a6") = PPCLibBasePTR
;
515 register void *a0
__asm("a0") = body
;
516 register int d0
__asm("d0") = len
;
518 __asm
__volatile ("jsr a6@(-0x126)\n\t"
521 : "r" (_base
), "r" (d0
), "r" (a0
)
522 : "a0", "a1", "d0", "d1", "memory");
527 static __inline
int PPCSendMessage(void* port
, void* msg
, void* data
,
530 register const struct PPCLibBase
*_base
__asm("a6") = PPCLibBasePTR
;
531 register void *a0
__asm("a0") = port
;
532 register void *a1
__asm("a1") = msg
;
533 register void *a2
__asm("a2") = data
;
534 register int d0
__asm("d0") = len
;
535 register int d1
__asm("d1") = id
;
537 __asm
__volatile ("jsr a6@(-0x14a)\n\t"
539 : "r" (_base
), "r" (d0
), "r" (d1
), "r" (a0
), "r" (a1
), "r" (a2
)
540 : "a0", "a1", "d0", "d1", "memory");
546 * Bootstrap Support Functions
549 static __inline
void disable_mmu(void)
551 if (SysBase
->AttnFlags
& AFF_68040
)
552 __asm
__volatile ("moveq #0,d0;"
553 ".long 0x4e7b0003;" /* movec d0,tc */
554 ".long 0x4e7b0004;" /* movec d0,itt0 */
555 ".long 0x4e7b0005;" /* movec d0,itt1 */
556 ".long 0x4e7b0006;" /* movec d0,dtt0 */
557 ".long 0x4e7b0007" /* movec d0,dtt1 */
562 __asm
__volatile ("subl #4,sp;"
567 if (SysBase
->AttnFlags
& AFF_68030
)
568 __asm
__volatile ("clrl sp@-;"
569 ".long 0xf0170800;" /* pmove sp@,tt0 */
570 ".long 0xf0170c00;" /* pmove sp@,tt1 */