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