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