]> git.karo-electronics.de Git - karo-tx-linux.git/blob - arch/m68k/kernel/head.S
m68k: Remove CONSOLE_PENGUIN macro, adopt CONFIG_LOGO
[karo-tx-linux.git] / arch / m68k / kernel / head.S
1 /* -*- mode: asm -*-
2 **
3 ** head.S -- This file contains the initial boot code for the
4 **           Linux/68k kernel.
5 **
6 ** Copyright 1993 by Hamish Macdonald
7 **
8 ** 68040 fixes by Michael Rausch
9 ** 68060 fixes by Roman Hodek
10 ** MMU cleanup by Randy Thelen
11 ** Final MMU cleanup by Roman Zippel
12 **
13 ** Atari support by Andreas Schwab, using ideas of Robert de Vries
14 ** and Bjoern Brauel
15 ** VME Support by Richard Hirst
16 **
17 ** 94/11/14 Andreas Schwab: put kernel at PAGESIZE
18 ** 94/11/18 Andreas Schwab: remove identity mapping of STRAM for Atari
19 ** ++ Bjoern & Roman: ATARI-68040 support for the Medusa
20 ** 95/11/18 Richard Hirst: Added MVME166 support
21 ** 96/04/26 Guenther Kelleter: fixed identity mapping for Falcon with
22 **                            Magnum- and FX-alternate ram
23 ** 98/04/25 Phil Blundell: added HP300 support
24 ** 1998/08/30 David Kilzer: Added support for font_desc structures
25 **            for linux-2.1.115
26 ** 1999/02/11  Richard Zidlicky: added Q40 support (initial version 99/01/01)
27 ** 2004/05/13 Kars de Jong: Finalised HP300 support
28 **
29 ** This file is subject to the terms and conditions of the GNU General Public
30 ** License. See the file README.legal in the main directory of this archive
31 ** for more details.
32 **
33 */
34
35 /*
36  * Linux startup code.
37  *
38  * At this point, the boot loader has:
39  * Disabled interrupts
40  * Disabled caches
41  * Put us in supervisor state.
42  *
43  * The kernel setup code takes the following steps:
44  * .  Raise interrupt level
45  * .  Set up initial kernel memory mapping.
46  *    .  This sets up a mapping of the 4M of memory the kernel is located in.
47  *    .  It also does a mapping of any initial machine specific areas.
48  * .  Enable the MMU
49  * .  Enable cache memories
50  * .  Jump to kernel startup
51  *
52  * Much of the file restructuring was to accomplish:
53  * 1) Remove register dependency through-out the file.
54  * 2) Increase use of subroutines to perform functions
55  * 3) Increase readability of the code
56  *
57  * Of course, readability is a subjective issue, so it will never be
58  * argued that that goal was accomplished.  It was merely a goal.
59  * A key way to help make code more readable is to give good
60  * documentation.  So, the first thing you will find is exaustive
61  * write-ups on the structure of the file, and the features of the
62  * functional subroutines.
63  *
64  * General Structure:
65  * ------------------
66  *      Without a doubt the single largest chunk of head.S is spent
67  * mapping the kernel and I/O physical space into the logical range
68  * for the kernel.
69  *      There are new subroutines and data structures to make MMU
70  * support cleaner and easier to understand.
71  *      First, you will find a routine call "mmu_map" which maps
72  * a logical to a physical region for some length given a cache
73  * type on behalf of the caller.  This routine makes writing the
74  * actual per-machine specific code very simple.
75  *      A central part of the code, but not a subroutine in itself,
76  * is the mmu_init code which is broken down into mapping the kernel
77  * (the same for all machines) and mapping machine-specific I/O
78  * regions.
79  *      Also, there will be a description of engaging the MMU and
80  * caches.
81  *      You will notice that there is a chunk of code which
82  * can emit the entire MMU mapping of the machine.  This is present
83  * only in debug modes and can be very helpful.
84  *      Further, there is a new console driver in head.S that is
85  * also only engaged in debug mode.  Currently, it's only supported
86  * on the Macintosh class of machines.  However, it is hoped that
87  * others will plug-in support for specific machines.
88  *
89  * ######################################################################
90  *
91  * mmu_map
92  * -------
93  *      mmu_map was written for two key reasons.  First, it was clear
94  * that it was very difficult to read the previous code for mapping
95  * regions of memory.  Second, the Macintosh required such extensive
96  * memory allocations that it didn't make sense to propagate the
97  * existing code any further.
98  *      mmu_map requires some parameters:
99  *
100  *      mmu_map (logical, physical, length, cache_type)
101  *
102  *      While this essentially describes the function in the abstract, you'll
103  * find more indepth description of other parameters at the implementation site.
104  *
105  * mmu_get_root_table_entry
106  * ------------------------
107  * mmu_get_ptr_table_entry
108  * -----------------------
109  * mmu_get_page_table_entry
110  * ------------------------
111  *
112  *      These routines are used by other mmu routines to get a pointer into
113  * a table, if necessary a new table is allocated. These routines are working
114  * basically like pmd_alloc() and pte_alloc() in <asm/pgtable.h>. The root
115  * table needs of course only to be allocated once in mmu_get_root_table_entry,
116  * so that here also some mmu specific initialization is done. The second page
117  * at the start of the kernel (the first page is unmapped later) is used for
118  * the kernel_pg_dir. It must be at a position known at link time (as it's used
119  * to initialize the init task struct) and since it needs special cache
120  * settings, it's the easiest to use this page, the rest of the page is used
121  * for further pointer tables.
122  * mmu_get_page_table_entry allocates always a whole page for page tables, this
123  * means 1024 pages and so 4MB of memory can be mapped. It doesn't make sense
124  * to manage page tables in smaller pieces as nearly all mappings have that
125  * size.
126  *
127  * ######################################################################
128  *
129  *
130  * ######################################################################
131  *
132  * mmu_engage
133  * ----------
134  *      Thanks to a small helping routine enabling the mmu got quite simple
135  * and there is only one way left. mmu_engage makes a complete a new mapping
136  * that only includes the absolute necessary to be able to jump to the final
137  * position and to restore the original mapping.
138  * As this code doesn't need a transparent translation register anymore this
139  * means all registers are free to be used by machines that needs them for
140  * other purposes.
141  *
142  * ######################################################################
143  *
144  * mmu_print
145  * ---------
146  *      This algorithm will print out the page tables of the system as
147  * appropriate for an 030 or an 040.  This is useful for debugging purposes
148  * and as such is enclosed in #ifdef MMU_PRINT/#endif clauses.
149  *
150  * ######################################################################
151  *
152  * console_init
153  * ------------
154  *      The console is also able to be turned off.  The console in head.S
155  * is specifically for debugging and can be very useful.  It is surrounded by
156  * #ifdef CONSOLE/#endif clauses so it doesn't have to ship in known-good
157  * kernels.  It's basic algorithm is to determine the size of the screen
158  * (in height/width and bit depth) and then use that information for
159  * displaying an 8x8 font or an 8x16 (widthxheight).  I prefer the 8x8 for
160  * debugging so I can see more good data.  But it was trivial to add support
161  * for both fonts, so I included it.
162  *      Also, the algorithm for plotting pixels is abstracted so that in
163  * theory other platforms could add support for different kinds of frame
164  * buffers.  This could be very useful.
165  *
166  * console_put_penguin
167  * -------------------
168  *      An important part of any Linux bring up is the penguin and there's
169  * nothing like getting the Penguin on the screen!  This algorithm will work
170  * on any machine for which there is a console_plot_pixel.
171  *
172  * console_scroll
173  * --------------
174  *      My hope is that the scroll algorithm does the right thing on the
175  * various platforms, but it wouldn't be hard to add the test conditions
176  * and new code if it doesn't.
177  *
178  * console_putc
179  * -------------
180  *
181  * ######################################################################
182  *
183  *      Register usage has greatly simplified within head.S. Every subroutine
184  * saves and restores all registers that it modifies (except it returns a
185  * value in there of course). So the only register that needs to be initialized
186  * is the stack pointer.
187  * All other init code and data is now placed in the init section, so it will
188  * be automatically freed at the end of the kernel initialization.
189  *
190  * ######################################################################
191  *
192  * options
193  * -------
194  *      There are many options available in a build of this file.  I've
195  * taken the time to describe them here to save you the time of searching
196  * for them and trying to understand what they mean.
197  *
198  * CONFIG_xxx:  These are the obvious machine configuration defines created
199  * during configuration.  These are defined in autoconf.h.
200  *
201  * CONSOLE:     There is support for head.S console in this file.  This
202  * console can talk to a Mac frame buffer, but could easily be extrapolated
203  * to extend it to support other platforms.
204  *
205  * TEST_MMU:    This is a test harness for running on any given machine but
206  * getting an MMU dump for another class of machine.  The classes of machines
207  * that can be tested are any of the makes (Atari, Amiga, Mac, VME, etc.)
208  * and any of the models (030, 040, 060, etc.).
209  *
210  *      NOTE:   TEST_MMU is NOT permanent!  It is scheduled to be removed
211  *              When head.S boots on Atari, Amiga, Macintosh, and VME
212  *              machines.  At that point the underlying logic will be
213  *              believed to be solid enough to be trusted, and TEST_MMU
214  *              can be dropped.  Do note that that will clean up the
215  *              head.S code significantly as large blocks of #if/#else
216  *              clauses can be removed.
217  *
218  * MMU_NOCACHE_KERNEL:  On the Macintosh platform there was an inquiry into
219  * determing why devices don't appear to work.  A test case was to remove
220  * the cacheability of the kernel bits.
221  *
222  * MMU_PRINT:   There is a routine built into head.S that can display the
223  * MMU data structures.  It outputs its result through the serial_putc
224  * interface.  So where ever that winds up driving data, that's where the
225  * mmu struct will appear.  On the Macintosh that's typically the console.
226  *
227  * SERIAL_DEBUG:        There are a series of putc() macro statements
228  * scattered through out the code to give progress of status to the
229  * person sitting at the console.  This constant determines whether those
230  * are used.
231  *
232  * DEBUG:       This is the standard DEBUG flag that can be set for building
233  *              the kernel.  It has the effect adding additional tests into
234  *              the code.
235  *
236  * FONT_6x11:
237  * FONT_8x8:
238  * FONT_8x16:
239  *              In theory these could be determined at run time or handed
240  *              over by the booter.  But, let's be real, it's a fine hard
241  *              coded value.  (But, you will notice the code is run-time
242  *              flexible!)  A pointer to the font's struct font_desc
243  *              is kept locally in Lconsole_font.  It is used to determine
244  *              font size information dynamically.
245  *
246  * Atari constants:
247  * USE_PRINTER: Use the printer port for serial debug.
248  * USE_SCC_B:   Use the SCC port A (Serial2) for serial debug.
249  * USE_SCC_A:   Use the SCC port B (Modem2) for serial debug.
250  * USE_MFP:     Use the ST-MFP port (Modem1) for serial debug.
251  *
252  * Macintosh constants:
253  * MAC_USE_SCC_A: Use SCC port A (modem) for serial debug and early console.
254  * MAC_USE_SCC_B: Use SCC port B (printer) for serial debug and early console.
255  */
256
257 #include <linux/linkage.h>
258 #include <linux/init.h>
259 #include <asm/bootinfo.h>
260 #include <asm/bootinfo-amiga.h>
261 #include <asm/bootinfo-atari.h>
262 #include <asm/bootinfo-hp300.h>
263 #include <asm/bootinfo-mac.h>
264 #include <asm/bootinfo-q40.h>
265 #include <asm/bootinfo-vme.h>
266 #include <asm/setup.h>
267 #include <asm/entry.h>
268 #include <asm/pgtable.h>
269 #include <asm/page.h>
270 #include <asm/asm-offsets.h>
271
272 #ifdef CONFIG_MAC
273
274 #include <asm/machw.h>
275
276 #ifdef CONFIG_FRAMEBUFFER_CONSOLE
277 #define CONSOLE
278 #endif
279
280 #ifdef CONFIG_EARLY_PRINTK
281 #define SERIAL_DEBUG
282 #else
283 #undef SERIAL_DEBUG
284 #endif
285
286 #else /* !CONFIG_MAC */
287
288 #define SERIAL_DEBUG
289
290 #endif /* !CONFIG_MAC */
291
292 #undef MMU_PRINT
293 #undef MMU_NOCACHE_KERNEL
294 #undef DEBUG
295
296 /*
297  * For the head.S console, there are three supported fonts, 6x11, 8x16 and 8x8.
298  * The 8x8 font is harder to read but fits more on the screen.
299  */
300 #define FONT_8x8        /* default */
301 /* #define FONT_8x16 */ /* 2nd choice */
302 /* #define FONT_6x11 */ /* 3rd choice */
303
304 .globl kernel_pg_dir
305 .globl availmem
306 .globl m68k_pgtable_cachemode
307 .globl m68k_supervisor_cachemode
308 #ifdef CONFIG_MVME16x
309 .globl mvme_bdid
310 #endif
311 #ifdef CONFIG_Q40
312 .globl q40_mem_cptr
313 #endif
314
315 CPUTYPE_040     = 1     /* indicates an 040 */
316 CPUTYPE_060     = 2     /* indicates an 060 */
317 CPUTYPE_0460    = 3     /* if either above are set, this is set */
318 CPUTYPE_020     = 4     /* indicates an 020 */
319
320 /* Translation control register */
321 TC_ENABLE = 0x8000
322 TC_PAGE8K = 0x4000
323 TC_PAGE4K = 0x0000
324
325 /* Transparent translation registers */
326 TTR_ENABLE      = 0x8000        /* enable transparent translation */
327 TTR_ANYMODE     = 0x4000        /* user and kernel mode access */
328 TTR_KERNELMODE  = 0x2000        /* only kernel mode access */
329 TTR_USERMODE    = 0x0000        /* only user mode access */
330 TTR_CI          = 0x0400        /* inhibit cache */
331 TTR_RW          = 0x0200        /* read/write mode */
332 TTR_RWM         = 0x0100        /* read/write mask */
333 TTR_FCB2        = 0x0040        /* function code base bit 2 */
334 TTR_FCB1        = 0x0020        /* function code base bit 1 */
335 TTR_FCB0        = 0x0010        /* function code base bit 0 */
336 TTR_FCM2        = 0x0004        /* function code mask bit 2 */
337 TTR_FCM1        = 0x0002        /* function code mask bit 1 */
338 TTR_FCM0        = 0x0001        /* function code mask bit 0 */
339
340 /* Cache Control registers */
341 CC6_ENABLE_D    = 0x80000000    /* enable data cache (680[46]0) */
342 CC6_FREEZE_D    = 0x40000000    /* freeze data cache (68060) */
343 CC6_ENABLE_SB   = 0x20000000    /* enable store buffer (68060) */
344 CC6_PUSH_DPI    = 0x10000000    /* disable CPUSH invalidation (68060) */
345 CC6_HALF_D      = 0x08000000    /* half-cache mode for data cache (68060) */
346 CC6_ENABLE_B    = 0x00800000    /* enable branch cache (68060) */
347 CC6_CLRA_B      = 0x00400000    /* clear all entries in branch cache (68060) */
348 CC6_CLRU_B      = 0x00200000    /* clear user entries in branch cache (68060) */
349 CC6_ENABLE_I    = 0x00008000    /* enable instruction cache (680[46]0) */
350 CC6_FREEZE_I    = 0x00004000    /* freeze instruction cache (68060) */
351 CC6_HALF_I      = 0x00002000    /* half-cache mode for instruction cache (68060) */
352 CC3_ALLOC_WRITE = 0x00002000    /* write allocate mode(68030) */
353 CC3_ENABLE_DB   = 0x00001000    /* enable data burst (68030) */
354 CC3_CLR_D       = 0x00000800    /* clear data cache (68030) */
355 CC3_CLRE_D      = 0x00000400    /* clear entry in data cache (68030) */
356 CC3_FREEZE_D    = 0x00000200    /* freeze data cache (68030) */
357 CC3_ENABLE_D    = 0x00000100    /* enable data cache (68030) */
358 CC3_ENABLE_IB   = 0x00000010    /* enable instruction burst (68030) */
359 CC3_CLR_I       = 0x00000008    /* clear instruction cache (68030) */
360 CC3_CLRE_I      = 0x00000004    /* clear entry in instruction cache (68030) */
361 CC3_FREEZE_I    = 0x00000002    /* freeze instruction cache (68030) */
362 CC3_ENABLE_I    = 0x00000001    /* enable instruction cache (68030) */
363
364 /* Miscellaneous definitions */
365 PAGESIZE        = 4096
366 PAGESHIFT       = 12
367
368 ROOT_TABLE_SIZE = 128
369 PTR_TABLE_SIZE  = 128
370 PAGE_TABLE_SIZE = 64
371 ROOT_INDEX_SHIFT = 25
372 PTR_INDEX_SHIFT  = 18
373 PAGE_INDEX_SHIFT = 12
374
375 #ifdef DEBUG
376 /* When debugging use readable names for labels */
377 #ifdef __STDC__
378 #define L(name) .head.S.##name
379 #else
380 #define L(name) .head.S./**/name
381 #endif
382 #else
383 #ifdef __STDC__
384 #define L(name) .L##name
385 #else
386 #define L(name) .L/**/name
387 #endif
388 #endif
389
390 /* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
391 #ifndef __INITDATA
392 #define __INITDATA      .data
393 #define __FINIT         .previous
394 #endif
395
396 /* Several macros to make the writing of subroutines easier:
397  * - func_start marks the beginning of the routine which setups the frame
398  *   register and saves the registers, it also defines another macro
399  *   to automatically restore the registers again.
400  * - func_return marks the end of the routine and simply calls the prepared
401  *   macro to restore registers and jump back to the caller.
402  * - func_define generates another macro to automatically put arguments
403  *   onto the stack call the subroutine and cleanup the stack again.
404  */
405
406 /* Within subroutines these macros can be used to access the arguments
407  * on the stack. With STACK some allocated memory on the stack can be
408  * accessed and ARG0 points to the return address (used by mmu_engage).
409  */
410 #define STACK   %a6@(stackstart)
411 #define ARG0    %a6@(4)
412 #define ARG1    %a6@(8)
413 #define ARG2    %a6@(12)
414 #define ARG3    %a6@(16)
415 #define ARG4    %a6@(20)
416
417 .macro  func_start      name,saveregs,stack=0
418 L(\name):
419         linkw   %a6,#-\stack
420         moveml  \saveregs,%sp@-
421 .set    stackstart,-\stack
422
423 .macro  func_return_\name
424         moveml  %sp@+,\saveregs
425         unlk    %a6
426         rts
427 .endm
428 .endm
429
430 .macro  func_return     name
431         func_return_\name
432 .endm
433
434 .macro  func_call       name
435         jbsr    L(\name)
436 .endm
437
438 .macro  move_stack      nr,arg1,arg2,arg3,arg4
439 .if     \nr
440         move_stack      "(\nr-1)",\arg2,\arg3,\arg4
441         movel   \arg1,%sp@-
442 .endif
443 .endm
444
445 .macro  func_define     name,nr=0
446 .macro  \name   arg1,arg2,arg3,arg4
447         move_stack      \nr,\arg1,\arg2,\arg3,\arg4
448         func_call       \name
449 .if     \nr
450         lea     %sp@(\nr*4),%sp
451 .endif
452 .endm
453 .endm
454
455 func_define     mmu_map,4
456 func_define     mmu_map_tt,4
457 func_define     mmu_fixup_page_mmu_cache,1
458 func_define     mmu_temp_map,2
459 func_define     mmu_engage
460 func_define     mmu_get_root_table_entry,1
461 func_define     mmu_get_ptr_table_entry,2
462 func_define     mmu_get_page_table_entry,2
463 func_define     mmu_print
464 func_define     get_new_page
465 #if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
466 func_define     set_leds
467 #endif
468
469 .macro  mmu_map_eq      arg1,arg2,arg3
470         mmu_map \arg1,\arg1,\arg2,\arg3
471 .endm
472
473 .macro  get_bi_record   record
474         pea     \record
475         func_call       get_bi_record
476         addql   #4,%sp
477 .endm
478
479 func_define     serial_putc,1
480 func_define     console_putc,1
481
482 func_define     console_init
483 func_define     console_put_stats
484 func_define     console_put_penguin
485 func_define     console_plot_pixel,3
486 func_define     console_scroll
487
488 .macro  putc    ch
489 #if defined(CONSOLE) || defined(SERIAL_DEBUG)
490         pea     \ch
491 #endif
492 #ifdef CONSOLE
493         func_call       console_putc
494 #endif
495 #ifdef SERIAL_DEBUG
496         func_call       serial_putc
497 #endif
498 #if defined(CONSOLE) || defined(SERIAL_DEBUG)
499         addql   #4,%sp
500 #endif
501 .endm
502
503 .macro  dputc   ch
504 #ifdef DEBUG
505         putc    \ch
506 #endif
507 .endm
508
509 func_define     putn,1
510
511 .macro  dputn   nr
512 #ifdef DEBUG
513         putn    \nr
514 #endif
515 .endm
516
517 .macro  puts            string
518 #if defined(CONSOLE) || defined(SERIAL_DEBUG)
519         __INITDATA
520 .Lstr\@:
521         .string "\string"
522         __FINIT
523         pea     %pc@(.Lstr\@)
524         func_call       puts
525         addql   #4,%sp
526 #endif
527 .endm
528
529 .macro  dputs   string
530 #ifdef DEBUG
531         puts    "\string"
532 #endif
533 .endm
534
535 #define is_not_amiga(lab) cmpl &MACH_AMIGA,%pc@(m68k_machtype); jne lab
536 #define is_not_atari(lab) cmpl &MACH_ATARI,%pc@(m68k_machtype); jne lab
537 #define is_not_mac(lab) cmpl &MACH_MAC,%pc@(m68k_machtype); jne lab
538 #define is_not_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jne lab
539 #define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab
540 #define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab
541 #define is_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jeq lab
542 #define is_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jeq lab
543 #define is_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jeq lab
544 #define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab
545 #define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab
546 #define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
547 #define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
548
549 #define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \
550                         jeq 42f; \
551                         cmpl &MACH_APOLLO,%pc@(m68k_machtype); \
552                         jne lab ;\
553                 42:\
554
555 #define is_040_or_060(lab)      btst &CPUTYPE_0460,%pc@(L(cputype)+3); jne lab
556 #define is_not_040_or_060(lab)  btst &CPUTYPE_0460,%pc@(L(cputype)+3); jeq lab
557 #define is_040(lab)             btst &CPUTYPE_040,%pc@(L(cputype)+3); jne lab
558 #define is_060(lab)             btst &CPUTYPE_060,%pc@(L(cputype)+3); jne lab
559 #define is_not_060(lab)         btst &CPUTYPE_060,%pc@(L(cputype)+3); jeq lab
560 #define is_020(lab)             btst &CPUTYPE_020,%pc@(L(cputype)+3); jne lab
561 #define is_not_020(lab)         btst &CPUTYPE_020,%pc@(L(cputype)+3); jeq lab
562
563 /* On the HP300 we use the on-board LEDs for debug output before
564    the console is running.  Writing a 1 bit turns the corresponding LED
565    _off_ - on the 340 bit 7 is towards the back panel of the machine.  */
566 .macro  leds    mask
567 #if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
568         hasnt_leds(.Lled\@)
569         pea     \mask
570         func_call       set_leds
571         addql   #4,%sp
572 .Lled\@:
573 #endif
574 .endm
575
576 __HEAD
577 ENTRY(_stext)
578 /*
579  * Version numbers of the bootinfo interface
580  * The area from _stext to _start will later be used as kernel pointer table
581  */
582         bras    1f      /* Jump over bootinfo version numbers */
583
584         .long   BOOTINFOV_MAGIC
585         .long   MACH_AMIGA, AMIGA_BOOTI_VERSION
586         .long   MACH_ATARI, ATARI_BOOTI_VERSION
587         .long   MACH_MVME147, MVME147_BOOTI_VERSION
588         .long   MACH_MVME16x, MVME16x_BOOTI_VERSION
589         .long   MACH_BVME6000, BVME6000_BOOTI_VERSION
590         .long   MACH_MAC, MAC_BOOTI_VERSION
591         .long   MACH_Q40, Q40_BOOTI_VERSION
592         .long   MACH_HP300, HP300_BOOTI_VERSION
593         .long   0
594 1:      jra     __start
595
596 .equ    kernel_pg_dir,_stext
597
598 .equ    .,_stext+PAGESIZE
599
600 ENTRY(_start)
601         jra     __start
602 __INIT
603 ENTRY(__start)
604 /*
605  * Setup initial stack pointer
606  */
607         lea     %pc@(_stext),%sp
608
609 /*
610  * Record the CPU and machine type.
611  */
612         get_bi_record   BI_MACHTYPE
613         lea     %pc@(m68k_machtype),%a1
614         movel   %a0@,%a1@
615
616         get_bi_record   BI_FPUTYPE
617         lea     %pc@(m68k_fputype),%a1
618         movel   %a0@,%a1@
619
620         get_bi_record   BI_MMUTYPE
621         lea     %pc@(m68k_mmutype),%a1
622         movel   %a0@,%a1@
623
624         get_bi_record   BI_CPUTYPE
625         lea     %pc@(m68k_cputype),%a1
626         movel   %a0@,%a1@
627
628         leds    0x1
629
630 #ifdef CONFIG_MAC
631 /*
632  * For Macintosh, we need to determine the display parameters early (at least
633  * while debugging it).
634  */
635
636         is_not_mac(L(test_notmac))
637
638         get_bi_record   BI_MAC_VADDR
639         lea     %pc@(L(mac_videobase)),%a1
640         movel   %a0@,%a1@
641
642         get_bi_record   BI_MAC_VDEPTH
643         lea     %pc@(L(mac_videodepth)),%a1
644         movel   %a0@,%a1@
645
646         get_bi_record   BI_MAC_VDIM
647         lea     %pc@(L(mac_dimensions)),%a1
648         movel   %a0@,%a1@
649
650         get_bi_record   BI_MAC_VROW
651         lea     %pc@(L(mac_rowbytes)),%a1
652         movel   %a0@,%a1@
653
654 #ifdef SERIAL_DEBUG
655         get_bi_record   BI_MAC_SCCBASE
656         lea     %pc@(L(mac_sccbase)),%a1
657         movel   %a0@,%a1@
658 #endif
659
660 #if 0
661         /*
662          * Clear the screen
663          */
664         lea     %pc@(L(mac_videobase)),%a0
665         movel   %a0@,%a1
666         lea     %pc@(L(mac_dimensions)),%a0
667         movel   %a0@,%d1
668         swap    %d1             /* #rows is high bytes */
669         andl    #0xFFFF,%d1     /* rows */
670         subl    #10,%d1
671         lea     %pc@(L(mac_rowbytes)),%a0
672 loopy2:
673         movel   %a0@,%d0
674         subql   #1,%d0
675 loopx2:
676         moveb   #0x55, %a1@+
677         dbra    %d0,loopx2
678         dbra    %d1,loopy2
679 #endif
680
681 L(test_notmac):
682 #endif /* CONFIG_MAC */
683
684
685 /*
686  * There are ultimately two pieces of information we want for all kinds of
687  * processors CpuType and CacheBits.  The CPUTYPE was passed in from booter
688  * and is converted here from a booter type definition to a separate bit
689  * number which allows for the standard is_0x0 macro tests.
690  */
691         movel   %pc@(m68k_cputype),%d0
692         /*
693          * Assume it's an 030
694          */
695         clrl    %d1
696
697         /*
698          * Test the BootInfo cputype for 060
699          */
700         btst    #CPUB_68060,%d0
701         jeq     1f
702         bset    #CPUTYPE_060,%d1
703         bset    #CPUTYPE_0460,%d1
704         jra     3f
705 1:
706         /*
707          * Test the BootInfo cputype for 040
708          */
709         btst    #CPUB_68040,%d0
710         jeq     2f
711         bset    #CPUTYPE_040,%d1
712         bset    #CPUTYPE_0460,%d1
713         jra     3f
714 2:
715         /*
716          * Test the BootInfo cputype for 020
717          */
718         btst    #CPUB_68020,%d0
719         jeq     3f
720         bset    #CPUTYPE_020,%d1
721         jra     3f
722 3:
723         /*
724          * Record the cpu type
725          */
726         lea     %pc@(L(cputype)),%a0
727         movel   %d1,%a0@
728
729         /*
730          * NOTE:
731          *
732          * Now the macros are valid:
733          *      is_040_or_060
734          *      is_not_040_or_060
735          *      is_040
736          *      is_060
737          *      is_not_060
738          */
739
740         /*
741          * Determine the cache mode for pages holding MMU tables
742          * and for supervisor mode, unused for '020 and '030
743          */
744         clrl    %d0
745         clrl    %d1
746
747         is_not_040_or_060(L(save_cachetype))
748
749         /*
750          * '040 or '060
751          * d1 := cacheable write-through
752          * NOTE: The 68040 manual strongly recommends non-cached for MMU tables,
753          * but we have been using write-through since at least 2.0.29 so I
754          * guess it is OK.
755          */
756 #ifdef CONFIG_060_WRITETHROUGH
757         /*
758          * If this is a 68060 board using drivers with cache coherency
759          * problems, then supervisor memory accesses need to be write-through
760          * also; otherwise, we want copyback.
761          */
762
763         is_not_060(1f)
764         movel   #_PAGE_CACHE040W,%d0
765         jra     L(save_cachetype)
766 #endif /* CONFIG_060_WRITETHROUGH */
767 1:
768         movew   #_PAGE_CACHE040,%d0
769
770         movel   #_PAGE_CACHE040W,%d1
771
772 L(save_cachetype):
773         /* Save cache mode for supervisor mode and page tables
774          */
775         lea     %pc@(m68k_supervisor_cachemode),%a0
776         movel   %d0,%a0@
777         lea     %pc@(m68k_pgtable_cachemode),%a0
778         movel   %d1,%a0@
779
780 /*
781  * raise interrupt level
782  */
783         movew   #0x2700,%sr
784
785 /*
786    If running on an Atari, determine the I/O base of the
787    serial port and test if we are running on a Medusa or Hades.
788    This test is necessary here, because on the Hades the serial
789    port is only accessible in the high I/O memory area.
790
791    The test whether it is a Medusa is done by writing to the byte at
792    phys. 0x0. This should result in a bus error on all other machines.
793
794    ...should, but doesn't. The Afterburner040 for the Falcon has the
795    same behaviour (0x0..0x7 are no ROM shadow). So we have to do
796    another test to distinguish Medusa and AB040. This is a
797    read attempt for 0x00ff82fe phys. that should bus error on a Falcon
798    (+AB040), but is in the range where the Medusa always asserts DTACK.
799
800    The test for the Hades is done by reading address 0xb0000000. This
801    should give a bus error on the Medusa.
802  */
803
804 #ifdef CONFIG_ATARI
805         is_not_atari(L(notypetest))
806
807         /* get special machine type (Medusa/Hades/AB40) */
808         moveq   #0,%d3 /* default if tag doesn't exist */
809         get_bi_record   BI_ATARI_MCH_TYPE
810         tstl    %d0
811         jbmi    1f
812         movel   %a0@,%d3
813         lea     %pc@(atari_mch_type),%a0
814         movel   %d3,%a0@
815 1:
816         /* On the Hades, the iobase must be set up before opening the
817          * serial port. There are no I/O regs at 0x00ffxxxx at all. */
818         moveq   #0,%d0
819         cmpl    #ATARI_MACH_HADES,%d3
820         jbne    1f
821         movel   #0xff000000,%d0         /* Hades I/O base addr: 0xff000000 */
822 1:      lea     %pc@(L(iobase)),%a0
823         movel   %d0,%a0@
824
825 L(notypetest):
826 #endif
827
828 #ifdef CONFIG_VME
829         is_mvme147(L(getvmetype))
830         is_bvme6000(L(getvmetype))
831         is_not_mvme16x(L(gvtdone))
832
833         /* See if the loader has specified the BI_VME_TYPE tag.  Recent
834          * versions of VMELILO and TFTPLILO do this.  We have to do this
835          * early so we know how to handle console output.  If the tag
836          * doesn't exist then we use the Bug for output on MVME16x.
837          */
838 L(getvmetype):
839         get_bi_record   BI_VME_TYPE
840         tstl    %d0
841         jbmi    1f
842         movel   %a0@,%d3
843         lea     %pc@(vme_brdtype),%a0
844         movel   %d3,%a0@
845 1:
846 #ifdef CONFIG_MVME16x
847         is_not_mvme16x(L(gvtdone))
848
849         /* Need to get the BRD_ID info to differentiate between 162, 167,
850          * etc.  This is available as a BI_VME_BRDINFO tag with later
851          * versions of VMELILO and TFTPLILO, otherwise we call the Bug.
852          */
853         get_bi_record   BI_VME_BRDINFO
854         tstl    %d0
855         jpl     1f
856
857         /* Get pointer to board ID data from Bug */
858         movel   %d2,%sp@-
859         trap    #15
860         .word   0x70            /* trap 0x70 - .BRD_ID */
861         movel   %sp@+,%a0
862 1:
863         lea     %pc@(mvme_bdid),%a1
864         /* Structure is 32 bytes long */
865         movel   %a0@+,%a1@+
866         movel   %a0@+,%a1@+
867         movel   %a0@+,%a1@+
868         movel   %a0@+,%a1@+
869         movel   %a0@+,%a1@+
870         movel   %a0@+,%a1@+
871         movel   %a0@+,%a1@+
872         movel   %a0@+,%a1@+
873 #endif
874
875 L(gvtdone):
876
877 #endif
878
879 #ifdef CONFIG_HP300
880         is_not_hp300(L(nothp))
881
882         /* Get the address of the UART for serial debugging */
883         get_bi_record   BI_HP300_UART_ADDR
884         tstl    %d0
885         jbmi    1f
886         movel   %a0@,%d3
887         lea     %pc@(L(uartbase)),%a0
888         movel   %d3,%a0@
889         get_bi_record   BI_HP300_UART_SCODE
890         tstl    %d0
891         jbmi    1f
892         movel   %a0@,%d3
893         lea     %pc@(L(uart_scode)),%a0
894         movel   %d3,%a0@
895 1:
896 L(nothp):
897 #endif
898
899 /*
900  * Initialize serial port
901  */
902         jbsr    L(serial_init)
903
904 /*
905  * Initialize console
906  */
907 #ifdef CONFIG_MAC
908         is_not_mac(L(nocon))
909 #  ifdef CONSOLE
910         console_init
911 #    ifdef CONFIG_LOGO
912         console_put_penguin
913 #    endif /* CONFIG_LOGO */
914         console_put_stats
915 #  endif /* CONSOLE */
916 L(nocon):
917 #endif /* CONFIG_MAC */
918
919
920         putc    '\n'
921         putc    'A'
922         leds    0x2
923         dputn   %pc@(L(cputype))
924         dputn   %pc@(m68k_supervisor_cachemode)
925         dputn   %pc@(m68k_pgtable_cachemode)
926         dputc   '\n'
927
928 /*
929  * Save physical start address of kernel
930  */
931         lea     %pc@(L(phys_kernel_start)),%a0
932         lea     %pc@(_stext),%a1
933         subl    #_stext,%a1
934         addl    #PAGE_OFFSET,%a1
935         movel   %a1,%a0@
936
937         putc    'B'
938
939         leds    0x4
940
941 /*
942  *      mmu_init
943  *
944  *      This block of code does what's necessary to map in the various kinds
945  *      of machines for execution of Linux.
946  *      First map the first 4 MB of kernel code & data
947  */
948
949         mmu_map #PAGE_OFFSET,%pc@(L(phys_kernel_start)),#4*1024*1024,\
950                 %pc@(m68k_supervisor_cachemode)
951
952         putc    'C'
953
954 #ifdef CONFIG_AMIGA
955
956 L(mmu_init_amiga):
957
958         is_not_amiga(L(mmu_init_not_amiga))
959 /*
960  * mmu_init_amiga
961  */
962
963         putc    'D'
964
965         is_not_040_or_060(1f)
966
967         /*
968          * 040: Map the 16Meg range physical 0x0 up to logical 0x8000.0000
969          */
970         mmu_map         #0x80000000,#0,#0x01000000,#_PAGE_NOCACHE_S
971         /*
972          * Map the Zorro III I/O space with transparent translation
973          * for frame buffer memory etc.
974          */
975         mmu_map_tt      #1,#0x40000000,#0x20000000,#_PAGE_NOCACHE_S
976
977         jbra    L(mmu_init_done)
978
979 1:
980         /*
981          * 030: Map the 32Meg range physical 0x0 up to logical 0x8000.0000
982          */
983         mmu_map         #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
984         mmu_map_tt      #1,#0x40000000,#0x20000000,#_PAGE_NOCACHE030
985
986         jbra    L(mmu_init_done)
987
988 L(mmu_init_not_amiga):
989 #endif
990
991 #ifdef CONFIG_ATARI
992
993 L(mmu_init_atari):
994
995         is_not_atari(L(mmu_init_not_atari))
996
997         putc    'E'
998
999 /* On the Atari, we map the I/O region (phys. 0x00ffxxxx) by mapping
1000    the last 16 MB of virtual address space to the first 16 MB (i.e.
1001    0xffxxxxxx -> 0x00xxxxxx). For this, an additional pointer table is
1002    needed. I/O ranges are marked non-cachable.
1003
1004    For the Medusa it is better to map the I/O region transparently
1005    (i.e. 0xffxxxxxx -> 0xffxxxxxx), because some I/O registers are
1006    accessible only in the high area.
1007
1008    On the Hades all I/O registers are only accessible in the high
1009    area.
1010 */
1011
1012         /* I/O base addr for non-Medusa, non-Hades: 0x00000000 */
1013         moveq   #0,%d0
1014         movel   %pc@(atari_mch_type),%d3
1015         cmpl    #ATARI_MACH_MEDUSA,%d3
1016         jbeq    2f
1017         cmpl    #ATARI_MACH_HADES,%d3
1018         jbne    1f
1019 2:      movel   #0xff000000,%d0 /* Medusa/Hades base addr: 0xff000000 */
1020 1:      movel   %d0,%d3
1021
1022         is_040_or_060(L(spata68040))
1023
1024         /* Map everything non-cacheable, though not all parts really
1025          * need to disable caches (crucial only for 0xff8000..0xffffff
1026          * (standard I/O) and 0xf00000..0xf3ffff (IDE)). The remainder
1027          * isn't really used, except for sometimes peeking into the
1028          * ROMs (mirror at phys. 0x0), so caching isn't necessary for
1029          * this. */
1030         mmu_map #0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE030
1031
1032         jbra    L(mmu_init_done)
1033
1034 L(spata68040):
1035
1036         mmu_map #0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE_S
1037
1038         jbra    L(mmu_init_done)
1039
1040 L(mmu_init_not_atari):
1041 #endif
1042
1043 #ifdef CONFIG_Q40
1044         is_not_q40(L(notq40))
1045         /*
1046          * add transparent mapping for 0xff00 0000 - 0xffff ffff
1047          * non-cached serialized etc..
1048          * this includes master chip, DAC, RTC and ISA ports
1049          * 0xfe000000-0xfeffffff is for screen and ROM
1050          */
1051
1052         putc    'Q'
1053
1054         mmu_map_tt      #0,#0xfe000000,#0x01000000,#_PAGE_CACHE040W
1055         mmu_map_tt      #1,#0xff000000,#0x01000000,#_PAGE_NOCACHE_S
1056
1057         jbra    L(mmu_init_done)
1058
1059 L(notq40):
1060 #endif
1061
1062 #ifdef CONFIG_HP300
1063         is_not_hp300(L(nothp300))
1064
1065         /* On the HP300, we map the ROM, INTIO and DIO regions (phys. 0x00xxxxxx)
1066          * by mapping 32MB (on 020/030) or 16 MB (on 040) from 0xf0xxxxxx -> 0x00xxxxxx).
1067          * The ROM mapping is needed because the LEDs are mapped there too.
1068          */
1069
1070         is_040(1f)
1071
1072         /*
1073          * 030: Map the 32Meg range physical 0x0 up to logical 0xf000.0000
1074          */
1075         mmu_map #0xf0000000,#0,#0x02000000,#_PAGE_NOCACHE030
1076
1077         jbra    L(mmu_init_done)
1078
1079 1:
1080         /*
1081          * 040: Map the 16Meg range physical 0x0 up to logical 0xf000.0000
1082          */
1083         mmu_map #0xf0000000,#0,#0x01000000,#_PAGE_NOCACHE_S
1084
1085         jbra    L(mmu_init_done)
1086
1087 L(nothp300):
1088 #endif /* CONFIG_HP300 */
1089
1090 #ifdef CONFIG_MVME147
1091
1092         is_not_mvme147(L(not147))
1093
1094         /*
1095          * On MVME147 we have already created kernel page tables for
1096          * 4MB of RAM at address 0, so now need to do a transparent
1097          * mapping of the top of memory space.  Make it 0.5GByte for now,
1098          * so we can access on-board i/o areas.
1099          */
1100
1101         mmu_map_tt      #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE030
1102
1103         jbra    L(mmu_init_done)
1104
1105 L(not147):
1106 #endif /* CONFIG_MVME147 */
1107
1108 #ifdef CONFIG_MVME16x
1109
1110         is_not_mvme16x(L(not16x))
1111
1112         /*
1113          * On MVME16x we have already created kernel page tables for
1114          * 4MB of RAM at address 0, so now need to do a transparent
1115          * mapping of the top of memory space.  Make it 0.5GByte for now.
1116          * Supervisor only access, so transparent mapping doesn't
1117          * clash with User code virtual address space.
1118          * this covers IO devices, PROM and SRAM.  The PROM and SRAM
1119          * mapping is needed to allow 167Bug to run.
1120          * IO is in the range 0xfff00000 to 0xfffeffff.
1121          * PROM is 0xff800000->0xffbfffff and SRAM is
1122          * 0xffe00000->0xffe1ffff.
1123          */
1124
1125         mmu_map_tt      #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
1126
1127         jbra    L(mmu_init_done)
1128
1129 L(not16x):
1130 #endif  /* CONFIG_MVME162 | CONFIG_MVME167 */
1131
1132 #ifdef CONFIG_BVME6000
1133
1134         is_not_bvme6000(L(not6000))
1135
1136         /*
1137          * On BVME6000 we have already created kernel page tables for
1138          * 4MB of RAM at address 0, so now need to do a transparent
1139          * mapping of the top of memory space.  Make it 0.5GByte for now,
1140          * so we can access on-board i/o areas.
1141          * Supervisor only access, so transparent mapping doesn't
1142          * clash with User code virtual address space.
1143          */
1144
1145         mmu_map_tt      #1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
1146
1147         jbra    L(mmu_init_done)
1148
1149 L(not6000):
1150 #endif /* CONFIG_BVME6000 */
1151
1152 /*
1153  * mmu_init_mac
1154  *
1155  * The Macintosh mappings are less clear.
1156  *
1157  * Even as of this writing, it is unclear how the
1158  * Macintosh mappings will be done.  However, as
1159  * the first author of this code I'm proposing the
1160  * following model:
1161  *
1162  * Map the kernel (that's already done),
1163  * Map the I/O (on most machines that's the
1164  * 0x5000.0000 ... 0x5300.0000 range,
1165  * Map the video frame buffer using as few pages
1166  * as absolutely (this requirement mostly stems from
1167  * the fact that when the frame buffer is at
1168  * 0x0000.0000 then we know there is valid RAM just
1169  * above the screen that we don't want to waste!).
1170  *
1171  * By the way, if the frame buffer is at 0x0000.0000
1172  * then the Macintosh is known as an RBV based Mac.
1173  *
1174  * By the way 2, the code currently maps in a bunch of
1175  * regions.  But I'd like to cut that out.  (And move most
1176  * of the mappings up into the kernel proper ... or only
1177  * map what's necessary.)
1178  */
1179
1180 #ifdef CONFIG_MAC
1181
1182 L(mmu_init_mac):
1183
1184         is_not_mac(L(mmu_init_not_mac))
1185
1186         putc    'F'
1187
1188         is_not_040_or_060(1f)
1189
1190         moveq   #_PAGE_NOCACHE_S,%d3
1191         jbra    2f
1192 1:
1193         moveq   #_PAGE_NOCACHE030,%d3
1194 2:
1195         /*
1196          * Mac Note: screen address of logical 0xF000.0000 -> <screen physical>
1197          *           we simply map the 4MB that contains the videomem
1198          */
1199
1200         movel   #VIDEOMEMMASK,%d0
1201         andl    %pc@(L(mac_videobase)),%d0
1202
1203         mmu_map         #VIDEOMEMBASE,%d0,#VIDEOMEMSIZE,%d3
1204         /* ROM from 4000 0000 to 4200 0000 (only for mac_reset()) */
1205         mmu_map_eq      #0x40000000,#0x02000000,%d3
1206         /* IO devices (incl. serial port) from 5000 0000 to 5300 0000 */
1207         mmu_map_eq      #0x50000000,#0x03000000,%d3
1208         /* Nubus slot space (video at 0xF0000000, rom at 0xF0F80000) */
1209         mmu_map_tt      #1,#0xf8000000,#0x08000000,%d3
1210
1211         jbra    L(mmu_init_done)
1212
1213 L(mmu_init_not_mac):
1214 #endif
1215
1216 #ifdef CONFIG_SUN3X
1217         is_not_sun3x(L(notsun3x))
1218
1219         /* oh, the pain..  We're gonna want the prom code after
1220          * starting the MMU, so we copy the mappings, translating
1221          * from 8k -> 4k pages as we go.
1222          */
1223
1224         /* copy maps from 0xfee00000 to 0xff000000 */
1225         movel   #0xfee00000, %d0
1226         moveq   #ROOT_INDEX_SHIFT, %d1
1227         lsrl    %d1,%d0
1228         mmu_get_root_table_entry        %d0
1229
1230         movel   #0xfee00000, %d0
1231         moveq   #PTR_INDEX_SHIFT, %d1
1232         lsrl    %d1,%d0
1233         andl    #PTR_TABLE_SIZE-1, %d0
1234         mmu_get_ptr_table_entry         %a0,%d0
1235
1236         movel   #0xfee00000, %d0
1237         moveq   #PAGE_INDEX_SHIFT, %d1
1238         lsrl    %d1,%d0
1239         andl    #PAGE_TABLE_SIZE-1, %d0
1240         mmu_get_page_table_entry        %a0,%d0
1241
1242         /* this is where the prom page table lives */
1243         movel   0xfefe00d4, %a1
1244         movel   %a1@, %a1
1245
1246         movel   #((0x200000 >> 13)-1), %d1
1247
1248 1:
1249         movel   %a1@+, %d3
1250         movel   %d3,%a0@+
1251         addl    #0x1000,%d3
1252         movel   %d3,%a0@+
1253
1254         dbra    %d1,1b
1255
1256         /* setup tt1 for I/O */
1257         mmu_map_tt      #1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
1258         jbra    L(mmu_init_done)
1259
1260 L(notsun3x):
1261 #endif
1262
1263 #ifdef CONFIG_APOLLO
1264         is_not_apollo(L(notapollo))
1265
1266         putc    'P'
1267         mmu_map         #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
1268
1269 L(notapollo):
1270         jbra    L(mmu_init_done)
1271 #endif
1272
1273 L(mmu_init_done):
1274
1275         putc    'G'
1276         leds    0x8
1277
1278 /*
1279  * mmu_fixup
1280  *
1281  * On the 040 class machines, all pages that are used for the
1282  * mmu have to be fixed up. According to Motorola, pages holding mmu
1283  * tables should be non-cacheable on a '040 and write-through on a
1284  * '060. But analysis of the reasons for this, and practical
1285  * experience, showed that write-through also works on a '040.
1286  *
1287  * Allocated memory so far goes from kernel_end to memory_start that
1288  * is used for all kind of tables, for that the cache attributes
1289  * are now fixed.
1290  */
1291 L(mmu_fixup):
1292
1293         is_not_040_or_060(L(mmu_fixup_done))
1294
1295 #ifdef MMU_NOCACHE_KERNEL
1296         jbra    L(mmu_fixup_done)
1297 #endif
1298
1299         /* first fix the page at the start of the kernel, that
1300          * contains also kernel_pg_dir.
1301          */
1302         movel   %pc@(L(phys_kernel_start)),%d0
1303         subl    #PAGE_OFFSET,%d0
1304         lea     %pc@(_stext),%a0
1305         subl    %d0,%a0
1306         mmu_fixup_page_mmu_cache        %a0
1307
1308         movel   %pc@(L(kernel_end)),%a0
1309         subl    %d0,%a0
1310         movel   %pc@(L(memory_start)),%a1
1311         subl    %d0,%a1
1312         bra     2f
1313 1:
1314         mmu_fixup_page_mmu_cache        %a0
1315         addw    #PAGESIZE,%a0
1316 2:
1317         cmpl    %a0,%a1
1318         jgt     1b
1319
1320 L(mmu_fixup_done):
1321
1322 #ifdef MMU_PRINT
1323         mmu_print
1324 #endif
1325
1326 /*
1327  * mmu_engage
1328  *
1329  * This chunk of code performs the gruesome task of engaging the MMU.
1330  * The reason its gruesome is because when the MMU becomes engaged it
1331  * maps logical addresses to physical addresses.  The Program Counter
1332  * register is then passed through the MMU before the next instruction
1333  * is fetched (the instruction following the engage MMU instruction).
1334  * This may mean one of two things:
1335  * 1. The Program Counter falls within the logical address space of
1336  *    the kernel of which there are two sub-possibilities:
1337  *    A. The PC maps to the correct instruction (logical PC == physical
1338  *       code location), or
1339  *    B. The PC does not map through and the processor will read some
1340  *       data (or instruction) which is not the logically next instr.
1341  *    As you can imagine, A is good and B is bad.
1342  * Alternatively,
1343  * 2. The Program Counter does not map through the MMU.  The processor
1344  *    will take a Bus Error.
1345  * Clearly, 2 is bad.
1346  * It doesn't take a wiz kid to figure you want 1.A.
1347  * This code creates that possibility.
1348  * There are two possible 1.A. states (we now ignore the other above states):
1349  * A. The kernel is located at physical memory addressed the same as
1350  *    the logical memory for the kernel, i.e., 0x01000.
1351  * B. The kernel is located some where else.  e.g., 0x0400.0000
1352  *
1353  *    Under some conditions the Macintosh can look like A or B.
1354  * [A friend and I once noted that Apple hardware engineers should be
1355  * wacked twice each day: once when they show up at work (as in, Whack!,
1356  * "This is for the screwy hardware we know you're going to design today."),
1357  * and also at the end of the day (as in, Whack! "I don't know what
1358  * you designed today, but I'm sure it wasn't good."). -- rst]
1359  *
1360  * This code works on the following premise:
1361  * If the kernel start (%d5) is within the first 16 Meg of RAM,
1362  * then create a mapping for the kernel at logical 0x8000.0000 to
1363  * the physical location of the pc.  And, create a transparent
1364  * translation register for the first 16 Meg.  Then, after the MMU
1365  * is engaged, the PC can be moved up into the 0x8000.0000 range
1366  * and then the transparent translation can be turned off and then
1367  * the PC can jump to the correct logical location and it will be
1368  * home (finally).  This is essentially the code that the Amiga used
1369  * to use.  Now, it's generalized for all processors.  Which means
1370  * that a fresh (but temporary) mapping has to be created.  The mapping
1371  * is made in page 0 (an as of yet unused location -- except for the
1372  * stack!).  This temporary mapping will only require 1 pointer table
1373  * and a single page table (it can map 256K).
1374  *
1375  * OK, alternatively, imagine that the Program Counter is not within
1376  * the first 16 Meg.  Then, just use Transparent Translation registers
1377  * to do the right thing.
1378  *
1379  * Last, if _start is already at 0x01000, then there's nothing special
1380  * to do (in other words, in a degenerate case of the first case above,
1381  * do nothing).
1382  *
1383  * Let's do it.
1384  *
1385  *
1386  */
1387
1388         putc    'H'
1389
1390         mmu_engage
1391
1392 /*
1393  * After this point no new memory is allocated and
1394  * the start of available memory is stored in availmem.
1395  * (The bootmem allocator requires now the physicall address.)
1396  */
1397
1398         movel   L(memory_start),availmem
1399
1400 #ifdef CONFIG_AMIGA
1401         is_not_amiga(1f)
1402         /* fixup the Amiga custom register location before printing */
1403         clrl    L(custom)
1404 1:
1405 #endif
1406
1407 #ifdef CONFIG_ATARI
1408         is_not_atari(1f)
1409         /* fixup the Atari iobase register location before printing */
1410         movel   #0xff000000,L(iobase)
1411 1:
1412 #endif
1413
1414 #ifdef CONFIG_MAC
1415         is_not_mac(1f)
1416         movel   #~VIDEOMEMMASK,%d0
1417         andl    L(mac_videobase),%d0
1418         addl    #VIDEOMEMBASE,%d0
1419         movel   %d0,L(mac_videobase)
1420 #if defined(CONSOLE)
1421         movel   %pc@(L(phys_kernel_start)),%d0
1422         subl    #PAGE_OFFSET,%d0
1423         subl    %d0,L(console_font)
1424         subl    %d0,L(console_font_data)
1425 #endif
1426 #ifdef SERIAL_DEBUG
1427         orl     #0x50000000,L(mac_sccbase)
1428 #endif
1429 1:
1430 #endif
1431
1432 #ifdef CONFIG_HP300
1433         is_not_hp300(2f)
1434         /*
1435          * Fix up the iobase register to point to the new location of the LEDs.
1436          */
1437         movel   #0xf0000000,L(iobase)
1438
1439         /*
1440          * Energise the FPU and caches.
1441          */
1442         is_040(1f)
1443         movel   #0x60,0xf05f400c
1444         jbra    2f
1445
1446         /*
1447          * 040: slightly different, apparently.
1448          */
1449 1:      movew   #0,0xf05f400e
1450         movew   #0x64,0xf05f400e
1451 2:
1452 #endif
1453
1454 #ifdef CONFIG_SUN3X
1455         is_not_sun3x(1f)
1456
1457         /* enable copro */
1458         oriw    #0x4000,0x61000000
1459 1:
1460 #endif
1461
1462 #ifdef CONFIG_APOLLO
1463         is_not_apollo(1f)
1464
1465         /*
1466          * Fix up the iobase before printing
1467          */
1468         movel   #0x80000000,L(iobase)
1469 1:
1470 #endif
1471
1472         putc    'I'
1473         leds    0x10
1474
1475 /*
1476  * Enable caches
1477  */
1478
1479         is_not_040_or_060(L(cache_not_680460))
1480
1481 L(cache680460):
1482         .chip   68040
1483         nop
1484         cpusha  %bc
1485         nop
1486
1487         is_060(L(cache68060))
1488
1489         movel   #CC6_ENABLE_D+CC6_ENABLE_I,%d0
1490         /* MMU stuff works in copyback mode now, so enable the cache */
1491         movec   %d0,%cacr
1492         jra     L(cache_done)
1493
1494 L(cache68060):
1495         movel   #CC6_ENABLE_D+CC6_ENABLE_I+CC6_ENABLE_SB+CC6_PUSH_DPI+CC6_ENABLE_B+CC6_CLRA_B,%d0
1496         /* MMU stuff works in copyback mode now, so enable the cache */
1497         movec   %d0,%cacr
1498         /* enable superscalar dispatch in PCR */
1499         moveq   #1,%d0
1500         .chip   68060
1501         movec   %d0,%pcr
1502
1503         jbra    L(cache_done)
1504 L(cache_not_680460):
1505 L(cache68030):
1506         .chip   68030
1507         movel   #CC3_ENABLE_DB+CC3_CLR_D+CC3_ENABLE_D+CC3_ENABLE_IB+CC3_CLR_I+CC3_ENABLE_I,%d0
1508         movec   %d0,%cacr
1509
1510         jra     L(cache_done)
1511         .chip   68k
1512 L(cache_done):
1513
1514         putc    'J'
1515
1516 /*
1517  * Setup initial stack pointer
1518  */
1519         lea     init_task,%curptr
1520         lea     init_thread_union+THREAD_SIZE,%sp
1521
1522         putc    'K'
1523
1524         subl    %a6,%a6         /* clear a6 for gdb */
1525
1526 /*
1527  * The new 64bit printf support requires an early exception initialization.
1528  */
1529         jbsr    base_trap_init
1530
1531 /* jump to the kernel start */
1532
1533         putc    '\n'
1534         leds    0x55
1535
1536         jbsr    start_kernel
1537
1538 /*
1539  * Find a tag record in the bootinfo structure
1540  * The bootinfo structure is located right after the kernel
1541  * Returns: d0: size (-1 if not found)
1542  *          a0: data pointer (end-of-records if not found)
1543  */
1544 func_start      get_bi_record,%d1
1545
1546         movel   ARG1,%d0
1547         lea     %pc@(_end),%a0
1548 1:      tstw    %a0@(BIR_TAG)
1549         jeq     3f
1550         cmpw    %a0@(BIR_TAG),%d0
1551         jeq     2f
1552         addw    %a0@(BIR_SIZE),%a0
1553         jra     1b
1554 2:      moveq   #0,%d0
1555         movew   %a0@(BIR_SIZE),%d0
1556         lea     %a0@(BIR_DATA),%a0
1557         jra     4f
1558 3:      moveq   #-1,%d0
1559         lea     %a0@(BIR_SIZE),%a0
1560 4:
1561 func_return     get_bi_record
1562
1563
1564 /*
1565  *      MMU Initialization Begins Here
1566  *
1567  *      The structure of the MMU tables on the 68k machines
1568  *      is thus:
1569  *      Root Table
1570  *              Logical addresses are translated through
1571  *      a hierarchical translation mechanism where the high-order
1572  *      seven bits of the logical address (LA) are used as an
1573  *      index into the "root table."  Each entry in the root
1574  *      table has a bit which specifies if it's a valid pointer to a
1575  *      pointer table.  Each entry defines a 32KMeg range of memory.
1576  *      If an entry is invalid then that logical range of 32M is
1577  *      invalid and references to that range of memory (when the MMU
1578  *      is enabled) will fault.  If the entry is valid, then it does
1579  *      one of two things.  On 040/060 class machines, it points to
1580  *      a pointer table which then describes more finely the memory
1581  *      within that 32M range.  On 020/030 class machines, a technique
1582  *      called "early terminating descriptors" are used.  This technique
1583  *      allows an entire 32Meg to be described by a single entry in the
1584  *      root table.  Thus, this entry in the root table, contains the
1585  *      physical address of the memory or I/O at the logical address
1586  *      which the entry represents and it also contains the necessary
1587  *      cache bits for this region.
1588  *
1589  *      Pointer Tables
1590  *              Per the Root Table, there will be one or more
1591  *      pointer tables.  Each pointer table defines a 32M range.
1592  *      Not all of the 32M range need be defined.  Again, the next
1593  *      seven bits of the logical address are used an index into
1594  *      the pointer table to point to page tables (if the pointer
1595  *      is valid).  There will undoubtedly be more than one
1596  *      pointer table for the kernel because each pointer table
1597  *      defines a range of only 32M.  Valid pointer table entries
1598  *      point to page tables, or are early terminating entries
1599  *      themselves.
1600  *
1601  *      Page Tables
1602  *              Per the Pointer Tables, each page table entry points
1603  *      to the physical page in memory that supports the logical
1604  *      address that translates to the particular index.
1605  *
1606  *      In short, the Logical Address gets translated as follows:
1607  *              bits 31..26 - index into the Root Table
1608  *              bits 25..18 - index into the Pointer Table
1609  *              bits 17..12 - index into the Page Table
1610  *              bits 11..0  - offset into a particular 4K page
1611  *
1612  *      The algorithms which follows do one thing: they abstract
1613  *      the MMU hardware.  For example, there are three kinds of
1614  *      cache settings that are relevant.  Either, memory is
1615  *      being mapped in which case it is either Kernel Code (or
1616  *      the RamDisk) or it is MMU data.  On the 030, the MMU data
1617  *      option also describes the kernel.  Or, I/O is being mapped
1618  *      in which case it has its own kind of cache bits.  There
1619  *      are constants which abstract these notions from the code that
1620  *      actually makes the call to map some range of memory.
1621  *
1622  *
1623  *
1624  */
1625
1626 #ifdef MMU_PRINT
1627 /*
1628  *      mmu_print
1629  *
1630  *      This algorithm will print out the current MMU mappings.
1631  *
1632  *      Input:
1633  *              %a5 points to the root table.  Everything else is calculated
1634  *                      from this.
1635  */
1636
1637 #define mmu_next_valid          0
1638 #define mmu_start_logical       4
1639 #define mmu_next_logical        8
1640 #define mmu_start_physical      12
1641 #define mmu_next_physical       16
1642
1643 #define MMU_PRINT_INVALID               -1
1644 #define MMU_PRINT_VALID                 1
1645 #define MMU_PRINT_UNINITED              0
1646
1647 #define putZc(z,n)              jbne 1f; putc z; jbra 2f; 1: putc n; 2:
1648
1649 func_start      mmu_print,%a0-%a6/%d0-%d7
1650
1651         movel   %pc@(L(kernel_pgdir_ptr)),%a5
1652         lea     %pc@(L(mmu_print_data)),%a0
1653         movel   #MMU_PRINT_UNINITED,%a0@(mmu_next_valid)
1654
1655         is_not_040_or_060(mmu_030_print)
1656
1657 mmu_040_print:
1658         puts    "\nMMU040\n"
1659         puts    "rp:"
1660         putn    %a5
1661         putc    '\n'
1662 #if 0
1663         /*
1664          * The following #if/#endif block is a tight algorithm for dumping the 040
1665          * MMU Map in gory detail.  It really isn't that practical unless the
1666          * MMU Map algorithm appears to go awry and you need to debug it at the
1667          * entry per entry level.
1668          */
1669         movel   #ROOT_TABLE_SIZE,%d5
1670 #if 0
1671         movel   %a5@+,%d7               | Burn an entry to skip the kernel mappings,
1672         subql   #1,%d5                  | they (might) work
1673 #endif
1674 1:      tstl    %d5
1675         jbeq    mmu_print_done
1676         subq    #1,%d5
1677         movel   %a5@+,%d7
1678         btst    #1,%d7
1679         jbeq    1b
1680
1681 2:      putn    %d7
1682         andil   #0xFFFFFE00,%d7
1683         movel   %d7,%a4
1684         movel   #PTR_TABLE_SIZE,%d4
1685         putc    ' '
1686 3:      tstl    %d4
1687         jbeq    11f
1688         subq    #1,%d4
1689         movel   %a4@+,%d7
1690         btst    #1,%d7
1691         jbeq    3b
1692
1693 4:      putn    %d7
1694         andil   #0xFFFFFF00,%d7
1695         movel   %d7,%a3
1696         movel   #PAGE_TABLE_SIZE,%d3
1697 5:      movel   #8,%d2
1698 6:      tstl    %d3
1699         jbeq    31f
1700         subq    #1,%d3
1701         movel   %a3@+,%d6
1702         btst    #0,%d6
1703         jbeq    6b
1704 7:      tstl    %d2
1705         jbeq    8f
1706         subq    #1,%d2
1707         putc    ' '
1708         jbra    91f
1709 8:      putc    '\n'
1710         movel   #8+1+8+1+1,%d2
1711 9:      putc    ' '
1712         dbra    %d2,9b
1713         movel   #7,%d2
1714 91:     putn    %d6
1715         jbra    6b
1716
1717 31:     putc    '\n'
1718         movel   #8+1,%d2
1719 32:     putc    ' '
1720         dbra    %d2,32b
1721         jbra    3b
1722
1723 11:     putc    '\n'
1724         jbra    1b
1725 #endif /* MMU 040 Dumping code that's gory and detailed */
1726
1727         lea     %pc@(kernel_pg_dir),%a5
1728         movel   %a5,%a0                 /* a0 has the address of the root table ptr */
1729         movel   #0x00000000,%a4         /* logical address */
1730         moveql  #0,%d0
1731 40:
1732         /* Increment the logical address and preserve in d5 */
1733         movel   %a4,%d5
1734         addil   #PAGESIZE<<13,%d5
1735         movel   %a0@+,%d6
1736         btst    #1,%d6
1737         jbne    41f
1738         jbsr    mmu_print_tuple_invalidate
1739         jbra    48f
1740 41:
1741         movel   #0,%d1
1742         andil   #0xfffffe00,%d6
1743         movel   %d6,%a1
1744 42:
1745         movel   %a4,%d5
1746         addil   #PAGESIZE<<6,%d5
1747         movel   %a1@+,%d6
1748         btst    #1,%d6
1749         jbne    43f
1750         jbsr    mmu_print_tuple_invalidate
1751         jbra    47f
1752 43:
1753         movel   #0,%d2
1754         andil   #0xffffff00,%d6
1755         movel   %d6,%a2
1756 44:
1757         movel   %a4,%d5
1758         addil   #PAGESIZE,%d5
1759         movel   %a2@+,%d6
1760         btst    #0,%d6
1761         jbne    45f
1762         jbsr    mmu_print_tuple_invalidate
1763         jbra    46f
1764 45:
1765         moveml  %d0-%d1,%sp@-
1766         movel   %a4,%d0
1767         movel   %d6,%d1
1768         andil   #0xfffff4e0,%d1
1769         lea     %pc@(mmu_040_print_flags),%a6
1770         jbsr    mmu_print_tuple
1771         moveml  %sp@+,%d0-%d1
1772 46:
1773         movel   %d5,%a4
1774         addq    #1,%d2
1775         cmpib   #64,%d2
1776         jbne    44b
1777 47:
1778         movel   %d5,%a4
1779         addq    #1,%d1
1780         cmpib   #128,%d1
1781         jbne    42b
1782 48:
1783         movel   %d5,%a4                 /* move to the next logical address */
1784         addq    #1,%d0
1785         cmpib   #128,%d0
1786         jbne    40b
1787
1788         .chip   68040
1789         movec   %dtt1,%d0
1790         movel   %d0,%d1
1791         andiw   #0x8000,%d1             /* is it valid ? */
1792         jbeq    1f                      /* No, bail out */
1793
1794         movel   %d0,%d1
1795         andil   #0xff000000,%d1         /* Get the address */
1796         putn    %d1
1797         puts    "=="
1798         putn    %d1
1799
1800         movel   %d0,%d6
1801         jbsr    mmu_040_print_flags_tt
1802 1:
1803         movec   %dtt0,%d0
1804         movel   %d0,%d1
1805         andiw   #0x8000,%d1             /* is it valid ? */
1806         jbeq    1f                      /* No, bail out */
1807
1808         movel   %d0,%d1
1809         andil   #0xff000000,%d1         /* Get the address */
1810         putn    %d1
1811         puts    "=="
1812         putn    %d1
1813
1814         movel   %d0,%d6
1815         jbsr    mmu_040_print_flags_tt
1816 1:
1817         .chip   68k
1818
1819         jbra    mmu_print_done
1820
1821 mmu_040_print_flags:
1822         btstl   #10,%d6
1823         putZc(' ','G')  /* global bit */
1824         btstl   #7,%d6
1825         putZc(' ','S')  /* supervisor bit */
1826 mmu_040_print_flags_tt:
1827         btstl   #6,%d6
1828         jbne    3f
1829         putc    'C'
1830         btstl   #5,%d6
1831         putZc('w','c')  /* write through or copy-back */
1832         jbra    4f
1833 3:
1834         putc    'N'
1835         btstl   #5,%d6
1836         putZc('s',' ')  /* serialized non-cacheable, or non-cacheable */
1837 4:
1838         rts
1839
1840 mmu_030_print_flags:
1841         btstl   #6,%d6
1842         putZc('C','I')  /* write through or copy-back */
1843         rts
1844
1845 mmu_030_print:
1846         puts    "\nMMU030\n"
1847         puts    "\nrp:"
1848         putn    %a5
1849         putc    '\n'
1850         movel   %a5,%d0
1851         andil   #0xfffffff0,%d0
1852         movel   %d0,%a0
1853         movel   #0x00000000,%a4         /* logical address */
1854         movel   #0,%d0
1855 30:
1856         movel   %a4,%d5
1857         addil   #PAGESIZE<<13,%d5
1858         movel   %a0@+,%d6
1859         btst    #1,%d6                  /* is it a table ptr? */
1860         jbne    31f                     /* yes */
1861         btst    #0,%d6                  /* is it early terminating? */
1862         jbeq    1f                      /* no */
1863         jbsr    mmu_030_print_helper
1864         jbra    38f
1865 1:
1866         jbsr    mmu_print_tuple_invalidate
1867         jbra    38f
1868 31:
1869         movel   #0,%d1
1870         andil   #0xfffffff0,%d6
1871         movel   %d6,%a1
1872 32:
1873         movel   %a4,%d5
1874         addil   #PAGESIZE<<6,%d5
1875         movel   %a1@+,%d6
1876         btst    #1,%d6                  /* is it a table ptr? */
1877         jbne    33f                     /* yes */
1878         btst    #0,%d6                  /* is it a page descriptor? */
1879         jbeq    1f                      /* no */
1880         jbsr    mmu_030_print_helper
1881         jbra    37f
1882 1:
1883         jbsr    mmu_print_tuple_invalidate
1884         jbra    37f
1885 33:
1886         movel   #0,%d2
1887         andil   #0xfffffff0,%d6
1888         movel   %d6,%a2
1889 34:
1890         movel   %a4,%d5
1891         addil   #PAGESIZE,%d5
1892         movel   %a2@+,%d6
1893         btst    #0,%d6
1894         jbne    35f
1895         jbsr    mmu_print_tuple_invalidate
1896         jbra    36f
1897 35:
1898         jbsr    mmu_030_print_helper
1899 36:
1900         movel   %d5,%a4
1901         addq    #1,%d2
1902         cmpib   #64,%d2
1903         jbne    34b
1904 37:
1905         movel   %d5,%a4
1906         addq    #1,%d1
1907         cmpib   #128,%d1
1908         jbne    32b
1909 38:
1910         movel   %d5,%a4                 /* move to the next logical address */
1911         addq    #1,%d0
1912         cmpib   #128,%d0
1913         jbne    30b
1914
1915 mmu_print_done:
1916         puts    "\n"
1917
1918 func_return     mmu_print
1919
1920
1921 mmu_030_print_helper:
1922         moveml  %d0-%d1,%sp@-
1923         movel   %a4,%d0
1924         movel   %d6,%d1
1925         lea     %pc@(mmu_030_print_flags),%a6
1926         jbsr    mmu_print_tuple
1927         moveml  %sp@+,%d0-%d1
1928         rts
1929
1930 mmu_print_tuple_invalidate:
1931         moveml  %a0/%d7,%sp@-
1932
1933         lea     %pc@(L(mmu_print_data)),%a0
1934         tstl    %a0@(mmu_next_valid)
1935         jbmi    mmu_print_tuple_invalidate_exit
1936
1937         movel   #MMU_PRINT_INVALID,%a0@(mmu_next_valid)
1938
1939         putn    %a4
1940
1941         puts    "##\n"
1942
1943 mmu_print_tuple_invalidate_exit:
1944         moveml  %sp@+,%a0/%d7
1945         rts
1946
1947
1948 mmu_print_tuple:
1949         moveml  %d0-%d7/%a0,%sp@-
1950
1951         lea     %pc@(L(mmu_print_data)),%a0
1952
1953         tstl    %a0@(mmu_next_valid)
1954         jble    mmu_print_tuple_print
1955
1956         cmpl    %a0@(mmu_next_physical),%d1
1957         jbeq    mmu_print_tuple_increment
1958
1959 mmu_print_tuple_print:
1960         putn    %d0
1961         puts    "->"
1962         putn    %d1
1963
1964         movel   %d1,%d6
1965         jbsr    %a6@
1966
1967 mmu_print_tuple_record:
1968         movel   #MMU_PRINT_VALID,%a0@(mmu_next_valid)
1969
1970         movel   %d1,%a0@(mmu_next_physical)
1971
1972 mmu_print_tuple_increment:
1973         movel   %d5,%d7
1974         subl    %a4,%d7
1975         addl    %d7,%a0@(mmu_next_physical)
1976
1977 mmu_print_tuple_exit:
1978         moveml  %sp@+,%d0-%d7/%a0
1979         rts
1980
1981 mmu_print_machine_cpu_types:
1982         puts    "machine: "
1983
1984         is_not_amiga(1f)
1985         puts    "amiga"
1986         jbra    9f
1987 1:
1988         is_not_atari(2f)
1989         puts    "atari"
1990         jbra    9f
1991 2:
1992         is_not_mac(3f)
1993         puts    "macintosh"
1994         jbra    9f
1995 3:      puts    "unknown"
1996 9:      putc    '\n'
1997
1998         puts    "cputype: 0"
1999         is_not_060(1f)
2000         putc    '6'
2001         jbra    9f
2002 1:
2003         is_not_040_or_060(2f)
2004         putc    '4'
2005         jbra    9f
2006 2:      putc    '3'
2007 9:      putc    '0'
2008         putc    '\n'
2009
2010         rts
2011 #endif /* MMU_PRINT */
2012
2013 /*
2014  * mmu_map_tt
2015  *
2016  * This is a specific function which works on all 680x0 machines.
2017  * On 030, 040 & 060 it will attempt to use Transparent Translation
2018  * registers (tt1).
2019  * On 020 it will call the standard mmu_map which will use early
2020  * terminating descriptors.
2021  */
2022 func_start      mmu_map_tt,%d0/%d1/%a0,4
2023
2024         dputs   "mmu_map_tt:"
2025         dputn   ARG1
2026         dputn   ARG2
2027         dputn   ARG3
2028         dputn   ARG4
2029         dputc   '\n'
2030
2031         is_020(L(do_map))
2032
2033         /* Extract the highest bit set
2034          */
2035         bfffo   ARG3{#0,#32},%d1
2036         cmpw    #8,%d1
2037         jcc     L(do_map)
2038
2039         /* And get the mask
2040          */
2041         moveq   #-1,%d0
2042         lsrl    %d1,%d0
2043         lsrl    #1,%d0
2044
2045         /* Mask the address
2046          */
2047         movel   %d0,%d1
2048         notl    %d1
2049         andl    ARG2,%d1
2050
2051         /* Generate the upper 16bit of the tt register
2052          */
2053         lsrl    #8,%d0
2054         orl     %d0,%d1
2055         clrw    %d1
2056
2057         is_040_or_060(L(mmu_map_tt_040))
2058
2059         /* set 030 specific bits (read/write access for supervisor mode
2060          * (highest function code set, lower two bits masked))
2061          */
2062         orw     #TTR_ENABLE+TTR_RWM+TTR_FCB2+TTR_FCM1+TTR_FCM0,%d1
2063         movel   ARG4,%d0
2064         btst    #6,%d0
2065         jeq     1f
2066         orw     #TTR_CI,%d1
2067
2068 1:      lea     STACK,%a0
2069         dputn   %d1
2070         movel   %d1,%a0@
2071         .chip   68030
2072         tstl    ARG1
2073         jne     1f
2074         pmove   %a0@,%tt0
2075         jra     2f
2076 1:      pmove   %a0@,%tt1
2077 2:      .chip   68k
2078         jra     L(mmu_map_tt_done)
2079
2080         /* set 040 specific bits
2081          */
2082 L(mmu_map_tt_040):
2083         orw     #TTR_ENABLE+TTR_KERNELMODE,%d1
2084         orl     ARG4,%d1
2085         dputn   %d1
2086
2087         .chip   68040
2088         tstl    ARG1
2089         jne     1f
2090         movec   %d1,%itt0
2091         movec   %d1,%dtt0
2092         jra     2f
2093 1:      movec   %d1,%itt1
2094         movec   %d1,%dtt1
2095 2:      .chip   68k
2096
2097         jra     L(mmu_map_tt_done)
2098
2099 L(do_map):
2100         mmu_map_eq      ARG2,ARG3,ARG4
2101
2102 L(mmu_map_tt_done):
2103
2104 func_return     mmu_map_tt
2105
2106 /*
2107  *      mmu_map
2108  *
2109  *      This routine will map a range of memory using a pointer
2110  *      table and allocating the pages on the fly from the kernel.
2111  *      The pointer table does not have to be already linked into
2112  *      the root table, this routine will do that if necessary.
2113  *
2114  *      NOTE
2115  *      This routine will assert failure and use the serial_putc
2116  *      routines in the case of a run-time error.  For example,
2117  *      if the address is already mapped.
2118  *
2119  *      NOTE-2
2120  *      This routine will use early terminating descriptors
2121  *      where possible for the 68020+68851 and 68030 type
2122  *      processors.
2123  */
2124 func_start      mmu_map,%d0-%d4/%a0-%a4
2125
2126         dputs   "\nmmu_map:"
2127         dputn   ARG1
2128         dputn   ARG2
2129         dputn   ARG3
2130         dputn   ARG4
2131         dputc   '\n'
2132
2133         /* Get logical address and round it down to 256KB
2134          */
2135         movel   ARG1,%d0
2136         andl    #-(PAGESIZE*PAGE_TABLE_SIZE),%d0
2137         movel   %d0,%a3
2138
2139         /* Get the end address
2140          */
2141         movel   ARG1,%a4
2142         addl    ARG3,%a4
2143         subql   #1,%a4
2144
2145         /* Get physical address and round it down to 256KB
2146          */
2147         movel   ARG2,%d0
2148         andl    #-(PAGESIZE*PAGE_TABLE_SIZE),%d0
2149         movel   %d0,%a2
2150
2151         /* Add page attributes to the physical address
2152          */
2153         movel   ARG4,%d0
2154         orw     #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
2155         addw    %d0,%a2
2156
2157         dputn   %a2
2158         dputn   %a3
2159         dputn   %a4
2160
2161         is_not_040_or_060(L(mmu_map_030))
2162
2163         addw    #_PAGE_GLOBAL040,%a2
2164 /*
2165  *      MMU 040 & 060 Support
2166  *
2167  *      The MMU usage for the 040 and 060 is different enough from
2168  *      the 030 and 68851 that there is separate code.  This comment
2169  *      block describes the data structures and algorithms built by
2170  *      this code.
2171  *
2172  *      The 040 does not support early terminating descriptors, as
2173  *      the 030 does.  Therefore, a third level of table is needed
2174  *      for the 040, and that would be the page table.  In Linux,
2175  *      page tables are allocated directly from the memory above the
2176  *      kernel.
2177  *
2178  */
2179
2180 L(mmu_map_040):
2181         /* Calculate the offset into the root table
2182          */
2183         movel   %a3,%d0
2184         moveq   #ROOT_INDEX_SHIFT,%d1
2185         lsrl    %d1,%d0
2186         mmu_get_root_table_entry        %d0
2187
2188         /* Calculate the offset into the pointer table
2189          */
2190         movel   %a3,%d0
2191         moveq   #PTR_INDEX_SHIFT,%d1
2192         lsrl    %d1,%d0
2193         andl    #PTR_TABLE_SIZE-1,%d0
2194         mmu_get_ptr_table_entry         %a0,%d0
2195
2196         /* Calculate the offset into the page table
2197          */
2198         movel   %a3,%d0
2199         moveq   #PAGE_INDEX_SHIFT,%d1
2200         lsrl    %d1,%d0
2201         andl    #PAGE_TABLE_SIZE-1,%d0
2202         mmu_get_page_table_entry        %a0,%d0
2203
2204         /* The page table entry must not no be busy
2205          */
2206         tstl    %a0@
2207         jne     L(mmu_map_error)
2208
2209         /* Do the mapping and advance the pointers
2210          */
2211         movel   %a2,%a0@
2212 2:
2213         addw    #PAGESIZE,%a2
2214         addw    #PAGESIZE,%a3
2215
2216         /* Ready with mapping?
2217          */
2218         lea     %a3@(-1),%a0
2219         cmpl    %a0,%a4
2220         jhi     L(mmu_map_040)
2221         jra     L(mmu_map_done)
2222
2223 L(mmu_map_030):
2224         /* Calculate the offset into the root table
2225          */
2226         movel   %a3,%d0
2227         moveq   #ROOT_INDEX_SHIFT,%d1
2228         lsrl    %d1,%d0
2229         mmu_get_root_table_entry        %d0
2230
2231         /* Check if logical address 32MB aligned,
2232          * so we can try to map it once
2233          */
2234         movel   %a3,%d0
2235         andl    #(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1)&(-ROOT_TABLE_SIZE),%d0
2236         jne     1f
2237
2238         /* Is there enough to map for 32MB at once
2239          */
2240         lea     %a3@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1),%a1
2241         cmpl    %a1,%a4
2242         jcs     1f
2243
2244         addql   #1,%a1
2245
2246         /* The root table entry must not no be busy
2247          */
2248         tstl    %a0@
2249         jne     L(mmu_map_error)
2250
2251         /* Do the mapping and advance the pointers
2252          */
2253         dputs   "early term1"
2254         dputn   %a2
2255         dputn   %a3
2256         dputn   %a1
2257         dputc   '\n'
2258         movel   %a2,%a0@
2259
2260         movel   %a1,%a3
2261         lea     %a2@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE),%a2
2262         jra     L(mmu_mapnext_030)
2263 1:
2264         /* Calculate the offset into the pointer table
2265          */
2266         movel   %a3,%d0
2267         moveq   #PTR_INDEX_SHIFT,%d1
2268         lsrl    %d1,%d0
2269         andl    #PTR_TABLE_SIZE-1,%d0
2270         mmu_get_ptr_table_entry         %a0,%d0
2271
2272         /* The pointer table entry must not no be busy
2273          */
2274         tstl    %a0@
2275         jne     L(mmu_map_error)
2276
2277         /* Do the mapping and advance the pointers
2278          */
2279         dputs   "early term2"
2280         dputn   %a2
2281         dputn   %a3
2282         dputc   '\n'
2283         movel   %a2,%a0@
2284
2285         addl    #PAGE_TABLE_SIZE*PAGESIZE,%a2
2286         addl    #PAGE_TABLE_SIZE*PAGESIZE,%a3
2287
2288 L(mmu_mapnext_030):
2289         /* Ready with mapping?
2290          */
2291         lea     %a3@(-1),%a0
2292         cmpl    %a0,%a4
2293         jhi     L(mmu_map_030)
2294         jra     L(mmu_map_done)
2295
2296 L(mmu_map_error):
2297
2298         dputs   "mmu_map error:"
2299         dputn   %a2
2300         dputn   %a3
2301         dputc   '\n'
2302
2303 L(mmu_map_done):
2304
2305 func_return     mmu_map
2306
2307 /*
2308  *      mmu_fixup
2309  *
2310  *      On the 040 class machines, all pages that are used for the
2311  *      mmu have to be fixed up.
2312  */
2313
2314 func_start      mmu_fixup_page_mmu_cache,%d0/%a0
2315
2316         dputs   "mmu_fixup_page_mmu_cache"
2317         dputn   ARG1
2318
2319         /* Calculate the offset into the root table
2320          */
2321         movel   ARG1,%d0
2322         moveq   #ROOT_INDEX_SHIFT,%d1
2323         lsrl    %d1,%d0
2324         mmu_get_root_table_entry        %d0
2325
2326         /* Calculate the offset into the pointer table
2327          */
2328         movel   ARG1,%d0
2329         moveq   #PTR_INDEX_SHIFT,%d1
2330         lsrl    %d1,%d0
2331         andl    #PTR_TABLE_SIZE-1,%d0
2332         mmu_get_ptr_table_entry         %a0,%d0
2333
2334         /* Calculate the offset into the page table
2335          */
2336         movel   ARG1,%d0
2337         moveq   #PAGE_INDEX_SHIFT,%d1
2338         lsrl    %d1,%d0
2339         andl    #PAGE_TABLE_SIZE-1,%d0
2340         mmu_get_page_table_entry        %a0,%d0
2341
2342         movel   %a0@,%d0
2343         andil   #_CACHEMASK040,%d0
2344         orl     %pc@(m68k_pgtable_cachemode),%d0
2345         movel   %d0,%a0@
2346
2347         dputc   '\n'
2348
2349 func_return     mmu_fixup_page_mmu_cache
2350
2351 /*
2352  *      mmu_temp_map
2353  *
2354  *      create a temporary mapping to enable the mmu,
2355  *      this we don't need any transparation translation tricks.
2356  */
2357
2358 func_start      mmu_temp_map,%d0/%d1/%a0/%a1
2359
2360         dputs   "mmu_temp_map"
2361         dputn   ARG1
2362         dputn   ARG2
2363         dputc   '\n'
2364
2365         lea     %pc@(L(temp_mmap_mem)),%a1
2366
2367         /* Calculate the offset in the root table
2368          */
2369         movel   ARG2,%d0
2370         moveq   #ROOT_INDEX_SHIFT,%d1
2371         lsrl    %d1,%d0
2372         mmu_get_root_table_entry        %d0
2373
2374         /* Check if the table is temporary allocated, so we have to reuse it
2375          */
2376         movel   %a0@,%d0
2377         cmpl    %pc@(L(memory_start)),%d0
2378         jcc     1f
2379
2380         /* Temporary allocate a ptr table and insert it into the root table
2381          */
2382         movel   %a1@,%d0
2383         addl    #PTR_TABLE_SIZE*4,%a1@
2384         orw     #_PAGE_TABLE+_PAGE_ACCESSED,%d0
2385         movel   %d0,%a0@
2386         dputs   " (new)"
2387 1:
2388         dputn   %d0
2389         /* Mask the root table entry for the ptr table
2390          */
2391         andw    #-ROOT_TABLE_SIZE,%d0
2392         movel   %d0,%a0
2393
2394         /* Calculate the offset into the pointer table
2395          */
2396         movel   ARG2,%d0
2397         moveq   #PTR_INDEX_SHIFT,%d1
2398         lsrl    %d1,%d0
2399         andl    #PTR_TABLE_SIZE-1,%d0
2400         lea     %a0@(%d0*4),%a0
2401         dputn   %a0
2402
2403         /* Check if a temporary page table is already allocated
2404          */
2405         movel   %a0@,%d0
2406         jne     1f
2407
2408         /* Temporary allocate a page table and insert it into the ptr table
2409          */
2410         movel   %a1@,%d0
2411         /* The 512 should be PAGE_TABLE_SIZE*4, but that violates the
2412            alignment restriction for pointer tables on the '0[46]0.  */
2413         addl    #512,%a1@
2414         orw     #_PAGE_TABLE+_PAGE_ACCESSED,%d0
2415         movel   %d0,%a0@
2416         dputs   " (new)"
2417 1:
2418         dputn   %d0
2419         /* Mask the ptr table entry for the page table
2420          */
2421         andw    #-PTR_TABLE_SIZE,%d0
2422         movel   %d0,%a0
2423
2424         /* Calculate the offset into the page table
2425          */
2426         movel   ARG2,%d0
2427         moveq   #PAGE_INDEX_SHIFT,%d1
2428         lsrl    %d1,%d0
2429         andl    #PAGE_TABLE_SIZE-1,%d0
2430         lea     %a0@(%d0*4),%a0
2431         dputn   %a0
2432
2433         /* Insert the address into the page table
2434          */
2435         movel   ARG1,%d0
2436         andw    #-PAGESIZE,%d0
2437         orw     #_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
2438         movel   %d0,%a0@
2439         dputn   %d0
2440
2441         dputc   '\n'
2442
2443 func_return     mmu_temp_map
2444
2445 func_start      mmu_engage,%d0-%d2/%a0-%a3
2446
2447         moveq   #ROOT_TABLE_SIZE-1,%d0
2448         /* Temporarily use a different root table.  */
2449         lea     %pc@(L(kernel_pgdir_ptr)),%a0
2450         movel   %a0@,%a2
2451         movel   %pc@(L(memory_start)),%a1
2452         movel   %a1,%a0@
2453         movel   %a2,%a0
2454 1:
2455         movel   %a0@+,%a1@+
2456         dbra    %d0,1b
2457
2458         lea     %pc@(L(temp_mmap_mem)),%a0
2459         movel   %a1,%a0@
2460
2461         movew   #PAGESIZE-1,%d0
2462 1:
2463         clrl    %a1@+
2464         dbra    %d0,1b
2465
2466         lea     %pc@(1b),%a0
2467         movel   #1b,%a1
2468         /* Skip temp mappings if phys == virt */
2469         cmpl    %a0,%a1
2470         jeq     1f
2471
2472         mmu_temp_map    %a0,%a0
2473         mmu_temp_map    %a0,%a1
2474
2475         addw    #PAGESIZE,%a0
2476         addw    #PAGESIZE,%a1
2477         mmu_temp_map    %a0,%a0
2478         mmu_temp_map    %a0,%a1
2479 1:
2480         movel   %pc@(L(memory_start)),%a3
2481         movel   %pc@(L(phys_kernel_start)),%d2
2482
2483         is_not_040_or_060(L(mmu_engage_030))
2484
2485 L(mmu_engage_040):
2486         .chip   68040
2487         nop
2488         cinva   %bc
2489         nop
2490         pflusha
2491         nop
2492         movec   %a3,%srp
2493         movel   #TC_ENABLE+TC_PAGE4K,%d0
2494         movec   %d0,%tc         /* enable the MMU */
2495         jmp     1f:l
2496 1:      nop
2497         movec   %a2,%srp
2498         nop
2499         cinva   %bc
2500         nop
2501         pflusha
2502         .chip   68k
2503         jra     L(mmu_engage_cleanup)
2504
2505 L(mmu_engage_030_temp):
2506         .space  12
2507 L(mmu_engage_030):
2508         .chip   68030
2509         lea     %pc@(L(mmu_engage_030_temp)),%a0
2510         movel   #0x80000002,%a0@
2511         movel   %a3,%a0@(4)
2512         movel   #0x0808,%d0
2513         movec   %d0,%cacr
2514         pmove   %a0@,%srp
2515         pflusha
2516         /*
2517          * enable,super root enable,4096 byte pages,7 bit root index,
2518          * 7 bit pointer index, 6 bit page table index.
2519          */
2520         movel   #0x82c07760,%a0@(8)
2521         pmove   %a0@(8),%tc     /* enable the MMU */
2522         jmp     1f:l
2523 1:      movel   %a2,%a0@(4)
2524         movel   #0x0808,%d0
2525         movec   %d0,%cacr
2526         pmove   %a0@,%srp
2527         pflusha
2528         .chip   68k
2529
2530 L(mmu_engage_cleanup):
2531         subl    #PAGE_OFFSET,%d2
2532         subl    %d2,%a2
2533         movel   %a2,L(kernel_pgdir_ptr)
2534         subl    %d2,%fp
2535         subl    %d2,%sp
2536         subl    %d2,ARG0
2537
2538 func_return     mmu_engage
2539
2540 func_start      mmu_get_root_table_entry,%d0/%a1
2541
2542 #if 0
2543         dputs   "mmu_get_root_table_entry:"
2544         dputn   ARG1
2545         dputs   " ="
2546 #endif
2547
2548         movel   %pc@(L(kernel_pgdir_ptr)),%a0
2549         tstl    %a0
2550         jne     2f
2551
2552         dputs   "\nmmu_init:"
2553
2554         /* Find the start of free memory, get_bi_record does this for us,
2555          * as the bootinfo structure is located directly behind the kernel
2556          * and and we simply search for the last entry.
2557          */
2558         get_bi_record   BI_LAST
2559         addw    #PAGESIZE-1,%a0
2560         movel   %a0,%d0
2561         andw    #-PAGESIZE,%d0
2562
2563         dputn   %d0
2564
2565         lea     %pc@(L(memory_start)),%a0
2566         movel   %d0,%a0@
2567         lea     %pc@(L(kernel_end)),%a0
2568         movel   %d0,%a0@
2569
2570         /* we have to return the first page at _stext since the init code
2571          * in mm/init.c simply expects kernel_pg_dir there, the rest of
2572          * page is used for further ptr tables in get_ptr_table.
2573          */
2574         lea     %pc@(_stext),%a0
2575         lea     %pc@(L(mmu_cached_pointer_tables)),%a1
2576         movel   %a0,%a1@
2577         addl    #ROOT_TABLE_SIZE*4,%a1@
2578
2579         lea     %pc@(L(mmu_num_pointer_tables)),%a1
2580         addql   #1,%a1@
2581
2582         /* clear the page
2583          */
2584         movel   %a0,%a1
2585         movew   #PAGESIZE/4-1,%d0
2586 1:
2587         clrl    %a1@+
2588         dbra    %d0,1b
2589
2590         lea     %pc@(L(kernel_pgdir_ptr)),%a1
2591         movel   %a0,%a1@
2592
2593         dputn   %a0
2594         dputc   '\n'
2595 2:
2596         movel   ARG1,%d0
2597         lea     %a0@(%d0*4),%a0
2598
2599 #if 0
2600         dputn   %a0
2601         dputc   '\n'
2602 #endif
2603
2604 func_return     mmu_get_root_table_entry
2605
2606
2607
2608 func_start      mmu_get_ptr_table_entry,%d0/%a1
2609
2610 #if 0
2611         dputs   "mmu_get_ptr_table_entry:"
2612         dputn   ARG1
2613         dputn   ARG2
2614         dputs   " ="
2615 #endif
2616
2617         movel   ARG1,%a0
2618         movel   %a0@,%d0
2619         jne     2f
2620
2621         /* Keep track of the number of pointer tables we use
2622          */
2623         dputs   "\nmmu_get_new_ptr_table:"
2624         lea     %pc@(L(mmu_num_pointer_tables)),%a0
2625         movel   %a0@,%d0
2626         addql   #1,%a0@
2627
2628         /* See if there is a free pointer table in our cache of pointer tables
2629          */
2630         lea     %pc@(L(mmu_cached_pointer_tables)),%a1
2631         andw    #7,%d0
2632         jne     1f
2633
2634         /* Get a new pointer table page from above the kernel memory
2635          */
2636         get_new_page
2637         movel   %a0,%a1@
2638 1:
2639         /* There is an unused pointer table in our cache... use it
2640          */
2641         movel   %a1@,%d0
2642         addl    #PTR_TABLE_SIZE*4,%a1@
2643
2644         dputn   %d0
2645         dputc   '\n'
2646
2647         /* Insert the new pointer table into the root table
2648          */
2649         movel   ARG1,%a0
2650         orw     #_PAGE_TABLE+_PAGE_ACCESSED,%d0
2651         movel   %d0,%a0@
2652 2:
2653         /* Extract the pointer table entry
2654          */
2655         andw    #-PTR_TABLE_SIZE,%d0
2656         movel   %d0,%a0
2657         movel   ARG2,%d0
2658         lea     %a0@(%d0*4),%a0
2659
2660 #if 0
2661         dputn   %a0
2662         dputc   '\n'
2663 #endif
2664
2665 func_return     mmu_get_ptr_table_entry
2666
2667
2668 func_start      mmu_get_page_table_entry,%d0/%a1
2669
2670 #if 0
2671         dputs   "mmu_get_page_table_entry:"
2672         dputn   ARG1
2673         dputn   ARG2
2674         dputs   " ="
2675 #endif
2676
2677         movel   ARG1,%a0
2678         movel   %a0@,%d0
2679         jne     2f
2680
2681         /* If the page table entry doesn't exist, we allocate a complete new
2682          * page and use it as one continues big page table which can cover
2683          * 4MB of memory, nearly almost all mappings have that alignment.
2684          */
2685         get_new_page
2686         addw    #_PAGE_TABLE+_PAGE_ACCESSED,%a0
2687
2688         /* align pointer table entry for a page of page tables
2689          */
2690         movel   ARG1,%d0
2691         andw    #-(PAGESIZE/PAGE_TABLE_SIZE),%d0
2692         movel   %d0,%a1
2693
2694         /* Insert the page tables into the pointer entries
2695          */
2696         moveq   #PAGESIZE/PAGE_TABLE_SIZE/4-1,%d0
2697 1:
2698         movel   %a0,%a1@+
2699         lea     %a0@(PAGE_TABLE_SIZE*4),%a0
2700         dbra    %d0,1b
2701
2702         /* Now we can get the initialized pointer table entry
2703          */
2704         movel   ARG1,%a0
2705         movel   %a0@,%d0
2706 2:
2707         /* Extract the page table entry
2708          */
2709         andw    #-PAGE_TABLE_SIZE,%d0
2710         movel   %d0,%a0
2711         movel   ARG2,%d0
2712         lea     %a0@(%d0*4),%a0
2713
2714 #if 0
2715         dputn   %a0
2716         dputc   '\n'
2717 #endif
2718
2719 func_return     mmu_get_page_table_entry
2720
2721 /*
2722  *      get_new_page
2723  *
2724  *      Return a new page from the memory start and clear it.
2725  */
2726 func_start      get_new_page,%d0/%a1
2727
2728         dputs   "\nget_new_page:"
2729
2730         /* allocate the page and adjust memory_start
2731          */
2732         lea     %pc@(L(memory_start)),%a0
2733         movel   %a0@,%a1
2734         addl    #PAGESIZE,%a0@
2735
2736         /* clear the new page
2737          */
2738         movel   %a1,%a0
2739         movew   #PAGESIZE/4-1,%d0
2740 1:
2741         clrl    %a1@+
2742         dbra    %d0,1b
2743
2744         dputn   %a0
2745         dputc   '\n'
2746
2747 func_return     get_new_page
2748
2749
2750
2751 /*
2752  * Debug output support
2753  * Atarians have a choice between the parallel port, the serial port
2754  * from the MFP or a serial port of the SCC
2755  */
2756
2757 #ifdef CONFIG_MAC
2758
2759 L(scc_initable_mac):
2760         .byte   4,0x44          /* x16, 1 stopbit, no parity */
2761         .byte   3,0xc0          /* receiver: 8 bpc */
2762         .byte   5,0xe2          /* transmitter: 8 bpc, assert dtr/rts */
2763         .byte   10,0            /* NRZ */
2764         .byte   11,0x50         /* use baud rate generator */
2765         .byte   12,1,13,0       /* 38400 baud */
2766         .byte   14,1            /* Baud rate generator enable */
2767         .byte   3,0xc1          /* enable receiver */
2768         .byte   5,0xea          /* enable transmitter */
2769         .byte   -1
2770         .even
2771 #endif
2772
2773 #ifdef CONFIG_ATARI
2774 /* #define USE_PRINTER */
2775 /* #define USE_SCC_B */
2776 /* #define USE_SCC_A */
2777 #define USE_MFP
2778
2779 #if defined(USE_SCC_A) || defined(USE_SCC_B)
2780 #define USE_SCC
2781 /* Initialisation table for SCC */
2782 L(scc_initable):
2783         .byte   9,12            /* Reset */
2784         .byte   4,0x44          /* x16, 1 stopbit, no parity */
2785         .byte   3,0xc0          /* receiver: 8 bpc */
2786         .byte   5,0xe2          /* transmitter: 8 bpc, assert dtr/rts */
2787         .byte   9,0             /* no interrupts */
2788         .byte   10,0            /* NRZ */
2789         .byte   11,0x50         /* use baud rate generator */
2790         .byte   12,24,13,0      /* 9600 baud */
2791         .byte   14,2,14,3       /* use master clock for BRG, enable */
2792         .byte   3,0xc1          /* enable receiver */
2793         .byte   5,0xea          /* enable transmitter */
2794         .byte   -1
2795         .even
2796 #endif
2797
2798 #ifdef USE_PRINTER
2799
2800 LPSG_SELECT     = 0xff8800
2801 LPSG_READ       = 0xff8800
2802 LPSG_WRITE      = 0xff8802
2803 LPSG_IO_A       = 14
2804 LPSG_IO_B       = 15
2805 LPSG_CONTROL    = 7
2806 LSTMFP_GPIP     = 0xfffa01
2807 LSTMFP_DDR      = 0xfffa05
2808 LSTMFP_IERB     = 0xfffa09
2809
2810 #elif defined(USE_SCC_B)
2811
2812 LSCC_CTRL       = 0xff8c85
2813 LSCC_DATA       = 0xff8c87
2814
2815 #elif defined(USE_SCC_A)
2816
2817 LSCC_CTRL       = 0xff8c81
2818 LSCC_DATA       = 0xff8c83
2819
2820 #elif defined(USE_MFP)
2821
2822 LMFP_UCR     = 0xfffa29
2823 LMFP_TDCDR   = 0xfffa1d
2824 LMFP_TDDR    = 0xfffa25
2825 LMFP_TSR     = 0xfffa2d
2826 LMFP_UDR     = 0xfffa2f
2827
2828 #endif
2829 #endif  /* CONFIG_ATARI */
2830
2831 /*
2832  * Serial port output support.
2833  */
2834
2835 /*
2836  * Initialize serial port hardware for 9600/8/1
2837  */
2838 func_start      serial_init,%d0/%d1/%a0/%a1
2839         /*
2840          *      Some of the register usage that follows
2841          *      CONFIG_AMIGA
2842          *              a0 = pointer to boot info record
2843          *              d0 = boot info offset
2844          *      CONFIG_ATARI
2845          *              a0 = address of SCC
2846          *              a1 = Liobase address/address of scc_initable
2847          *              d0 = init data for serial port
2848          *      CONFIG_MAC
2849          *              a0 = address of SCC
2850          *              a1 = address of scc_initable_mac
2851          *              d0 = init data for serial port
2852          */
2853
2854 #ifdef CONFIG_AMIGA
2855 #define SERIAL_DTR      7
2856 #define SERIAL_CNTRL    CIABBASE+C_PRA
2857
2858         is_not_amiga(1f)
2859         lea     %pc@(L(custom)),%a0
2860         movel   #-ZTWOBASE,%a0@
2861         bclr    #SERIAL_DTR,SERIAL_CNTRL-ZTWOBASE
2862         get_bi_record   BI_AMIGA_SERPER
2863         movew   %a0@,CUSTOMBASE+C_SERPER-ZTWOBASE
2864 |       movew   #61,CUSTOMBASE+C_SERPER-ZTWOBASE
2865 1:
2866 #endif
2867 #ifdef CONFIG_ATARI
2868         is_not_atari(4f)
2869         movel   %pc@(L(iobase)),%a1
2870 #if defined(USE_PRINTER)
2871         bclr    #0,%a1@(LSTMFP_IERB)
2872         bclr    #0,%a1@(LSTMFP_DDR)
2873         moveb   #LPSG_CONTROL,%a1@(LPSG_SELECT)
2874         moveb   #0xff,%a1@(LPSG_WRITE)
2875         moveb   #LPSG_IO_B,%a1@(LPSG_SELECT)
2876         clrb    %a1@(LPSG_WRITE)
2877         moveb   #LPSG_IO_A,%a1@(LPSG_SELECT)
2878         moveb   %a1@(LPSG_READ),%d0
2879         bset    #5,%d0
2880         moveb   %d0,%a1@(LPSG_WRITE)
2881 #elif defined(USE_SCC)
2882         lea     %a1@(LSCC_CTRL),%a0
2883         lea     %pc@(L(scc_initable)),%a1
2884 2:      moveb   %a1@+,%d0
2885         jmi     3f
2886         moveb   %d0,%a0@
2887         moveb   %a1@+,%a0@
2888         jra     2b
2889 3:      clrb    %a0@
2890 #elif defined(USE_MFP)
2891         bclr    #1,%a1@(LMFP_TSR)
2892         moveb   #0x88,%a1@(LMFP_UCR)
2893         andb    #0x70,%a1@(LMFP_TDCDR)
2894         moveb   #2,%a1@(LMFP_TDDR)
2895         orb     #1,%a1@(LMFP_TDCDR)
2896         bset    #1,%a1@(LMFP_TSR)
2897 #endif
2898         jra     L(serial_init_done)
2899 4:
2900 #endif
2901 #ifdef CONFIG_MAC
2902         is_not_mac(L(serial_init_not_mac))
2903
2904 #ifdef SERIAL_DEBUG
2905
2906 /* You may define either or both of these. */
2907 #define MAC_USE_SCC_A /* Modem port */
2908 #define MAC_USE_SCC_B /* Printer port */
2909
2910 #define mac_scc_cha_b_ctrl_offset       0x0
2911 #define mac_scc_cha_a_ctrl_offset       0x2
2912 #define mac_scc_cha_b_data_offset       0x4
2913 #define mac_scc_cha_a_data_offset       0x6
2914
2915 #if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
2916         movel   %pc@(L(mac_sccbase)),%a0
2917         /* Reset SCC register pointer */
2918         moveb   %a0@(mac_scc_cha_a_ctrl_offset),%d0
2919         /* Reset SCC device: write register pointer then register value */
2920         moveb   #9,%a0@(mac_scc_cha_a_ctrl_offset)
2921         moveb   #0xc0,%a0@(mac_scc_cha_a_ctrl_offset)
2922         /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */
2923         /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */
2924         movel   #35,%d0
2925 5:
2926         subq    #1,%d0
2927         jne     5b
2928 #endif
2929
2930 #ifdef MAC_USE_SCC_A
2931         /* Initialize channel A */
2932         lea     %pc@(L(scc_initable_mac)),%a1
2933 5:      moveb   %a1@+,%d0
2934         jmi     6f
2935         moveb   %d0,%a0@(mac_scc_cha_a_ctrl_offset)
2936         moveb   %a1@+,%a0@(mac_scc_cha_a_ctrl_offset)
2937         jra     5b
2938 6:
2939 #endif  /* MAC_USE_SCC_A */
2940
2941 #ifdef MAC_USE_SCC_B
2942         /* Initialize channel B */
2943         lea     %pc@(L(scc_initable_mac)),%a1
2944 7:      moveb   %a1@+,%d0
2945         jmi     8f
2946         moveb   %d0,%a0@(mac_scc_cha_b_ctrl_offset)
2947         moveb   %a1@+,%a0@(mac_scc_cha_b_ctrl_offset)
2948         jra     7b
2949 8:
2950 #endif  /* MAC_USE_SCC_B */
2951
2952 #endif  /* SERIAL_DEBUG */
2953
2954         jra     L(serial_init_done)
2955 L(serial_init_not_mac):
2956 #endif  /* CONFIG_MAC */
2957
2958 #ifdef CONFIG_Q40
2959         is_not_q40(2f)
2960 /* debug output goes into SRAM, so we don't do it unless requested
2961    - check for '%LX$' signature in SRAM   */
2962         lea     %pc@(q40_mem_cptr),%a1
2963         move.l  #0xff020010,%a1@  /* must be inited - also used by debug=mem */
2964         move.l  #0xff020000,%a1
2965         cmp.b   #'%',%a1@
2966         bne     2f      /*nodbg*/
2967         addq.w  #4,%a1
2968         cmp.b   #'L',%a1@
2969         bne     2f      /*nodbg*/
2970         addq.w  #4,%a1
2971         cmp.b   #'X',%a1@
2972         bne     2f      /*nodbg*/
2973         addq.w  #4,%a1
2974         cmp.b   #'$',%a1@
2975         bne     2f      /*nodbg*/
2976         /* signature OK */
2977         lea     %pc@(L(q40_do_debug)),%a1
2978         tas     %a1@
2979 /*nodbg: q40_do_debug is 0 by default*/
2980 2:
2981 #endif
2982
2983 #ifdef CONFIG_APOLLO
2984 /* We count on the PROM initializing SIO1 */
2985 #endif
2986
2987 #ifdef CONFIG_HP300
2988 /* We count on the boot loader initialising the UART */
2989 #endif
2990
2991 L(serial_init_done):
2992 func_return     serial_init
2993
2994 /*
2995  * Output character on serial port.
2996  */
2997 func_start      serial_putc,%d0/%d1/%a0/%a1
2998
2999         movel   ARG1,%d0
3000         cmpib   #'\n',%d0
3001         jbne    1f
3002
3003         /* A little safe recursion is good for the soul */
3004         serial_putc     #'\r'
3005 1:
3006
3007 #ifdef CONFIG_AMIGA
3008         is_not_amiga(2f)
3009         andw    #0x00ff,%d0
3010         oriw    #0x0100,%d0
3011         movel   %pc@(L(custom)),%a0
3012         movew   %d0,%a0@(CUSTOMBASE+C_SERDAT)
3013 1:      movew   %a0@(CUSTOMBASE+C_SERDATR),%d0
3014         andw    #0x2000,%d0
3015         jeq     1b
3016         jra     L(serial_putc_done)
3017 2:
3018 #endif
3019
3020 #ifdef CONFIG_MAC
3021         is_not_mac(5f)
3022
3023 #ifdef SERIAL_DEBUG
3024
3025 #if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
3026         movel   %pc@(L(mac_sccbase)),%a1
3027 #endif
3028
3029 #ifdef MAC_USE_SCC_A
3030 3:      btst    #2,%a1@(mac_scc_cha_a_ctrl_offset)
3031         jeq     3b
3032         moveb   %d0,%a1@(mac_scc_cha_a_data_offset)
3033 #endif  /* MAC_USE_SCC_A */
3034
3035 #ifdef MAC_USE_SCC_B
3036 4:      btst    #2,%a1@(mac_scc_cha_b_ctrl_offset)
3037         jeq     4b
3038         moveb   %d0,%a1@(mac_scc_cha_b_data_offset)
3039 #endif  /* MAC_USE_SCC_B */
3040
3041 #endif  /* SERIAL_DEBUG */
3042
3043         jra     L(serial_putc_done)
3044 5:
3045 #endif  /* CONFIG_MAC */
3046
3047 #ifdef CONFIG_ATARI
3048         is_not_atari(4f)
3049         movel   %pc@(L(iobase)),%a1
3050 #if defined(USE_PRINTER)
3051 3:      btst    #0,%a1@(LSTMFP_GPIP)
3052         jne     3b
3053         moveb   #LPSG_IO_B,%a1@(LPSG_SELECT)
3054         moveb   %d0,%a1@(LPSG_WRITE)
3055         moveb   #LPSG_IO_A,%a1@(LPSG_SELECT)
3056         moveb   %a1@(LPSG_READ),%d0
3057         bclr    #5,%d0
3058         moveb   %d0,%a1@(LPSG_WRITE)
3059         nop
3060         nop
3061         bset    #5,%d0
3062         moveb   %d0,%a1@(LPSG_WRITE)
3063 #elif defined(USE_SCC)
3064 3:      btst    #2,%a1@(LSCC_CTRL)
3065         jeq     3b
3066         moveb   %d0,%a1@(LSCC_DATA)
3067 #elif defined(USE_MFP)
3068 3:      btst    #7,%a1@(LMFP_TSR)
3069         jeq     3b
3070         moveb   %d0,%a1@(LMFP_UDR)
3071 #endif
3072         jra     L(serial_putc_done)
3073 4:
3074 #endif  /* CONFIG_ATARI */
3075
3076 #ifdef CONFIG_MVME147
3077         is_not_mvme147(2f)
3078 1:      btst    #2,M147_SCC_CTRL_A
3079         jeq     1b
3080         moveb   %d0,M147_SCC_DATA_A
3081         jbra    L(serial_putc_done)
3082 2:
3083 #endif
3084
3085 #ifdef CONFIG_MVME16x
3086         is_not_mvme16x(2f)
3087         /*
3088          * If the loader gave us a board type then we can use that to
3089          * select an appropriate output routine; otherwise we just use
3090          * the Bug code.  If we have to use the Bug that means the Bug
3091          * workspace has to be valid, which means the Bug has to use
3092          * the SRAM, which is non-standard.
3093          */
3094         moveml  %d0-%d7/%a2-%a6,%sp@-
3095         movel   vme_brdtype,%d1
3096         jeq     1f                      | No tag - use the Bug
3097         cmpi    #VME_TYPE_MVME162,%d1
3098         jeq     6f
3099         cmpi    #VME_TYPE_MVME172,%d1
3100         jne     5f
3101         /* 162/172; it's an SCC */
3102 6:      btst    #2,M162_SCC_CTRL_A
3103         nop
3104         nop
3105         nop
3106         jeq     6b
3107         moveb   #8,M162_SCC_CTRL_A
3108         nop
3109         nop
3110         nop
3111         moveb   %d0,M162_SCC_CTRL_A
3112         jra     3f
3113 5:
3114         /* 166/167/177; it's a CD2401 */
3115         moveb   #0,M167_CYCAR
3116         moveb   M167_CYIER,%d2
3117         moveb   #0x02,M167_CYIER
3118 7:
3119         btst    #5,M167_PCSCCTICR
3120         jeq     7b
3121         moveb   M167_PCTPIACKR,%d1
3122         moveb   M167_CYLICR,%d1
3123         jeq     8f
3124         moveb   #0x08,M167_CYTEOIR
3125         jra     7b
3126 8:
3127         moveb   %d0,M167_CYTDR
3128         moveb   #0,M167_CYTEOIR
3129         moveb   %d2,M167_CYIER
3130         jra     3f
3131 1:
3132         moveb   %d0,%sp@-
3133         trap    #15
3134         .word   0x0020  /* TRAP 0x020 */
3135 3:
3136         moveml  %sp@+,%d0-%d7/%a2-%a6
3137         jbra    L(serial_putc_done)
3138 2:
3139 #endif /* CONFIG_MVME16x */
3140
3141 #ifdef CONFIG_BVME6000
3142         is_not_bvme6000(2f)
3143         /*
3144          * The BVME6000 machine has a serial port ...
3145          */
3146 1:      btst    #2,BVME_SCC_CTRL_A
3147         jeq     1b
3148         moveb   %d0,BVME_SCC_DATA_A
3149         jbra    L(serial_putc_done)
3150 2:
3151 #endif
3152
3153 #ifdef CONFIG_SUN3X
3154         is_not_sun3x(2f)
3155         movel   %d0,-(%sp)
3156         movel   0xFEFE0018,%a1
3157         jbsr    (%a1)
3158         addq    #4,%sp
3159         jbra    L(serial_putc_done)
3160 2:
3161 #endif
3162
3163 #ifdef CONFIG_Q40
3164         is_not_q40(2f)
3165         tst.l   %pc@(L(q40_do_debug))   /* only debug if requested */
3166         beq     2f
3167         lea     %pc@(q40_mem_cptr),%a1
3168         move.l  %a1@,%a0
3169         move.b  %d0,%a0@
3170         addq.l  #4,%a0
3171         move.l  %a0,%a1@
3172         jbra    L(serial_putc_done)
3173 2:
3174 #endif
3175
3176 #ifdef CONFIG_APOLLO
3177         is_not_apollo(2f)
3178         movl    %pc@(L(iobase)),%a1
3179         moveb   %d0,%a1@(LTHRB0)
3180 1:      moveb   %a1@(LSRB0),%d0
3181         andb    #0x4,%d0
3182         beq     1b
3183         jbra    L(serial_putc_done)
3184 2:
3185 #endif
3186
3187 #ifdef CONFIG_HP300
3188         is_not_hp300(3f)
3189         movl    %pc@(L(iobase)),%a1
3190         addl    %pc@(L(uartbase)),%a1
3191         movel   %pc@(L(uart_scode)),%d1 /* Check the scode */
3192         jmi     3f                      /* Unset? Exit */
3193         cmpi    #256,%d1                /* APCI scode? */
3194         jeq     2f
3195 1:      moveb   %a1@(DCALSR),%d1        /* Output to DCA */
3196         andb    #0x20,%d1
3197         beq     1b
3198         moveb   %d0,%a1@(DCADATA)
3199         jbra    L(serial_putc_done)
3200 2:      moveb   %a1@(APCILSR),%d1       /* Output to APCI */
3201         andb    #0x20,%d1
3202         beq     2b
3203         moveb   %d0,%a1@(APCIDATA)
3204         jbra    L(serial_putc_done)
3205 3:
3206 #endif
3207
3208 L(serial_putc_done):
3209 func_return     serial_putc
3210
3211 /*
3212  * Output a string.
3213  */
3214 func_start      puts,%d0/%a0
3215
3216         movel   ARG1,%a0
3217         jra     2f
3218 1:
3219 #ifdef CONSOLE
3220         console_putc    %d0
3221 #endif
3222 #ifdef SERIAL_DEBUG
3223         serial_putc     %d0
3224 #endif
3225 2:      moveb   %a0@+,%d0
3226         jne     1b
3227
3228 func_return     puts
3229
3230 /*
3231  * Output number in hex notation.
3232  */
3233
3234 func_start      putn,%d0-%d2
3235
3236         putc    ' '
3237
3238         movel   ARG1,%d0
3239         moveq   #7,%d1
3240 1:      roll    #4,%d0
3241         move    %d0,%d2
3242         andb    #0x0f,%d2
3243         addb    #'0',%d2
3244         cmpb    #'9',%d2
3245         jls     2f
3246         addb    #'A'-('9'+1),%d2
3247 2:
3248 #ifdef CONSOLE
3249         console_putc    %d2
3250 #endif
3251 #ifdef SERIAL_DEBUG
3252         serial_putc     %d2
3253 #endif
3254         dbra    %d1,1b
3255
3256 func_return     putn
3257
3258 #ifdef CONFIG_MAC
3259 /*
3260  *      mac_early_print
3261  *
3262  *      This routine takes its parameters on the stack.  It then
3263  *      turns around and calls the internal routines.  This routine
3264  *      is used by the boot console.
3265  *
3266  *      The calling parameters are:
3267  *              void mac_early_print(const char *str, unsigned length);
3268  *
3269  *      This routine does NOT understand variable arguments only
3270  *      simple strings!
3271  */
3272 ENTRY(mac_early_print)
3273         moveml  %d0/%d1/%a0,%sp@-
3274         movew   %sr,%sp@-
3275         ori     #0x0700,%sr
3276         movel   %sp@(18),%a0            /* fetch parameter */
3277         movel   %sp@(22),%d1            /* fetch parameter */
3278         jra     2f
3279 1:
3280 #ifdef CONSOLE
3281         console_putc    %d0
3282 #endif
3283 #ifdef SERIAL_DEBUG
3284         serial_putc     %d0
3285 #endif
3286         subq    #1,%d1
3287 2:      jeq     3f
3288         moveb   %a0@+,%d0
3289         jne     1b
3290 3:
3291         movew   %sp@+,%sr
3292         moveml  %sp@+,%d0/%d1/%a0
3293         rts
3294 #endif /* CONFIG_MAC */
3295
3296 #if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
3297 func_start      set_leds,%d0/%a0
3298         movel   ARG1,%d0
3299 #ifdef CONFIG_HP300
3300         is_not_hp300(1f)
3301         movel   %pc@(L(iobase)),%a0
3302         moveb   %d0,%a0@(0x1ffff)
3303         jra     2f
3304 #endif
3305 1:
3306 #ifdef CONFIG_APOLLO
3307         movel   %pc@(L(iobase)),%a0
3308         lsll    #8,%d0
3309         eorw    #0xff00,%d0
3310         moveb   %d0,%a0@(LCPUCTRL)
3311 #endif
3312 2:
3313 func_return     set_leds
3314 #endif
3315
3316 #ifdef CONSOLE
3317 /*
3318  *      For continuity, see the data alignment
3319  *      to which this structure is tied.
3320  */
3321 #define Lconsole_struct_cur_column      0
3322 #define Lconsole_struct_cur_row         4
3323 #define Lconsole_struct_num_columns     8
3324 #define Lconsole_struct_num_rows        12
3325 #define Lconsole_struct_left_edge       16
3326 #define Lconsole_struct_penguin_putc    20
3327
3328 func_start      console_init,%a0-%a4/%d0-%d7
3329         /*
3330          *      Some of the register usage that follows
3331          *              a0 = pointer to boot_info
3332          *              a1 = pointer to screen
3333          *              a2 = pointer to Lconsole_globals
3334          *              d3 = pixel width of screen
3335          *              d4 = pixel height of screen
3336          *              (d3,d4) ~= (x,y) of a point just below
3337          *                      and to the right of the screen
3338          *                      NOT on the screen!
3339          *              d5 = number of bytes per scan line
3340          *              d6 = number of bytes on the entire screen
3341          */
3342
3343         lea     %pc@(L(console_globals)),%a2
3344         movel   %pc@(L(mac_videobase)),%a1
3345         movel   %pc@(L(mac_rowbytes)),%d5
3346         movel   %pc@(L(mac_dimensions)),%d3     /* -> low byte */
3347         movel   %d3,%d4
3348         swap    %d4             /* -> high byte */
3349         andl    #0xffff,%d3     /* d3 = screen width in pixels */
3350         andl    #0xffff,%d4     /* d4 = screen height in pixels */
3351
3352         movel   %d5,%d6
3353 |       subl    #20,%d6
3354         mulul   %d4,%d6         /* scan line bytes x num scan lines */
3355         divul   #8,%d6          /* we'll clear 8 bytes at a time */
3356         moveq   #-1,%d0         /* Mac_black */
3357         subq    #1,%d6
3358
3359 L(console_clear_loop):
3360         movel   %d0,%a1@+
3361         movel   %d0,%a1@+
3362         dbra    %d6,L(console_clear_loop)
3363
3364         /* Calculate font size */
3365
3366 #if   defined(FONT_8x8) && defined(CONFIG_FONT_8x8)
3367         lea     %pc@(font_vga_8x8),%a0
3368 #elif defined(FONT_8x16) && defined(CONFIG_FONT_8x16)
3369         lea     %pc@(font_vga_8x16),%a0
3370 #elif defined(FONT_6x11) && defined(CONFIG_FONT_6x11)
3371         lea     %pc@(font_vga_6x11),%a0
3372 #elif defined(CONFIG_FONT_8x8) /* default */
3373         lea     %pc@(font_vga_8x8),%a0
3374 #else /* no compiled-in font */
3375         lea     0,%a0
3376 #endif
3377
3378         /*
3379          *      At this point we make a shift in register usage
3380          *      a1 = address of console_font pointer
3381          */
3382         lea     %pc@(L(console_font)),%a1
3383         movel   %a0,%a1@        /* store pointer to struct fbcon_font_desc in console_font */
3384         tstl    %a0
3385         jeq     1f
3386         lea     %pc@(L(console_font_data)),%a4
3387         movel   %a0@(FONT_DESC_DATA),%d0
3388         subl    #L(console_font),%a1
3389         addl    %a1,%d0
3390         movel   %d0,%a4@
3391
3392         /*
3393          *      Calculate global maxs
3394          *      Note - we can use either an
3395          *      8 x 16 or 8 x 8 character font
3396          *      6 x 11 also supported
3397          */
3398                 /* ASSERT: a0 = contents of Lconsole_font */
3399         movel   %d3,%d0                         /* screen width in pixels */
3400         divul   %a0@(FONT_DESC_WIDTH),%d0       /* d0 = max num chars per row */
3401
3402         movel   %d4,%d1                         /* screen height in pixels */
3403         divul   %a0@(FONT_DESC_HEIGHT),%d1      /* d1 = max num rows */
3404
3405         movel   %d0,%a2@(Lconsole_struct_num_columns)
3406         movel   %d1,%a2@(Lconsole_struct_num_rows)
3407
3408         /*
3409          *      Clear the current row and column
3410          */
3411         clrl    %a2@(Lconsole_struct_cur_column)
3412         clrl    %a2@(Lconsole_struct_cur_row)
3413         clrl    %a2@(Lconsole_struct_left_edge)
3414
3415         /*
3416          * Initialization is complete
3417          */
3418 1:
3419 func_return     console_init
3420
3421 func_start      console_put_stats,%a0/%d7
3422         /*
3423          *      Some of the register usage that follows
3424          *              a0 = pointer to boot_info
3425          *              d7 = value of boot_info fields
3426          */
3427         puts    "\nMacLinux\n"
3428
3429 #ifdef SERIAL_DEBUG
3430         puts    "\n vidaddr:"
3431         putn    %pc@(L(mac_videobase))          /* video addr. */
3432
3433         puts    "\n  _stext:"
3434         lea     %pc@(_stext),%a0
3435         putn    %a0
3436
3437         puts    "\nbootinfo:"
3438         lea     %pc@(_end),%a0
3439         putn    %a0
3440
3441         puts    "\n   cpuid:"
3442         putn    %pc@(L(cputype))
3443
3444 #  ifdef CONFIG_MAC
3445         puts    "\n sccbase:"
3446         putn    %pc@(L(mac_sccbase))
3447 #  endif
3448 #  ifdef MMU_PRINT
3449         putc    '\n'
3450         jbsr    mmu_print_machine_cpu_types
3451 #  endif
3452 #endif /* SERIAL_DEBUG */
3453
3454         putc    '\n'
3455
3456 func_return     console_put_stats
3457
3458 #ifdef CONFIG_LOGO
3459 func_start      console_put_penguin,%a0-%a1/%d0-%d7
3460         /*
3461          *      Get 'that_penguin' onto the screen in the upper right corner
3462          *      penguin is 64 x 74 pixels, align against right edge of screen
3463          */
3464         lea     %pc@(L(mac_dimensions)),%a0
3465         movel   %a0@,%d0
3466         andil   #0xffff,%d0
3467         subil   #64,%d0         /* snug up against the right edge */
3468         clrl    %d1             /* start at the top */
3469         movel   #73,%d7
3470         lea     %pc@(L(that_penguin)),%a1
3471 L(console_penguin_row):
3472         movel   #31,%d6
3473 L(console_penguin_pixel_pair):
3474         moveb   %a1@,%d2
3475         lsrb    #4,%d2
3476         console_plot_pixel %d0,%d1,%d2
3477         addq    #1,%d0
3478         moveb   %a1@+,%d2
3479         console_plot_pixel %d0,%d1,%d2
3480         addq    #1,%d0
3481         dbra    %d6,L(console_penguin_pixel_pair)
3482
3483         subil   #64,%d0
3484         addq    #1,%d1
3485         dbra    %d7,L(console_penguin_row)
3486
3487 func_return     console_put_penguin
3488
3489 /* include penguin bitmap */
3490 L(that_penguin):
3491 #include "../mac/mac_penguin.S"
3492 #endif
3493
3494         /*
3495          * Calculate source and destination addresses
3496          *      output  a1 = dest
3497          *              a2 = source
3498          */
3499
3500 func_start      console_scroll,%a0-%a4/%d0-%d7
3501         lea     %pc@(L(mac_videobase)),%a0
3502         movel   %a0@,%a1
3503         movel   %a1,%a2
3504         lea     %pc@(L(mac_rowbytes)),%a0
3505         movel   %a0@,%d5
3506         movel   %pc@(L(console_font)),%a0
3507         tstl    %a0
3508         jeq     1f
3509         mulul   %a0@(FONT_DESC_HEIGHT),%d5      /* account for # scan lines per character */
3510         addal   %d5,%a2
3511
3512         /*
3513          * Get dimensions
3514          */
3515         lea     %pc@(L(mac_dimensions)),%a0
3516         movel   %a0@,%d3
3517         movel   %d3,%d4
3518         swap    %d4
3519         andl    #0xffff,%d3     /* d3 = screen width in pixels */
3520         andl    #0xffff,%d4     /* d4 = screen height in pixels */
3521
3522         /*
3523          * Calculate number of bytes to move
3524          */
3525         lea     %pc@(L(mac_rowbytes)),%a0
3526         movel   %a0@,%d6
3527         movel   %pc@(L(console_font)),%a0
3528         subl    %a0@(FONT_DESC_HEIGHT),%d4      /* we're not scrolling the top row! */
3529         mulul   %d4,%d6         /* scan line bytes x num scan lines */
3530         divul   #32,%d6         /* we'll move 8 longs at a time */
3531         subq    #1,%d6
3532
3533 L(console_scroll_loop):
3534         movel   %a2@+,%a1@+
3535         movel   %a2@+,%a1@+
3536         movel   %a2@+,%a1@+
3537         movel   %a2@+,%a1@+
3538         movel   %a2@+,%a1@+
3539         movel   %a2@+,%a1@+
3540         movel   %a2@+,%a1@+
3541         movel   %a2@+,%a1@+
3542         dbra    %d6,L(console_scroll_loop)
3543
3544         lea     %pc@(L(mac_rowbytes)),%a0
3545         movel   %a0@,%d6
3546         movel   %pc@(L(console_font)),%a0
3547         mulul   %a0@(FONT_DESC_HEIGHT),%d6      /* scan line bytes x font height */
3548         divul   #32,%d6                 /* we'll move 8 words at a time */
3549         subq    #1,%d6
3550
3551         moveq   #-1,%d0
3552 L(console_scroll_clear_loop):
3553         movel   %d0,%a1@+
3554         movel   %d0,%a1@+
3555         movel   %d0,%a1@+
3556         movel   %d0,%a1@+
3557         movel   %d0,%a1@+
3558         movel   %d0,%a1@+
3559         movel   %d0,%a1@+
3560         movel   %d0,%a1@+
3561         dbra    %d6,L(console_scroll_clear_loop)
3562
3563 1:
3564 func_return     console_scroll
3565
3566
3567 func_start      console_putc,%a0/%a1/%d0-%d7
3568
3569         is_not_mac(L(console_exit))
3570         tstl    %pc@(L(console_font))
3571         jeq     L(console_exit)
3572
3573         /* Output character in d7 on console.
3574          */
3575         movel   ARG1,%d7
3576         cmpib   #'\n',%d7
3577         jbne    1f
3578
3579         /* A little safe recursion is good for the soul */
3580         console_putc    #'\r'
3581 1:
3582         lea     %pc@(L(console_globals)),%a0
3583
3584         cmpib   #10,%d7
3585         jne     L(console_not_lf)
3586         movel   %a0@(Lconsole_struct_cur_row),%d0
3587         addil   #1,%d0
3588         movel   %d0,%a0@(Lconsole_struct_cur_row)
3589         movel   %a0@(Lconsole_struct_num_rows),%d1
3590         cmpl    %d1,%d0
3591         jcs     1f
3592         subil   #1,%d0
3593         movel   %d0,%a0@(Lconsole_struct_cur_row)
3594         console_scroll
3595 1:
3596         jra     L(console_exit)
3597
3598 L(console_not_lf):
3599         cmpib   #13,%d7
3600         jne     L(console_not_cr)
3601         clrl    %a0@(Lconsole_struct_cur_column)
3602         jra     L(console_exit)
3603
3604 L(console_not_cr):
3605         cmpib   #1,%d7
3606         jne     L(console_not_home)
3607         clrl    %a0@(Lconsole_struct_cur_row)
3608         clrl    %a0@(Lconsole_struct_cur_column)
3609         jra     L(console_exit)
3610
3611 /*
3612  *      At this point we know that the %d7 character is going to be
3613  *      rendered on the screen.  Register usage is -
3614  *              a0 = pointer to console globals
3615  *              a1 = font data
3616  *              d0 = cursor column
3617  *              d1 = cursor row to draw the character
3618  *              d7 = character number
3619  */
3620 L(console_not_home):
3621         movel   %a0@(Lconsole_struct_cur_column),%d0
3622         addql   #1,%a0@(Lconsole_struct_cur_column)
3623         movel   %a0@(Lconsole_struct_num_columns),%d1
3624         cmpl    %d1,%d0
3625         jcs     1f
3626         console_putc    #'\n'   /* recursion is OK! */
3627 1:
3628         movel   %a0@(Lconsole_struct_cur_row),%d1
3629
3630         /*
3631          *      At this point we make a shift in register usage
3632          *      a0 = address of pointer to font data (fbcon_font_desc)
3633          */
3634         movel   %pc@(L(console_font)),%a0
3635         movel   %pc@(L(console_font_data)),%a1  /* Load fbcon_font_desc.data into a1 */
3636         andl    #0x000000ff,%d7
3637                 /* ASSERT: a0 = contents of Lconsole_font */
3638         mulul   %a0@(FONT_DESC_HEIGHT),%d7      /* d7 = index into font data */
3639         addl    %d7,%a1                 /* a1 = points to char image */
3640
3641         /*
3642          *      At this point we make a shift in register usage
3643          *      d0 = pixel coordinate, x
3644          *      d1 = pixel coordinate, y
3645          *      d2 = (bit 0) 1/0 for white/black (!) pixel on screen
3646          *      d3 = font scan line data (8 pixels)
3647          *      d6 = count down for the font's pixel width (8)
3648          *      d7 = count down for the font's pixel count in height
3649          */
3650                 /* ASSERT: a0 = contents of Lconsole_font */
3651         mulul   %a0@(FONT_DESC_WIDTH),%d0
3652         mulul   %a0@(FONT_DESC_HEIGHT),%d1
3653         movel   %a0@(FONT_DESC_HEIGHT),%d7      /* Load fbcon_font_desc.height into d7 */
3654         subq    #1,%d7
3655 L(console_read_char_scanline):
3656         moveb   %a1@+,%d3
3657
3658                 /* ASSERT: a0 = contents of Lconsole_font */
3659         movel   %a0@(FONT_DESC_WIDTH),%d6       /* Load fbcon_font_desc.width into d6 */
3660         subql   #1,%d6
3661
3662 L(console_do_font_scanline):
3663         lslb    #1,%d3
3664         scsb    %d2             /* convert 1 bit into a byte */
3665         console_plot_pixel %d0,%d1,%d2
3666         addq    #1,%d0
3667         dbra    %d6,L(console_do_font_scanline)
3668
3669                 /* ASSERT: a0 = contents of Lconsole_font */
3670         subl    %a0@(FONT_DESC_WIDTH),%d0
3671         addq    #1,%d1
3672         dbra    %d7,L(console_read_char_scanline)
3673
3674 L(console_exit):
3675 func_return     console_putc
3676
3677         /*
3678          *      Input:
3679          *              d0 = x coordinate
3680          *              d1 = y coordinate
3681          *              d2 = (bit 0) 1/0 for white/black (!)
3682          *      All registers are preserved
3683          */
3684 func_start      console_plot_pixel,%a0-%a1/%d0-%d4
3685
3686         movel   %pc@(L(mac_videobase)),%a1
3687         movel   %pc@(L(mac_videodepth)),%d3
3688         movel   ARG1,%d0
3689         movel   ARG2,%d1
3690         mulul   %pc@(L(mac_rowbytes)),%d1
3691         movel   ARG3,%d2
3692
3693         /*
3694          *      Register usage:
3695          *              d0 = x coord becomes byte offset into frame buffer
3696          *              d1 = y coord
3697          *              d2 = black or white (0/1)
3698          *              d3 = video depth
3699          *              d4 = temp of x (d0) for many bit depths
3700          */
3701 L(test_1bit):
3702         cmpb    #1,%d3
3703         jbne    L(test_2bit)
3704         movel   %d0,%d4         /* we need the low order 3 bits! */
3705         divul   #8,%d0
3706         addal   %d0,%a1
3707         addal   %d1,%a1
3708         andb    #7,%d4
3709         eorb    #7,%d4          /* reverse the x-coordinate w/ screen-bit # */
3710         andb    #1,%d2
3711         jbne    L(white_1)
3712         bsetb   %d4,%a1@
3713         jbra    L(console_plot_pixel_exit)
3714 L(white_1):
3715         bclrb   %d4,%a1@
3716         jbra    L(console_plot_pixel_exit)
3717
3718 L(test_2bit):
3719         cmpb    #2,%d3
3720         jbne    L(test_4bit)
3721         movel   %d0,%d4         /* we need the low order 2 bits! */
3722         divul   #4,%d0
3723         addal   %d0,%a1
3724         addal   %d1,%a1
3725         andb    #3,%d4
3726         eorb    #3,%d4          /* reverse the x-coordinate w/ screen-bit # */
3727         lsll    #1,%d4          /* ! */
3728         andb    #1,%d2
3729         jbne    L(white_2)
3730         bsetb   %d4,%a1@
3731         addq    #1,%d4
3732         bsetb   %d4,%a1@
3733         jbra    L(console_plot_pixel_exit)
3734 L(white_2):
3735         bclrb   %d4,%a1@
3736         addq    #1,%d4
3737         bclrb   %d4,%a1@
3738         jbra    L(console_plot_pixel_exit)
3739
3740 L(test_4bit):
3741         cmpb    #4,%d3
3742         jbne    L(test_8bit)
3743         movel   %d0,%d4         /* we need the low order bit! */
3744         divul   #2,%d0
3745         addal   %d0,%a1
3746         addal   %d1,%a1
3747         andb    #1,%d4
3748         eorb    #1,%d4
3749         lsll    #2,%d4          /* ! */
3750         andb    #1,%d2
3751         jbne    L(white_4)
3752         bsetb   %d4,%a1@
3753         addq    #1,%d4
3754         bsetb   %d4,%a1@
3755         addq    #1,%d4
3756         bsetb   %d4,%a1@
3757         addq    #1,%d4
3758         bsetb   %d4,%a1@
3759         jbra    L(console_plot_pixel_exit)
3760 L(white_4):
3761         bclrb   %d4,%a1@
3762         addq    #1,%d4
3763         bclrb   %d4,%a1@
3764         addq    #1,%d4
3765         bclrb   %d4,%a1@
3766         addq    #1,%d4
3767         bclrb   %d4,%a1@
3768         jbra    L(console_plot_pixel_exit)
3769
3770 L(test_8bit):
3771         cmpb    #8,%d3
3772         jbne    L(test_16bit)
3773         addal   %d0,%a1
3774         addal   %d1,%a1
3775         andb    #1,%d2
3776         jbne    L(white_8)
3777         moveb   #0xff,%a1@
3778         jbra    L(console_plot_pixel_exit)
3779 L(white_8):
3780         clrb    %a1@
3781         jbra    L(console_plot_pixel_exit)
3782
3783 L(test_16bit):
3784         cmpb    #16,%d3
3785         jbne    L(console_plot_pixel_exit)
3786         addal   %d0,%a1
3787         addal   %d0,%a1
3788         addal   %d1,%a1
3789         andb    #1,%d2
3790         jbne    L(white_16)
3791         clrw    %a1@
3792         jbra    L(console_plot_pixel_exit)
3793 L(white_16):
3794         movew   #0x0fff,%a1@
3795         jbra    L(console_plot_pixel_exit)
3796
3797 L(console_plot_pixel_exit):
3798 func_return     console_plot_pixel
3799 #endif /* CONSOLE */
3800
3801 #if 0
3802 /*
3803  * This is some old code lying around.  I don't believe
3804  * it's used or important anymore.  My guess is it contributed
3805  * to getting to this point, but it's done for now.
3806  * It was still in the 2.1.77 head.S, so it's still here.
3807  * (And still not used!)
3808  */
3809 L(showtest):
3810         moveml  %a0/%d7,%sp@-
3811         puts    "A="
3812         putn    %a1
3813
3814         .long   0xf0119f15              | ptestr        #5,%a1@,#7,%a0
3815
3816         puts    "DA="
3817         putn    %a0
3818
3819         puts    "D="
3820         putn    %a0@
3821
3822         puts    "S="
3823         lea     %pc@(L(mmu)),%a0
3824         .long   0xf0106200              | pmove         %psr,%a0@
3825         clrl    %d7
3826         movew   %a0@,%d7
3827         putn    %d7
3828
3829         putc    '\n'
3830         moveml  %sp@+,%a0/%d7
3831         rts
3832 #endif  /* 0 */
3833
3834 __INITDATA
3835         .align  4
3836
3837 #if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
3838     defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
3839 L(custom):
3840 L(iobase):
3841         .long 0
3842 #endif
3843
3844 #if defined(CONSOLE)
3845 L(console_globals):
3846         .long   0               /* cursor column */
3847         .long   0               /* cursor row */
3848         .long   0               /* max num columns */
3849         .long   0               /* max num rows */
3850         .long   0               /* left edge */
3851         .long   0               /* mac putc */
3852 L(console_font):
3853         .long   0               /* pointer to console font (struct font_desc) */
3854 L(console_font_data):
3855         .long   0               /* pointer to console font data */
3856 #endif /* CONSOLE */
3857
3858 #if defined(MMU_PRINT)
3859 L(mmu_print_data):
3860         .long   0               /* valid flag */
3861         .long   0               /* start logical */
3862         .long   0               /* next logical */
3863         .long   0               /* start physical */
3864         .long   0               /* next physical */
3865 #endif /* MMU_PRINT */
3866
3867 L(cputype):
3868         .long   0
3869 L(mmu_cached_pointer_tables):
3870         .long   0
3871 L(mmu_num_pointer_tables):
3872         .long   0
3873 L(phys_kernel_start):
3874         .long   0
3875 L(kernel_end):
3876         .long   0
3877 L(memory_start):
3878         .long   0
3879 L(kernel_pgdir_ptr):
3880         .long   0
3881 L(temp_mmap_mem):
3882         .long   0
3883
3884 #if defined (CONFIG_MVME147)
3885 M147_SCC_CTRL_A = 0xfffe3002
3886 M147_SCC_DATA_A = 0xfffe3003
3887 #endif
3888
3889 #if defined (CONFIG_MVME16x)
3890 M162_SCC_CTRL_A = 0xfff45005
3891 M167_CYCAR = 0xfff450ee
3892 M167_CYIER = 0xfff45011
3893 M167_CYLICR = 0xfff45026
3894 M167_CYTEOIR = 0xfff45085
3895 M167_CYTDR = 0xfff450f8
3896 M167_PCSCCTICR = 0xfff4201e
3897 M167_PCTPIACKR = 0xfff42025
3898 #endif
3899
3900 #if defined (CONFIG_BVME6000)
3901 BVME_SCC_CTRL_A = 0xffb0000b
3902 BVME_SCC_DATA_A = 0xffb0000f
3903 #endif
3904
3905 #if defined(CONFIG_MAC)
3906 L(mac_videobase):
3907         .long   0
3908 L(mac_videodepth):
3909         .long   0
3910 L(mac_dimensions):
3911         .long   0
3912 L(mac_rowbytes):
3913         .long   0
3914 #ifdef SERIAL_DEBUG
3915 L(mac_sccbase):
3916         .long   0
3917 #endif
3918 #endif /* CONFIG_MAC */
3919
3920 #if defined (CONFIG_APOLLO)
3921 LSRB0        = 0x10412
3922 LTHRB0       = 0x10416
3923 LCPUCTRL     = 0x10100
3924 #endif
3925
3926 #if defined(CONFIG_HP300)
3927 DCADATA      = 0x11
3928 DCALSR       = 0x1b
3929 APCIDATA     = 0x00
3930 APCILSR      = 0x14
3931 L(uartbase):
3932         .long   0
3933 L(uart_scode):
3934         .long   -1
3935 #endif
3936
3937 __FINIT
3938         .data
3939         .align  4
3940
3941 availmem:
3942         .long   0
3943 m68k_pgtable_cachemode:
3944         .long   0
3945 m68k_supervisor_cachemode:
3946         .long   0
3947 #if defined(CONFIG_MVME16x)
3948 mvme_bdid:
3949         .long   0,0,0,0,0,0,0,0
3950 #endif
3951 #if defined(CONFIG_Q40)
3952 q40_mem_cptr:
3953         .long   0
3954 L(q40_do_debug):
3955         .long   0
3956 #endif