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