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