xref: /openbmc/linux/arch/m68k/kernel/head.S (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
11da177e4SLinus Torvalds/* -*- mode: asm -*-
21da177e4SLinus Torvalds**
31da177e4SLinus Torvalds** head.S -- This file contains the initial boot code for the
41da177e4SLinus Torvalds**	     Linux/68k kernel.
51da177e4SLinus Torvalds**
61da177e4SLinus Torvalds** Copyright 1993 by Hamish Macdonald
71da177e4SLinus Torvalds**
81da177e4SLinus Torvalds** 68040 fixes by Michael Rausch
91da177e4SLinus Torvalds** 68060 fixes by Roman Hodek
101da177e4SLinus Torvalds** MMU cleanup by Randy Thelen
111da177e4SLinus Torvalds** Final MMU cleanup by Roman Zippel
121da177e4SLinus Torvalds**
131da177e4SLinus Torvalds** Atari support by Andreas Schwab, using ideas of Robert de Vries
141da177e4SLinus Torvalds** and Bjoern Brauel
151da177e4SLinus Torvalds** VME Support by Richard Hirst
161da177e4SLinus Torvalds**
171da177e4SLinus Torvalds** 94/11/14 Andreas Schwab: put kernel at PAGESIZE
181da177e4SLinus Torvalds** 94/11/18 Andreas Schwab: remove identity mapping of STRAM for Atari
191da177e4SLinus Torvalds** ++ Bjoern & Roman: ATARI-68040 support for the Medusa
201da177e4SLinus Torvalds** 95/11/18 Richard Hirst: Added MVME166 support
211da177e4SLinus Torvalds** 96/04/26 Guenther Kelleter: fixed identity mapping for Falcon with
221da177e4SLinus Torvalds**			      Magnum- and FX-alternate ram
231da177e4SLinus Torvalds** 98/04/25 Phil Blundell: added HP300 support
241da177e4SLinus Torvalds** 1998/08/30 David Kilzer: Added support for font_desc structures
251da177e4SLinus Torvalds**            for linux-2.1.115
267ca1e52dSGeert Uytterhoeven** 1999/02/11  Richard Zidlicky: added Q40 support (initial version 99/01/01)
271da177e4SLinus Torvalds** 2004/05/13 Kars de Jong: Finalised HP300 support
281da177e4SLinus Torvalds**
291da177e4SLinus Torvalds** This file is subject to the terms and conditions of the GNU General Public
301da177e4SLinus Torvalds** License. See the file README.legal in the main directory of this archive
311da177e4SLinus Torvalds** for more details.
321da177e4SLinus Torvalds**
331da177e4SLinus Torvalds*/
341da177e4SLinus Torvalds
351da177e4SLinus Torvalds/*
361da177e4SLinus Torvalds * Linux startup code.
371da177e4SLinus Torvalds *
381da177e4SLinus Torvalds * At this point, the boot loader has:
391da177e4SLinus Torvalds * Disabled interrupts
401da177e4SLinus Torvalds * Disabled caches
411da177e4SLinus Torvalds * Put us in supervisor state.
421da177e4SLinus Torvalds *
431da177e4SLinus Torvalds * The kernel setup code takes the following steps:
441da177e4SLinus Torvalds * .  Raise interrupt level
451da177e4SLinus Torvalds * .  Set up initial kernel memory mapping.
461da177e4SLinus Torvalds *    .  This sets up a mapping of the 4M of memory the kernel is located in.
471da177e4SLinus Torvalds *    .  It also does a mapping of any initial machine specific areas.
481da177e4SLinus Torvalds * .  Enable the MMU
491da177e4SLinus Torvalds * .  Enable cache memories
501da177e4SLinus Torvalds * .  Jump to kernel startup
511da177e4SLinus Torvalds *
521da177e4SLinus Torvalds * Much of the file restructuring was to accomplish:
531da177e4SLinus Torvalds * 1) Remove register dependency through-out the file.
541da177e4SLinus Torvalds * 2) Increase use of subroutines to perform functions
551da177e4SLinus Torvalds * 3) Increase readability of the code
561da177e4SLinus Torvalds *
571da177e4SLinus Torvalds * Of course, readability is a subjective issue, so it will never be
581da177e4SLinus Torvalds * argued that that goal was accomplished.  It was merely a goal.
591da177e4SLinus Torvalds * A key way to help make code more readable is to give good
605661bccbSFinn Thain * documentation.  So, the first thing you will find is exhaustive
611da177e4SLinus Torvalds * write-ups on the structure of the file, and the features of the
621da177e4SLinus Torvalds * functional subroutines.
631da177e4SLinus Torvalds *
641da177e4SLinus Torvalds * General Structure:
651da177e4SLinus Torvalds * ------------------
661da177e4SLinus Torvalds *	Without a doubt the single largest chunk of head.S is spent
671da177e4SLinus Torvalds * mapping the kernel and I/O physical space into the logical range
681da177e4SLinus Torvalds * for the kernel.
691da177e4SLinus Torvalds *	There are new subroutines and data structures to make MMU
701da177e4SLinus Torvalds * support cleaner and easier to understand.
711da177e4SLinus Torvalds *	First, you will find a routine call "mmu_map" which maps
721da177e4SLinus Torvalds * a logical to a physical region for some length given a cache
731da177e4SLinus Torvalds * type on behalf of the caller.  This routine makes writing the
741da177e4SLinus Torvalds * actual per-machine specific code very simple.
751da177e4SLinus Torvalds *	A central part of the code, but not a subroutine in itself,
761da177e4SLinus Torvalds * is the mmu_init code which is broken down into mapping the kernel
771da177e4SLinus Torvalds * (the same for all machines) and mapping machine-specific I/O
781da177e4SLinus Torvalds * regions.
791da177e4SLinus Torvalds *	Also, there will be a description of engaging the MMU and
801da177e4SLinus Torvalds * caches.
811da177e4SLinus Torvalds *	You will notice that there is a chunk of code which
821da177e4SLinus Torvalds * can emit the entire MMU mapping of the machine.  This is present
831da177e4SLinus Torvalds * only in debug modes and can be very helpful.
841da177e4SLinus Torvalds *	Further, there is a new console driver in head.S that is
851da177e4SLinus Torvalds * also only engaged in debug mode.  Currently, it's only supported
861da177e4SLinus Torvalds * on the Macintosh class of machines.  However, it is hoped that
871da177e4SLinus Torvalds * others will plug-in support for specific machines.
881da177e4SLinus Torvalds *
891da177e4SLinus Torvalds * ######################################################################
901da177e4SLinus Torvalds *
911da177e4SLinus Torvalds * mmu_map
921da177e4SLinus Torvalds * -------
931da177e4SLinus Torvalds *	mmu_map was written for two key reasons.  First, it was clear
941da177e4SLinus Torvalds * that it was very difficult to read the previous code for mapping
951da177e4SLinus Torvalds * regions of memory.  Second, the Macintosh required such extensive
961da177e4SLinus Torvalds * memory allocations that it didn't make sense to propagate the
971da177e4SLinus Torvalds * existing code any further.
981da177e4SLinus Torvalds *	mmu_map requires some parameters:
991da177e4SLinus Torvalds *
1001da177e4SLinus Torvalds *	mmu_map (logical, physical, length, cache_type)
1011da177e4SLinus Torvalds *
1021da177e4SLinus Torvalds *	While this essentially describes the function in the abstract, you'll
1031da177e4SLinus Torvalds * find more indepth description of other parameters at the implementation site.
1041da177e4SLinus Torvalds *
1051da177e4SLinus Torvalds * mmu_get_root_table_entry
1061da177e4SLinus Torvalds * ------------------------
1071da177e4SLinus Torvalds * mmu_get_ptr_table_entry
1081da177e4SLinus Torvalds * -----------------------
1091da177e4SLinus Torvalds * mmu_get_page_table_entry
1101da177e4SLinus Torvalds * ------------------------
1111da177e4SLinus Torvalds *
1121da177e4SLinus Torvalds *	These routines are used by other mmu routines to get a pointer into
1131da177e4SLinus Torvalds * a table, if necessary a new table is allocated. These routines are working
1141da177e4SLinus Torvalds * basically like pmd_alloc() and pte_alloc() in <asm/pgtable.h>. The root
1151da177e4SLinus Torvalds * table needs of course only to be allocated once in mmu_get_root_table_entry,
1161da177e4SLinus Torvalds * so that here also some mmu specific initialization is done. The second page
1171da177e4SLinus Torvalds * at the start of the kernel (the first page is unmapped later) is used for
1181da177e4SLinus Torvalds * the kernel_pg_dir. It must be at a position known at link time (as it's used
1191da177e4SLinus Torvalds * to initialize the init task struct) and since it needs special cache
1201da177e4SLinus Torvalds * settings, it's the easiest to use this page, the rest of the page is used
1211da177e4SLinus Torvalds * for further pointer tables.
1221da177e4SLinus Torvalds * mmu_get_page_table_entry allocates always a whole page for page tables, this
1231da177e4SLinus Torvalds * means 1024 pages and so 4MB of memory can be mapped. It doesn't make sense
1241da177e4SLinus Torvalds * to manage page tables in smaller pieces as nearly all mappings have that
1251da177e4SLinus Torvalds * size.
1261da177e4SLinus Torvalds *
1271da177e4SLinus Torvalds * ######################################################################
1281da177e4SLinus Torvalds *
1291da177e4SLinus Torvalds *
1301da177e4SLinus Torvalds * ######################################################################
1311da177e4SLinus Torvalds *
1321da177e4SLinus Torvalds * mmu_engage
1331da177e4SLinus Torvalds * ----------
1341da177e4SLinus Torvalds *	Thanks to a small helping routine enabling the mmu got quite simple
1351da177e4SLinus Torvalds * and there is only one way left. mmu_engage makes a complete a new mapping
1361da177e4SLinus Torvalds * that only includes the absolute necessary to be able to jump to the final
13725985edcSLucas De Marchi * position and to restore the original mapping.
1381da177e4SLinus Torvalds * As this code doesn't need a transparent translation register anymore this
1391da177e4SLinus Torvalds * means all registers are free to be used by machines that needs them for
1401da177e4SLinus Torvalds * other purposes.
1411da177e4SLinus Torvalds *
1421da177e4SLinus Torvalds * ######################################################################
1431da177e4SLinus Torvalds *
1441da177e4SLinus Torvalds * mmu_print
1451da177e4SLinus Torvalds * ---------
1461da177e4SLinus Torvalds *	This algorithm will print out the page tables of the system as
1471da177e4SLinus Torvalds * appropriate for an 030 or an 040.  This is useful for debugging purposes
1481da177e4SLinus Torvalds * and as such is enclosed in #ifdef MMU_PRINT/#endif clauses.
1491da177e4SLinus Torvalds *
1501da177e4SLinus Torvalds * ######################################################################
1511da177e4SLinus Torvalds *
1521da177e4SLinus Torvalds * console_init
1531da177e4SLinus Torvalds * ------------
1541da177e4SLinus Torvalds *	The console is also able to be turned off.  The console in head.S
1551da177e4SLinus Torvalds * is specifically for debugging and can be very useful.  It is surrounded by
15697f3f68cSFinn Thain * #ifdef / #endif clauses so it doesn't have to ship in known-good
1571da177e4SLinus Torvalds * kernels.  It's basic algorithm is to determine the size of the screen
1581da177e4SLinus Torvalds * (in height/width and bit depth) and then use that information for
1591da177e4SLinus Torvalds * displaying an 8x8 font or an 8x16 (widthxheight).  I prefer the 8x8 for
1601da177e4SLinus Torvalds * debugging so I can see more good data.  But it was trivial to add support
1611da177e4SLinus Torvalds * for both fonts, so I included it.
1621da177e4SLinus Torvalds *	Also, the algorithm for plotting pixels is abstracted so that in
1631da177e4SLinus Torvalds * theory other platforms could add support for different kinds of frame
1641da177e4SLinus Torvalds * buffers.  This could be very useful.
1651da177e4SLinus Torvalds *
1661da177e4SLinus Torvalds * console_put_penguin
1671da177e4SLinus Torvalds * -------------------
1681da177e4SLinus Torvalds *	An important part of any Linux bring up is the penguin and there's
1691da177e4SLinus Torvalds * nothing like getting the Penguin on the screen!  This algorithm will work
1701da177e4SLinus Torvalds * on any machine for which there is a console_plot_pixel.
1711da177e4SLinus Torvalds *
1721da177e4SLinus Torvalds * console_scroll
1731da177e4SLinus Torvalds * --------------
1741da177e4SLinus Torvalds *	My hope is that the scroll algorithm does the right thing on the
1751da177e4SLinus Torvalds * various platforms, but it wouldn't be hard to add the test conditions
1761da177e4SLinus Torvalds * and new code if it doesn't.
1771da177e4SLinus Torvalds *
1781da177e4SLinus Torvalds * console_putc
1791da177e4SLinus Torvalds * -------------
1801da177e4SLinus Torvalds *
1811da177e4SLinus Torvalds * ######################################################################
1821da177e4SLinus Torvalds *
1831da177e4SLinus Torvalds *	Register usage has greatly simplified within head.S. Every subroutine
1841da177e4SLinus Torvalds * saves and restores all registers that it modifies (except it returns a
1851da177e4SLinus Torvalds * value in there of course). So the only register that needs to be initialized
1861da177e4SLinus Torvalds * is the stack pointer.
1871da177e4SLinus Torvalds * All other init code and data is now placed in the init section, so it will
1881da177e4SLinus Torvalds * be automatically freed at the end of the kernel initialization.
1891da177e4SLinus Torvalds *
1901da177e4SLinus Torvalds * ######################################################################
1911da177e4SLinus Torvalds *
1921da177e4SLinus Torvalds * options
1931da177e4SLinus Torvalds * -------
1941da177e4SLinus Torvalds *	There are many options available in a build of this file.  I've
1951da177e4SLinus Torvalds * taken the time to describe them here to save you the time of searching
1961da177e4SLinus Torvalds * for them and trying to understand what they mean.
1971da177e4SLinus Torvalds *
1981da177e4SLinus Torvalds * CONFIG_xxx:	These are the obvious machine configuration defines created
199264a2683SSam Ravnborg * during configuration.  These are defined in autoconf.h.
2001da177e4SLinus Torvalds *
20197f3f68cSFinn Thain * CONSOLE_DEBUG:  Only supports a Mac frame buffer but could easily be
20297f3f68cSFinn Thain * extended to support other platforms.
2031da177e4SLinus Torvalds *
2041da177e4SLinus Torvalds * TEST_MMU:	This is a test harness for running on any given machine but
2051da177e4SLinus Torvalds * getting an MMU dump for another class of machine.  The classes of machines
2061da177e4SLinus Torvalds * that can be tested are any of the makes (Atari, Amiga, Mac, VME, etc.)
2071da177e4SLinus Torvalds * and any of the models (030, 040, 060, etc.).
2081da177e4SLinus Torvalds *
2091da177e4SLinus Torvalds *	NOTE:	TEST_MMU is NOT permanent!  It is scheduled to be removed
2101da177e4SLinus Torvalds *		When head.S boots on Atari, Amiga, Macintosh, and VME
2111da177e4SLinus Torvalds *		machines.  At that point the underlying logic will be
2121da177e4SLinus Torvalds *		believed to be solid enough to be trusted, and TEST_MMU
2131da177e4SLinus Torvalds *		can be dropped.  Do note that that will clean up the
2141da177e4SLinus Torvalds *		head.S code significantly as large blocks of #if/#else
2151da177e4SLinus Torvalds *		clauses can be removed.
2161da177e4SLinus Torvalds *
2171da177e4SLinus Torvalds * MMU_NOCACHE_KERNEL:	On the Macintosh platform there was an inquiry into
2181da177e4SLinus Torvalds * determing why devices don't appear to work.  A test case was to remove
2191da177e4SLinus Torvalds * the cacheability of the kernel bits.
2201da177e4SLinus Torvalds *
2211da177e4SLinus Torvalds * MMU_PRINT:	There is a routine built into head.S that can display the
2221da177e4SLinus Torvalds * MMU data structures.  It outputs its result through the serial_putc
2231da177e4SLinus Torvalds * interface.  So where ever that winds up driving data, that's where the
2247913ad1aSFinn Thain * mmu struct will appear.
2251da177e4SLinus Torvalds *
2261da177e4SLinus Torvalds * SERIAL_DEBUG:	There are a series of putc() macro statements
2271da177e4SLinus Torvalds * scattered through out the code to give progress of status to the
2281da177e4SLinus Torvalds * person sitting at the console.  This constant determines whether those
2291da177e4SLinus Torvalds * are used.
2301da177e4SLinus Torvalds *
2311da177e4SLinus Torvalds * DEBUG:	This is the standard DEBUG flag that can be set for building
2321da177e4SLinus Torvalds *		the kernel.  It has the effect adding additional tests into
2331da177e4SLinus Torvalds *		the code.
2341da177e4SLinus Torvalds *
2351da177e4SLinus Torvalds * FONT_6x11:
2361da177e4SLinus Torvalds * FONT_8x8:
2371da177e4SLinus Torvalds * FONT_8x16:
2381da177e4SLinus Torvalds *		In theory these could be determined at run time or handed
2391da177e4SLinus Torvalds *		over by the booter.  But, let's be real, it's a fine hard
2401da177e4SLinus Torvalds *		coded value.  (But, you will notice the code is run-time
2411da177e4SLinus Torvalds *		flexible!)  A pointer to the font's struct font_desc
2421da177e4SLinus Torvalds *		is kept locally in Lconsole_font.  It is used to determine
2431da177e4SLinus Torvalds *		font size information dynamically.
2441da177e4SLinus Torvalds *
2451da177e4SLinus Torvalds * Atari constants:
2461da177e4SLinus Torvalds * USE_PRINTER:	Use the printer port for serial debug.
2471da177e4SLinus Torvalds * USE_SCC_B:	Use the SCC port A (Serial2) for serial debug.
2481da177e4SLinus Torvalds * USE_SCC_A:	Use the SCC port B (Modem2) for serial debug.
2491da177e4SLinus Torvalds * USE_MFP:	Use the ST-MFP port (Modem1) for serial debug.
2501da177e4SLinus Torvalds *
2511da177e4SLinus Torvalds * Macintosh constants:
2527913ad1aSFinn Thain * MAC_USE_SCC_A: Use SCC port A (modem) for serial debug.
2537913ad1aSFinn Thain * MAC_USE_SCC_B: Use SCC port B (printer) for serial debug.
2541da177e4SLinus Torvalds */
2551da177e4SLinus Torvalds
2561da177e4SLinus Torvalds#include <linux/linkage.h>
2571da177e4SLinus Torvalds#include <linux/init.h>
25865fddcfcSMike Rapoport#include <linux/pgtable.h>
2591da177e4SLinus Torvalds#include <asm/bootinfo.h>
2604c3c522bSGeert Uytterhoeven#include <asm/bootinfo-amiga.h>
2614c3c522bSGeert Uytterhoeven#include <asm/bootinfo-atari.h>
2624c3c522bSGeert Uytterhoeven#include <asm/bootinfo-hp300.h>
2634c3c522bSGeert Uytterhoeven#include <asm/bootinfo-mac.h>
2644c3c522bSGeert Uytterhoeven#include <asm/bootinfo-q40.h>
265*05d51e42SLaurent Vivier#include <asm/bootinfo-virt.h>
2664c3c522bSGeert Uytterhoeven#include <asm/bootinfo-vme.h>
2671da177e4SLinus Torvalds#include <asm/setup.h>
2681da177e4SLinus Torvalds#include <asm/entry.h>
2691da177e4SLinus Torvalds#include <asm/page.h>
2700013a854SSam Ravnborg#include <asm/asm-offsets.h>
2711da177e4SLinus Torvalds#ifdef CONFIG_MAC
2721da177e4SLinus Torvalds#  include <asm/machw.h>
273a2d823bfSAl Viro#endif
2741da177e4SLinus Torvalds
27593edd023SFinn Thain#ifdef CONFIG_EARLY_PRINTK
27693edd023SFinn Thain#  define SERIAL_DEBUG
2777913ad1aSFinn Thain#  if defined(CONFIG_MAC) && defined(CONFIG_FONT_SUPPORT)
2787913ad1aSFinn Thain#    define CONSOLE_DEBUG
27993edd023SFinn Thain#  endif
2807913ad1aSFinn Thain#endif
2811da177e4SLinus Torvalds
2821da177e4SLinus Torvalds#undef MMU_PRINT
2831da177e4SLinus Torvalds#undef MMU_NOCACHE_KERNEL
2841da177e4SLinus Torvalds#undef DEBUG
2851da177e4SLinus Torvalds
2861da177e4SLinus Torvalds/*
2871da177e4SLinus Torvalds * For the head.S console, there are three supported fonts, 6x11, 8x16 and 8x8.
2881da177e4SLinus Torvalds * The 8x8 font is harder to read but fits more on the screen.
2891da177e4SLinus Torvalds */
2901da177e4SLinus Torvalds#define FONT_8x8	/* default */
2911da177e4SLinus Torvalds/* #define FONT_8x16 */	/* 2nd choice */
2921da177e4SLinus Torvalds/* #define FONT_6x11 */	/* 3rd choice */
2931da177e4SLinus Torvalds
2941da177e4SLinus Torvalds.globl kernel_pg_dir
2951da177e4SLinus Torvalds.globl availmem
296486df8bcSAndreas Schwab.globl m68k_init_mapped_size
2971da177e4SLinus Torvalds.globl m68k_pgtable_cachemode
2981da177e4SLinus Torvalds.globl m68k_supervisor_cachemode
2991da177e4SLinus Torvalds#ifdef CONFIG_MVME16x
3001da177e4SLinus Torvalds.globl mvme_bdid
3011da177e4SLinus Torvalds#endif
3021da177e4SLinus Torvalds#ifdef CONFIG_Q40
3031da177e4SLinus Torvalds.globl q40_mem_cptr
3041da177e4SLinus Torvalds#endif
3051da177e4SLinus Torvalds
3061da177e4SLinus TorvaldsCPUTYPE_040	= 1	/* indicates an 040 */
3071da177e4SLinus TorvaldsCPUTYPE_060	= 2	/* indicates an 060 */
3081da177e4SLinus TorvaldsCPUTYPE_0460	= 3	/* if either above are set, this is set */
3091da177e4SLinus TorvaldsCPUTYPE_020	= 4	/* indicates an 020 */
3101da177e4SLinus Torvalds
3111da177e4SLinus Torvalds/* Translation control register */
3121da177e4SLinus TorvaldsTC_ENABLE = 0x8000
3131da177e4SLinus TorvaldsTC_PAGE8K = 0x4000
3141da177e4SLinus TorvaldsTC_PAGE4K = 0x0000
3151da177e4SLinus Torvalds
3161da177e4SLinus Torvalds/* Transparent translation registers */
3171da177e4SLinus TorvaldsTTR_ENABLE	= 0x8000	/* enable transparent translation */
3181da177e4SLinus TorvaldsTTR_ANYMODE	= 0x4000	/* user and kernel mode access */
3191da177e4SLinus TorvaldsTTR_KERNELMODE	= 0x2000	/* only kernel mode access */
3201da177e4SLinus TorvaldsTTR_USERMODE	= 0x0000	/* only user mode access */
3211da177e4SLinus TorvaldsTTR_CI		= 0x0400	/* inhibit cache */
3221da177e4SLinus TorvaldsTTR_RW		= 0x0200	/* read/write mode */
3231da177e4SLinus TorvaldsTTR_RWM		= 0x0100	/* read/write mask */
3241da177e4SLinus TorvaldsTTR_FCB2	= 0x0040	/* function code base bit 2 */
3251da177e4SLinus TorvaldsTTR_FCB1	= 0x0020	/* function code base bit 1 */
3261da177e4SLinus TorvaldsTTR_FCB0	= 0x0010	/* function code base bit 0 */
3271da177e4SLinus TorvaldsTTR_FCM2	= 0x0004	/* function code mask bit 2 */
3281da177e4SLinus TorvaldsTTR_FCM1	= 0x0002	/* function code mask bit 1 */
3291da177e4SLinus TorvaldsTTR_FCM0	= 0x0001	/* function code mask bit 0 */
3301da177e4SLinus Torvalds
3311da177e4SLinus Torvalds/* Cache Control registers */
3321da177e4SLinus TorvaldsCC6_ENABLE_D	= 0x80000000	/* enable data cache (680[46]0) */
3331da177e4SLinus TorvaldsCC6_FREEZE_D	= 0x40000000	/* freeze data cache (68060) */
3341da177e4SLinus TorvaldsCC6_ENABLE_SB	= 0x20000000	/* enable store buffer (68060) */
3351da177e4SLinus TorvaldsCC6_PUSH_DPI	= 0x10000000	/* disable CPUSH invalidation (68060) */
3361da177e4SLinus TorvaldsCC6_HALF_D	= 0x08000000	/* half-cache mode for data cache (68060) */
3371da177e4SLinus TorvaldsCC6_ENABLE_B	= 0x00800000	/* enable branch cache (68060) */
3381da177e4SLinus TorvaldsCC6_CLRA_B	= 0x00400000	/* clear all entries in branch cache (68060) */
3391da177e4SLinus TorvaldsCC6_CLRU_B	= 0x00200000	/* clear user entries in branch cache (68060) */
3401da177e4SLinus TorvaldsCC6_ENABLE_I	= 0x00008000	/* enable instruction cache (680[46]0) */
3411da177e4SLinus TorvaldsCC6_FREEZE_I	= 0x00004000	/* freeze instruction cache (68060) */
3421da177e4SLinus TorvaldsCC6_HALF_I	= 0x00002000	/* half-cache mode for instruction cache (68060) */
3431da177e4SLinus TorvaldsCC3_ALLOC_WRITE	= 0x00002000	/* write allocate mode(68030) */
3441da177e4SLinus TorvaldsCC3_ENABLE_DB	= 0x00001000	/* enable data burst (68030) */
3451da177e4SLinus TorvaldsCC3_CLR_D	= 0x00000800	/* clear data cache (68030) */
3461da177e4SLinus TorvaldsCC3_CLRE_D	= 0x00000400	/* clear entry in data cache (68030) */
3471da177e4SLinus TorvaldsCC3_FREEZE_D	= 0x00000200	/* freeze data cache (68030) */
3481da177e4SLinus TorvaldsCC3_ENABLE_D	= 0x00000100	/* enable data cache (68030) */
3491da177e4SLinus TorvaldsCC3_ENABLE_IB	= 0x00000010	/* enable instruction burst (68030) */
3501da177e4SLinus TorvaldsCC3_CLR_I	= 0x00000008	/* clear instruction cache (68030) */
3511da177e4SLinus TorvaldsCC3_CLRE_I	= 0x00000004	/* clear entry in instruction cache (68030) */
3521da177e4SLinus TorvaldsCC3_FREEZE_I	= 0x00000002	/* freeze instruction cache (68030) */
3531da177e4SLinus TorvaldsCC3_ENABLE_I	= 0x00000001	/* enable instruction cache (68030) */
3541da177e4SLinus Torvalds
3551da177e4SLinus Torvalds/* Miscellaneous definitions */
3561da177e4SLinus TorvaldsPAGESIZE	= 4096
3571da177e4SLinus TorvaldsPAGESHIFT	= 12
3581da177e4SLinus Torvalds
3591da177e4SLinus TorvaldsROOT_TABLE_SIZE	= 128
3601da177e4SLinus TorvaldsPTR_TABLE_SIZE	= 128
3611da177e4SLinus TorvaldsPAGE_TABLE_SIZE	= 64
3621da177e4SLinus TorvaldsROOT_INDEX_SHIFT = 25
3631da177e4SLinus TorvaldsPTR_INDEX_SHIFT  = 18
3641da177e4SLinus TorvaldsPAGE_INDEX_SHIFT = 12
3651da177e4SLinus Torvalds
3661da177e4SLinus Torvalds#ifdef DEBUG
3671da177e4SLinus Torvalds/* When debugging use readable names for labels */
3681da177e4SLinus Torvalds#ifdef __STDC__
3691da177e4SLinus Torvalds#define L(name) .head.S.##name
3701da177e4SLinus Torvalds#else
3711da177e4SLinus Torvalds#define L(name) .head.S./**/name
3721da177e4SLinus Torvalds#endif
3731da177e4SLinus Torvalds#else
3741da177e4SLinus Torvalds#ifdef __STDC__
3751da177e4SLinus Torvalds#define L(name) .L##name
3761da177e4SLinus Torvalds#else
3771da177e4SLinus Torvalds#define L(name) .L/**/name
3781da177e4SLinus Torvalds#endif
3791da177e4SLinus Torvalds#endif
3801da177e4SLinus Torvalds
3811da177e4SLinus Torvalds/* The __INITDATA stuff is a no-op when ftrace or kgdb are turned on */
3821da177e4SLinus Torvalds#ifndef __INITDATA
3831da177e4SLinus Torvalds#define __INITDATA	.data
3841da177e4SLinus Torvalds#define __FINIT		.previous
3851da177e4SLinus Torvalds#endif
3861da177e4SLinus Torvalds
3871da177e4SLinus Torvalds/* Several macros to make the writing of subroutines easier:
3881da177e4SLinus Torvalds * - func_start marks the beginning of the routine which setups the frame
3891da177e4SLinus Torvalds *   register and saves the registers, it also defines another macro
3901da177e4SLinus Torvalds *   to automatically restore the registers again.
3911da177e4SLinus Torvalds * - func_return marks the end of the routine and simply calls the prepared
3921da177e4SLinus Torvalds *   macro to restore registers and jump back to the caller.
3931da177e4SLinus Torvalds * - func_define generates another macro to automatically put arguments
3941da177e4SLinus Torvalds *   onto the stack call the subroutine and cleanup the stack again.
3951da177e4SLinus Torvalds */
3961da177e4SLinus Torvalds
3971da177e4SLinus Torvalds/* Within subroutines these macros can be used to access the arguments
3981da177e4SLinus Torvalds * on the stack. With STACK some allocated memory on the stack can be
3991da177e4SLinus Torvalds * accessed and ARG0 points to the return address (used by mmu_engage).
4001da177e4SLinus Torvalds */
4011da177e4SLinus Torvalds#define	STACK	%a6@(stackstart)
4021da177e4SLinus Torvalds#define ARG0	%a6@(4)
4031da177e4SLinus Torvalds#define ARG1	%a6@(8)
4041da177e4SLinus Torvalds#define ARG2	%a6@(12)
4051da177e4SLinus Torvalds#define ARG3	%a6@(16)
4061da177e4SLinus Torvalds#define ARG4	%a6@(20)
4071da177e4SLinus Torvalds
4081da177e4SLinus Torvalds.macro	func_start	name,saveregs,stack=0
4091da177e4SLinus TorvaldsL(\name):
4101da177e4SLinus Torvalds	linkw	%a6,#-\stack
4111da177e4SLinus Torvalds	moveml	\saveregs,%sp@-
4121da177e4SLinus Torvalds.set	stackstart,-\stack
4131da177e4SLinus Torvalds
4141da177e4SLinus Torvalds.macro	func_return_\name
4151da177e4SLinus Torvalds	moveml	%sp@+,\saveregs
4161da177e4SLinus Torvalds	unlk	%a6
4171da177e4SLinus Torvalds	rts
4181da177e4SLinus Torvalds.endm
4191da177e4SLinus Torvalds.endm
4201da177e4SLinus Torvalds
4211da177e4SLinus Torvalds.macro	func_return	name
4221da177e4SLinus Torvalds	func_return_\name
4231da177e4SLinus Torvalds.endm
4241da177e4SLinus Torvalds
4251da177e4SLinus Torvalds.macro	func_call	name
4261da177e4SLinus Torvalds	jbsr	L(\name)
4271da177e4SLinus Torvalds.endm
4281da177e4SLinus Torvalds
4291da177e4SLinus Torvalds.macro	move_stack	nr,arg1,arg2,arg3,arg4
4301da177e4SLinus Torvalds.if	\nr
4311da177e4SLinus Torvalds	move_stack	"(\nr-1)",\arg2,\arg3,\arg4
4321da177e4SLinus Torvalds	movel	\arg1,%sp@-
4331da177e4SLinus Torvalds.endif
4341da177e4SLinus Torvalds.endm
4351da177e4SLinus Torvalds
4361da177e4SLinus Torvalds.macro	func_define	name,nr=0
4371da177e4SLinus Torvalds.macro	\name	arg1,arg2,arg3,arg4
4381da177e4SLinus Torvalds	move_stack	\nr,\arg1,\arg2,\arg3,\arg4
4391da177e4SLinus Torvalds	func_call	\name
4401da177e4SLinus Torvalds.if	\nr
4411da177e4SLinus Torvalds	lea	%sp@(\nr*4),%sp
4421da177e4SLinus Torvalds.endif
4431da177e4SLinus Torvalds.endm
4441da177e4SLinus Torvalds.endm
4451da177e4SLinus Torvalds
4461da177e4SLinus Torvaldsfunc_define	mmu_map,4
4471da177e4SLinus Torvaldsfunc_define	mmu_map_tt,4
4481da177e4SLinus Torvaldsfunc_define	mmu_fixup_page_mmu_cache,1
4491da177e4SLinus Torvaldsfunc_define	mmu_temp_map,2
4501da177e4SLinus Torvaldsfunc_define	mmu_engage
4511da177e4SLinus Torvaldsfunc_define	mmu_get_root_table_entry,1
4521da177e4SLinus Torvaldsfunc_define	mmu_get_ptr_table_entry,2
4531da177e4SLinus Torvaldsfunc_define	mmu_get_page_table_entry,2
4541da177e4SLinus Torvaldsfunc_define	mmu_print
4551da177e4SLinus Torvaldsfunc_define	get_new_page
4561da177e4SLinus Torvalds#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
4571da177e4SLinus Torvaldsfunc_define	set_leds
4581da177e4SLinus Torvalds#endif
4591da177e4SLinus Torvalds
4601da177e4SLinus Torvalds.macro	mmu_map_eq	arg1,arg2,arg3
4611da177e4SLinus Torvalds	mmu_map	\arg1,\arg1,\arg2,\arg3
4621da177e4SLinus Torvalds.endm
4631da177e4SLinus Torvalds
4641da177e4SLinus Torvalds.macro	get_bi_record	record
4651da177e4SLinus Torvalds	pea	\record
4661da177e4SLinus Torvalds	func_call	get_bi_record
4671da177e4SLinus Torvalds	addql	#4,%sp
4681da177e4SLinus Torvalds.endm
4691da177e4SLinus Torvalds
4701da177e4SLinus Torvaldsfunc_define	serial_putc,1
4711da177e4SLinus Torvaldsfunc_define	console_putc,1
4721da177e4SLinus Torvalds
4731da177e4SLinus Torvaldsfunc_define	console_init
4741da177e4SLinus Torvaldsfunc_define	console_put_penguin
4751da177e4SLinus Torvaldsfunc_define	console_plot_pixel,3
4761da177e4SLinus Torvaldsfunc_define	console_scroll
4771da177e4SLinus Torvalds
4781da177e4SLinus Torvalds.macro	putc	ch
47997f3f68cSFinn Thain#if defined(CONSOLE_DEBUG) || defined(SERIAL_DEBUG)
4801da177e4SLinus Torvalds	pea	\ch
4811da177e4SLinus Torvalds#endif
48297f3f68cSFinn Thain#ifdef CONSOLE_DEBUG
4831da177e4SLinus Torvalds	func_call	console_putc
4841da177e4SLinus Torvalds#endif
4851da177e4SLinus Torvalds#ifdef SERIAL_DEBUG
4861da177e4SLinus Torvalds	func_call	serial_putc
4871da177e4SLinus Torvalds#endif
48897f3f68cSFinn Thain#if defined(CONSOLE_DEBUG) || defined(SERIAL_DEBUG)
4891da177e4SLinus Torvalds	addql	#4,%sp
4901da177e4SLinus Torvalds#endif
4911da177e4SLinus Torvalds.endm
4921da177e4SLinus Torvalds
4931da177e4SLinus Torvalds.macro	dputc	ch
4941da177e4SLinus Torvalds#ifdef DEBUG
4951da177e4SLinus Torvalds	putc	\ch
4961da177e4SLinus Torvalds#endif
4971da177e4SLinus Torvalds.endm
4981da177e4SLinus Torvalds
4991da177e4SLinus Torvaldsfunc_define	putn,1
5001da177e4SLinus Torvalds
5011da177e4SLinus Torvalds.macro	dputn	nr
5021da177e4SLinus Torvalds#ifdef DEBUG
5031da177e4SLinus Torvalds	putn	\nr
5041da177e4SLinus Torvalds#endif
5051da177e4SLinus Torvalds.endm
5061da177e4SLinus Torvalds
5071da177e4SLinus Torvalds.macro	puts		string
50897f3f68cSFinn Thain#if defined(CONSOLE_DEBUG) || defined(SERIAL_DEBUG)
5091da177e4SLinus Torvalds	__INITDATA
5101da177e4SLinus Torvalds.Lstr\@:
5111da177e4SLinus Torvalds	.string	"\string"
5121da177e4SLinus Torvalds	__FINIT
5131da177e4SLinus Torvalds	pea	%pc@(.Lstr\@)
5141da177e4SLinus Torvalds	func_call	puts
5151da177e4SLinus Torvalds	addql	#4,%sp
5161da177e4SLinus Torvalds#endif
5171da177e4SLinus Torvalds.endm
5181da177e4SLinus Torvalds
5191da177e4SLinus Torvalds.macro	dputs	string
5201da177e4SLinus Torvalds#ifdef DEBUG
5211da177e4SLinus Torvalds	puts	"\string"
5221da177e4SLinus Torvalds#endif
5231da177e4SLinus Torvalds.endm
5241da177e4SLinus Torvalds
5251da177e4SLinus Torvalds#define is_not_amiga(lab) cmpl &MACH_AMIGA,%pc@(m68k_machtype); jne lab
5261da177e4SLinus Torvalds#define is_not_atari(lab) cmpl &MACH_ATARI,%pc@(m68k_machtype); jne lab
5271da177e4SLinus Torvalds#define is_not_mac(lab) cmpl &MACH_MAC,%pc@(m68k_machtype); jne lab
5281da177e4SLinus Torvalds#define is_not_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jne lab
5291da177e4SLinus Torvalds#define is_not_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jne lab
5301da177e4SLinus Torvalds#define is_not_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jne lab
5311da177e4SLinus Torvalds#define is_mvme147(lab) cmpl &MACH_MVME147,%pc@(m68k_machtype); jeq lab
5321da177e4SLinus Torvalds#define is_mvme16x(lab) cmpl &MACH_MVME16x,%pc@(m68k_machtype); jeq lab
5331da177e4SLinus Torvalds#define is_bvme6000(lab) cmpl &MACH_BVME6000,%pc@(m68k_machtype); jeq lab
5341da177e4SLinus Torvalds#define is_not_hp300(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); jne lab
5351da177e4SLinus Torvalds#define is_not_apollo(lab) cmpl &MACH_APOLLO,%pc@(m68k_machtype); jne lab
5361da177e4SLinus Torvalds#define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m68k_machtype); jne lab
5371da177e4SLinus Torvalds#define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc@(m68k_machtype); jne lab
538*05d51e42SLaurent Vivier#define is_not_virt(lab) cmpl &MACH_VIRT,%pc@(m68k_machtype); jne lab
5391da177e4SLinus Torvalds
5401da177e4SLinus Torvalds#define hasnt_leds(lab) cmpl &MACH_HP300,%pc@(m68k_machtype); \
5411da177e4SLinus Torvalds			jeq 42f; \
5421da177e4SLinus Torvalds			cmpl &MACH_APOLLO,%pc@(m68k_machtype); \
5431da177e4SLinus Torvalds			jne lab ;\
5441da177e4SLinus Torvalds		42:\
5451da177e4SLinus Torvalds
5461da177e4SLinus Torvalds#define is_040_or_060(lab)	btst &CPUTYPE_0460,%pc@(L(cputype)+3); jne lab
5471da177e4SLinus Torvalds#define is_not_040_or_060(lab)	btst &CPUTYPE_0460,%pc@(L(cputype)+3); jeq lab
5481da177e4SLinus Torvalds#define is_040(lab)		btst &CPUTYPE_040,%pc@(L(cputype)+3); jne lab
5491da177e4SLinus Torvalds#define is_060(lab)		btst &CPUTYPE_060,%pc@(L(cputype)+3); jne lab
5501da177e4SLinus Torvalds#define is_not_060(lab)		btst &CPUTYPE_060,%pc@(L(cputype)+3); jeq lab
5511da177e4SLinus Torvalds#define is_020(lab)		btst &CPUTYPE_020,%pc@(L(cputype)+3); jne lab
5521da177e4SLinus Torvalds#define is_not_020(lab)		btst &CPUTYPE_020,%pc@(L(cputype)+3); jeq lab
5531da177e4SLinus Torvalds
5541da177e4SLinus Torvalds/* On the HP300 we use the on-board LEDs for debug output before
5551da177e4SLinus Torvalds   the console is running.  Writing a 1 bit turns the corresponding LED
5561da177e4SLinus Torvalds   _off_ - on the 340 bit 7 is towards the back panel of the machine.  */
5571da177e4SLinus Torvalds.macro	leds	mask
5581da177e4SLinus Torvalds#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
5591da177e4SLinus Torvalds	hasnt_leds(.Lled\@)
5601da177e4SLinus Torvalds	pea	\mask
5611da177e4SLinus Torvalds	func_call	set_leds
5621da177e4SLinus Torvalds	addql	#4,%sp
5631da177e4SLinus Torvalds.Lled\@:
5641da177e4SLinus Torvalds#endif
5651da177e4SLinus Torvalds.endm
5661da177e4SLinus Torvalds
5676f335cabSTim Abbott__HEAD
5681da177e4SLinus TorvaldsENTRY(_stext)
5691da177e4SLinus Torvalds/*
5701da177e4SLinus Torvalds * Version numbers of the bootinfo interface
5711da177e4SLinus Torvalds * The area from _stext to _start will later be used as kernel pointer table
5721da177e4SLinus Torvalds */
5731da177e4SLinus Torvalds	bras	1f	/* Jump over bootinfo version numbers */
5741da177e4SLinus Torvalds
5751da177e4SLinus Torvalds	.long	BOOTINFOV_MAGIC
5761da177e4SLinus Torvalds	.long	MACH_AMIGA, AMIGA_BOOTI_VERSION
5771da177e4SLinus Torvalds	.long	MACH_ATARI, ATARI_BOOTI_VERSION
5781da177e4SLinus Torvalds	.long	MACH_MVME147, MVME147_BOOTI_VERSION
5791da177e4SLinus Torvalds	.long	MACH_MVME16x, MVME16x_BOOTI_VERSION
5801da177e4SLinus Torvalds	.long	MACH_BVME6000, BVME6000_BOOTI_VERSION
5811da177e4SLinus Torvalds	.long	MACH_MAC, MAC_BOOTI_VERSION
5821da177e4SLinus Torvalds	.long	MACH_Q40, Q40_BOOTI_VERSION
5831da177e4SLinus Torvalds	.long	MACH_HP300, HP300_BOOTI_VERSION
5841da177e4SLinus Torvalds	.long	0
5851da177e4SLinus Torvalds1:	jra	__start
5861da177e4SLinus Torvalds
5871da177e4SLinus Torvalds.equ	kernel_pg_dir,_stext
5881da177e4SLinus Torvalds
5891da177e4SLinus Torvalds.equ	.,_stext+PAGESIZE
5901da177e4SLinus Torvalds
5911da177e4SLinus TorvaldsENTRY(_start)
5921da177e4SLinus Torvalds	jra	__start
5931da177e4SLinus Torvalds__INIT
5941da177e4SLinus TorvaldsENTRY(__start)
5951da177e4SLinus Torvalds/*
5961da177e4SLinus Torvalds * Setup initial stack pointer
5971da177e4SLinus Torvalds */
5981da177e4SLinus Torvalds	lea	%pc@(_stext),%sp
5991da177e4SLinus Torvalds
6001da177e4SLinus Torvalds/*
6011da177e4SLinus Torvalds * Record the CPU and machine type.
6021da177e4SLinus Torvalds */
6031da177e4SLinus Torvalds	get_bi_record	BI_MACHTYPE
6041da177e4SLinus Torvalds	lea	%pc@(m68k_machtype),%a1
6051da177e4SLinus Torvalds	movel	%a0@,%a1@
6061da177e4SLinus Torvalds
6071da177e4SLinus Torvalds	get_bi_record	BI_FPUTYPE
6081da177e4SLinus Torvalds	lea	%pc@(m68k_fputype),%a1
6091da177e4SLinus Torvalds	movel	%a0@,%a1@
6101da177e4SLinus Torvalds
6111da177e4SLinus Torvalds	get_bi_record	BI_MMUTYPE
6121da177e4SLinus Torvalds	lea	%pc@(m68k_mmutype),%a1
6131da177e4SLinus Torvalds	movel	%a0@,%a1@
6141da177e4SLinus Torvalds
6151da177e4SLinus Torvalds	get_bi_record	BI_CPUTYPE
6161da177e4SLinus Torvalds	lea	%pc@(m68k_cputype),%a1
6171da177e4SLinus Torvalds	movel	%a0@,%a1@
6181da177e4SLinus Torvalds
6191da177e4SLinus Torvalds	leds	0x1
6201da177e4SLinus Torvalds
6211da177e4SLinus Torvalds#ifdef CONFIG_MAC
6221da177e4SLinus Torvalds/*
6231da177e4SLinus Torvalds * For Macintosh, we need to determine the display parameters early (at least
6241da177e4SLinus Torvalds * while debugging it).
6251da177e4SLinus Torvalds */
6261da177e4SLinus Torvalds
6271da177e4SLinus Torvalds	is_not_mac(L(test_notmac))
6281da177e4SLinus Torvalds
6291da177e4SLinus Torvalds	get_bi_record	BI_MAC_VADDR
6301da177e4SLinus Torvalds	lea	%pc@(L(mac_videobase)),%a1
6311da177e4SLinus Torvalds	movel	%a0@,%a1@
6321da177e4SLinus Torvalds
6331da177e4SLinus Torvalds	get_bi_record	BI_MAC_VDEPTH
6341da177e4SLinus Torvalds	lea	%pc@(L(mac_videodepth)),%a1
6351da177e4SLinus Torvalds	movel	%a0@,%a1@
6361da177e4SLinus Torvalds
6371da177e4SLinus Torvalds	get_bi_record	BI_MAC_VDIM
6381da177e4SLinus Torvalds	lea	%pc@(L(mac_dimensions)),%a1
6391da177e4SLinus Torvalds	movel	%a0@,%a1@
6401da177e4SLinus Torvalds
6411da177e4SLinus Torvalds	get_bi_record	BI_MAC_VROW
6421da177e4SLinus Torvalds	lea	%pc@(L(mac_rowbytes)),%a1
6431da177e4SLinus Torvalds	movel	%a0@,%a1@
6441da177e4SLinus Torvalds
6451da177e4SLinus Torvalds	get_bi_record	BI_MAC_SCCBASE
6461da177e4SLinus Torvalds	lea	%pc@(L(mac_sccbase)),%a1
6471da177e4SLinus Torvalds	movel	%a0@,%a1@
6481da177e4SLinus Torvalds
6491da177e4SLinus TorvaldsL(test_notmac):
6501da177e4SLinus Torvalds#endif /* CONFIG_MAC */
6511da177e4SLinus Torvalds
652*05d51e42SLaurent Vivier#ifdef CONFIG_VIRT
653*05d51e42SLaurent Vivier	is_not_virt(L(test_notvirt))
654*05d51e42SLaurent Vivier
655*05d51e42SLaurent Vivier	get_bi_record BI_VIRT_GF_TTY_BASE
656*05d51e42SLaurent Vivier	lea	%pc@(L(virt_gf_tty_base)),%a1
657*05d51e42SLaurent Vivier	movel	%a0@,%a1@
658*05d51e42SLaurent VivierL(test_notvirt):
659*05d51e42SLaurent Vivier#endif /* CONFIG_VIRT */
6601da177e4SLinus Torvalds
6611da177e4SLinus Torvalds/*
6621da177e4SLinus Torvalds * There are ultimately two pieces of information we want for all kinds of
6631da177e4SLinus Torvalds * processors CpuType and CacheBits.  The CPUTYPE was passed in from booter
6641da177e4SLinus Torvalds * and is converted here from a booter type definition to a separate bit
6651da177e4SLinus Torvalds * number which allows for the standard is_0x0 macro tests.
6661da177e4SLinus Torvalds */
6671da177e4SLinus Torvalds	movel	%pc@(m68k_cputype),%d0
6681da177e4SLinus Torvalds	/*
6691da177e4SLinus Torvalds	 * Assume it's an 030
6701da177e4SLinus Torvalds	 */
6711da177e4SLinus Torvalds	clrl	%d1
6721da177e4SLinus Torvalds
6731da177e4SLinus Torvalds	/*
6741da177e4SLinus Torvalds	 * Test the BootInfo cputype for 060
6751da177e4SLinus Torvalds	 */
6761da177e4SLinus Torvalds	btst	#CPUB_68060,%d0
6771da177e4SLinus Torvalds	jeq	1f
6781da177e4SLinus Torvalds	bset	#CPUTYPE_060,%d1
6791da177e4SLinus Torvalds	bset	#CPUTYPE_0460,%d1
6801da177e4SLinus Torvalds	jra	3f
6811da177e4SLinus Torvalds1:
6821da177e4SLinus Torvalds	/*
6831da177e4SLinus Torvalds	 * Test the BootInfo cputype for 040
6841da177e4SLinus Torvalds	 */
6851da177e4SLinus Torvalds	btst	#CPUB_68040,%d0
6861da177e4SLinus Torvalds	jeq	2f
6871da177e4SLinus Torvalds	bset	#CPUTYPE_040,%d1
6881da177e4SLinus Torvalds	bset	#CPUTYPE_0460,%d1
6891da177e4SLinus Torvalds	jra	3f
6901da177e4SLinus Torvalds2:
6911da177e4SLinus Torvalds	/*
6921da177e4SLinus Torvalds	 * Test the BootInfo cputype for 020
6931da177e4SLinus Torvalds	 */
6941da177e4SLinus Torvalds	btst	#CPUB_68020,%d0
6951da177e4SLinus Torvalds	jeq	3f
6961da177e4SLinus Torvalds	bset	#CPUTYPE_020,%d1
6971da177e4SLinus Torvalds	jra	3f
6981da177e4SLinus Torvalds3:
6991da177e4SLinus Torvalds	/*
7001da177e4SLinus Torvalds	 * Record the cpu type
7011da177e4SLinus Torvalds	 */
7021da177e4SLinus Torvalds	lea	%pc@(L(cputype)),%a0
7031da177e4SLinus Torvalds	movel	%d1,%a0@
7041da177e4SLinus Torvalds
7051da177e4SLinus Torvalds	/*
7061da177e4SLinus Torvalds	 * NOTE:
7071da177e4SLinus Torvalds	 *
7081da177e4SLinus Torvalds	 * Now the macros are valid:
7091da177e4SLinus Torvalds	 *	is_040_or_060
7101da177e4SLinus Torvalds	 *	is_not_040_or_060
7111da177e4SLinus Torvalds	 *	is_040
7121da177e4SLinus Torvalds	 *	is_060
7131da177e4SLinus Torvalds	 *	is_not_060
7141da177e4SLinus Torvalds	 */
7151da177e4SLinus Torvalds
7161da177e4SLinus Torvalds	/*
7171da177e4SLinus Torvalds	 * Determine the cache mode for pages holding MMU tables
7181da177e4SLinus Torvalds	 * and for supervisor mode, unused for '020 and '030
7191da177e4SLinus Torvalds	 */
7201da177e4SLinus Torvalds	clrl	%d0
7211da177e4SLinus Torvalds	clrl	%d1
7221da177e4SLinus Torvalds
7231da177e4SLinus Torvalds	is_not_040_or_060(L(save_cachetype))
7241da177e4SLinus Torvalds
7251da177e4SLinus Torvalds	/*
7261da177e4SLinus Torvalds	 * '040 or '060
7271da177e4SLinus Torvalds	 * d1 := cacheable write-through
7281da177e4SLinus Torvalds	 * NOTE: The 68040 manual strongly recommends non-cached for MMU tables,
7291da177e4SLinus Torvalds	 * but we have been using write-through since at least 2.0.29 so I
7301da177e4SLinus Torvalds	 * guess it is OK.
7311da177e4SLinus Torvalds	 */
7321da177e4SLinus Torvalds#ifdef CONFIG_060_WRITETHROUGH
7331da177e4SLinus Torvalds	/*
7341da177e4SLinus Torvalds	 * If this is a 68060 board using drivers with cache coherency
7351da177e4SLinus Torvalds	 * problems, then supervisor memory accesses need to be write-through
7361da177e4SLinus Torvalds	 * also; otherwise, we want copyback.
7371da177e4SLinus Torvalds	 */
7381da177e4SLinus Torvalds
7391da177e4SLinus Torvalds	is_not_060(1f)
7401da177e4SLinus Torvalds	movel	#_PAGE_CACHE040W,%d0
7411da177e4SLinus Torvalds	jra	L(save_cachetype)
7421da177e4SLinus Torvalds#endif /* CONFIG_060_WRITETHROUGH */
7431da177e4SLinus Torvalds1:
7441da177e4SLinus Torvalds	movew	#_PAGE_CACHE040,%d0
7451da177e4SLinus Torvalds
7461da177e4SLinus Torvalds	movel	#_PAGE_CACHE040W,%d1
7471da177e4SLinus Torvalds
7481da177e4SLinus TorvaldsL(save_cachetype):
7491da177e4SLinus Torvalds	/* Save cache mode for supervisor mode and page tables
7501da177e4SLinus Torvalds	 */
7511da177e4SLinus Torvalds	lea	%pc@(m68k_supervisor_cachemode),%a0
7521da177e4SLinus Torvalds	movel	%d0,%a0@
7531da177e4SLinus Torvalds	lea	%pc@(m68k_pgtable_cachemode),%a0
7541da177e4SLinus Torvalds	movel	%d1,%a0@
7551da177e4SLinus Torvalds
7561da177e4SLinus Torvalds/*
7571da177e4SLinus Torvalds * raise interrupt level
7581da177e4SLinus Torvalds */
7591da177e4SLinus Torvalds	movew	#0x2700,%sr
7601da177e4SLinus Torvalds
7611da177e4SLinus Torvalds/*
7621da177e4SLinus Torvalds   If running on an Atari, determine the I/O base of the
7631da177e4SLinus Torvalds   serial port and test if we are running on a Medusa or Hades.
7641da177e4SLinus Torvalds   This test is necessary here, because on the Hades the serial
7651da177e4SLinus Torvalds   port is only accessible in the high I/O memory area.
7661da177e4SLinus Torvalds
7671da177e4SLinus Torvalds   The test whether it is a Medusa is done by writing to the byte at
7681da177e4SLinus Torvalds   phys. 0x0. This should result in a bus error on all other machines.
7691da177e4SLinus Torvalds
7701da177e4SLinus Torvalds   ...should, but doesn't. The Afterburner040 for the Falcon has the
7711da177e4SLinus Torvalds   same behaviour (0x0..0x7 are no ROM shadow). So we have to do
7721da177e4SLinus Torvalds   another test to distinguish Medusa and AB040. This is a
7731da177e4SLinus Torvalds   read attempt for 0x00ff82fe phys. that should bus error on a Falcon
7741da177e4SLinus Torvalds   (+AB040), but is in the range where the Medusa always asserts DTACK.
7751da177e4SLinus Torvalds
7761da177e4SLinus Torvalds   The test for the Hades is done by reading address 0xb0000000. This
7771da177e4SLinus Torvalds   should give a bus error on the Medusa.
7781da177e4SLinus Torvalds */
7791da177e4SLinus Torvalds
7801da177e4SLinus Torvalds#ifdef CONFIG_ATARI
7811da177e4SLinus Torvalds	is_not_atari(L(notypetest))
7821da177e4SLinus Torvalds
7831da177e4SLinus Torvalds	/* get special machine type (Medusa/Hades/AB40) */
7841da177e4SLinus Torvalds	moveq	#0,%d3 /* default if tag doesn't exist */
7851da177e4SLinus Torvalds	get_bi_record	BI_ATARI_MCH_TYPE
7861da177e4SLinus Torvalds	tstl	%d0
7871da177e4SLinus Torvalds	jbmi	1f
7881da177e4SLinus Torvalds	movel	%a0@,%d3
7891da177e4SLinus Torvalds	lea	%pc@(atari_mch_type),%a0
7901da177e4SLinus Torvalds	movel	%d3,%a0@
7911da177e4SLinus Torvalds1:
7921da177e4SLinus Torvalds	/* On the Hades, the iobase must be set up before opening the
7931da177e4SLinus Torvalds	 * serial port. There are no I/O regs at 0x00ffxxxx at all. */
7941da177e4SLinus Torvalds	moveq	#0,%d0
7951da177e4SLinus Torvalds	cmpl	#ATARI_MACH_HADES,%d3
7961da177e4SLinus Torvalds	jbne	1f
7971da177e4SLinus Torvalds	movel	#0xff000000,%d0		/* Hades I/O base addr: 0xff000000 */
7981da177e4SLinus Torvalds1:	lea     %pc@(L(iobase)),%a0
7991da177e4SLinus Torvalds	movel   %d0,%a0@
8001da177e4SLinus Torvalds
8011da177e4SLinus TorvaldsL(notypetest):
8021da177e4SLinus Torvalds#endif
8031da177e4SLinus Torvalds
8041da177e4SLinus Torvalds#ifdef CONFIG_VME
8051da177e4SLinus Torvalds	is_mvme147(L(getvmetype))
8061da177e4SLinus Torvalds	is_bvme6000(L(getvmetype))
8071da177e4SLinus Torvalds	is_not_mvme16x(L(gvtdone))
8081da177e4SLinus Torvalds
8091da177e4SLinus Torvalds	/* See if the loader has specified the BI_VME_TYPE tag.  Recent
8101da177e4SLinus Torvalds	 * versions of VMELILO and TFTPLILO do this.  We have to do this
8111da177e4SLinus Torvalds	 * early so we know how to handle console output.  If the tag
8121da177e4SLinus Torvalds	 * doesn't exist then we use the Bug for output on MVME16x.
8131da177e4SLinus Torvalds	 */
8141da177e4SLinus TorvaldsL(getvmetype):
8151da177e4SLinus Torvalds	get_bi_record	BI_VME_TYPE
8161da177e4SLinus Torvalds	tstl	%d0
8171da177e4SLinus Torvalds	jbmi	1f
8181da177e4SLinus Torvalds	movel	%a0@,%d3
8191da177e4SLinus Torvalds	lea	%pc@(vme_brdtype),%a0
8201da177e4SLinus Torvalds	movel	%d3,%a0@
8211da177e4SLinus Torvalds1:
8221da177e4SLinus Torvalds#ifdef CONFIG_MVME16x
8231da177e4SLinus Torvalds	is_not_mvme16x(L(gvtdone))
8241da177e4SLinus Torvalds
8251da177e4SLinus Torvalds	/* Need to get the BRD_ID info to differentiate between 162, 167,
8261da177e4SLinus Torvalds	 * etc.  This is available as a BI_VME_BRDINFO tag with later
8271da177e4SLinus Torvalds	 * versions of VMELILO and TFTPLILO, otherwise we call the Bug.
8281da177e4SLinus Torvalds	 */
8291da177e4SLinus Torvalds	get_bi_record	BI_VME_BRDINFO
8301da177e4SLinus Torvalds	tstl	%d0
8311da177e4SLinus Torvalds	jpl	1f
8321da177e4SLinus Torvalds
8331da177e4SLinus Torvalds	/* Get pointer to board ID data from Bug */
8341da177e4SLinus Torvalds	movel	%d2,%sp@-
8351da177e4SLinus Torvalds	trap	#15
8361da177e4SLinus Torvalds	.word	0x70		/* trap 0x70 - .BRD_ID */
8371da177e4SLinus Torvalds	movel	%sp@+,%a0
8381da177e4SLinus Torvalds1:
8391da177e4SLinus Torvalds	lea	%pc@(mvme_bdid),%a1
8401da177e4SLinus Torvalds	/* Structure is 32 bytes long */
8411da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8421da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8431da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8441da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8451da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8461da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8471da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8481da177e4SLinus Torvalds	movel	%a0@+,%a1@+
8491da177e4SLinus Torvalds#endif
8501da177e4SLinus Torvalds
8511da177e4SLinus TorvaldsL(gvtdone):
8521da177e4SLinus Torvalds
8531da177e4SLinus Torvalds#endif
8541da177e4SLinus Torvalds
8551da177e4SLinus Torvalds#ifdef CONFIG_HP300
8561da177e4SLinus Torvalds	is_not_hp300(L(nothp))
8571da177e4SLinus Torvalds
8581da177e4SLinus Torvalds	/* Get the address of the UART for serial debugging */
8591da177e4SLinus Torvalds	get_bi_record	BI_HP300_UART_ADDR
8601da177e4SLinus Torvalds	tstl	%d0
8611da177e4SLinus Torvalds	jbmi	1f
8621da177e4SLinus Torvalds	movel	%a0@,%d3
8631da177e4SLinus Torvalds	lea	%pc@(L(uartbase)),%a0
8641da177e4SLinus Torvalds	movel	%d3,%a0@
8651da177e4SLinus Torvalds	get_bi_record	BI_HP300_UART_SCODE
8661da177e4SLinus Torvalds	tstl	%d0
8671da177e4SLinus Torvalds	jbmi	1f
8681da177e4SLinus Torvalds	movel	%a0@,%d3
8691da177e4SLinus Torvalds	lea	%pc@(L(uart_scode)),%a0
8701da177e4SLinus Torvalds	movel	%d3,%a0@
8711da177e4SLinus Torvalds1:
8721da177e4SLinus TorvaldsL(nothp):
8731da177e4SLinus Torvalds#endif
8741da177e4SLinus Torvalds
8751da177e4SLinus Torvalds/*
8761da177e4SLinus Torvalds * Initialize serial port
8771da177e4SLinus Torvalds */
8781da177e4SLinus Torvalds	jbsr	L(serial_init)
8791da177e4SLinus Torvalds
8801da177e4SLinus Torvalds/*
8811da177e4SLinus Torvalds * Initialize console
8821da177e4SLinus Torvalds */
8831da177e4SLinus Torvalds#ifdef CONFIG_MAC
8841da177e4SLinus Torvalds	is_not_mac(L(nocon))
88597f3f68cSFinn Thain#  ifdef CONSOLE_DEBUG
8861da177e4SLinus Torvalds	console_init
887a91c406cSFinn Thain#    ifdef CONFIG_LOGO
8881da177e4SLinus Torvalds	console_put_penguin
889a91c406cSFinn Thain#    endif /* CONFIG_LOGO */
89097f3f68cSFinn Thain#  endif /* CONSOLE_DEBUG */
8911da177e4SLinus TorvaldsL(nocon):
8921da177e4SLinus Torvalds#endif /* CONFIG_MAC */
8931da177e4SLinus Torvalds
8941da177e4SLinus Torvalds
8951da177e4SLinus Torvalds	putc	'\n'
8961da177e4SLinus Torvalds	putc	'A'
8971da177e4SLinus Torvalds	leds	0x2
8981da177e4SLinus Torvalds	dputn	%pc@(L(cputype))
8991da177e4SLinus Torvalds	dputn	%pc@(m68k_supervisor_cachemode)
9001da177e4SLinus Torvalds	dputn	%pc@(m68k_pgtable_cachemode)
9011da177e4SLinus Torvalds	dputc	'\n'
9021da177e4SLinus Torvalds
9031da177e4SLinus Torvalds/*
9041da177e4SLinus Torvalds * Save physical start address of kernel
9051da177e4SLinus Torvalds */
9061da177e4SLinus Torvalds	lea	%pc@(L(phys_kernel_start)),%a0
9071da177e4SLinus Torvalds	lea	%pc@(_stext),%a1
9081da177e4SLinus Torvalds	subl	#_stext,%a1
9091da177e4SLinus Torvalds	addl	#PAGE_OFFSET,%a1
9101da177e4SLinus Torvalds	movel	%a1,%a0@
9111da177e4SLinus Torvalds
9121da177e4SLinus Torvalds	putc	'B'
9131da177e4SLinus Torvalds
9141da177e4SLinus Torvalds	leds	0x4
9151da177e4SLinus Torvalds
9161da177e4SLinus Torvalds/*
9171da177e4SLinus Torvalds *	mmu_init
9181da177e4SLinus Torvalds *
9191da177e4SLinus Torvalds *	This block of code does what's necessary to map in the various kinds
9201da177e4SLinus Torvalds *	of machines for execution of Linux.
921486df8bcSAndreas Schwab *	First map the first 4, 8, or 16 MB of kernel code & data
9221da177e4SLinus Torvalds */
9231da177e4SLinus Torvalds
924486df8bcSAndreas Schwab	get_bi_record BI_MEMCHUNK
925486df8bcSAndreas Schwab	movel	%a0@(4),%d0
926486df8bcSAndreas Schwab	movel	#16*1024*1024,%d1
927486df8bcSAndreas Schwab	cmpl	%d0,%d1
928486df8bcSAndreas Schwab	jls	1f
929486df8bcSAndreas Schwab	lsrl	#1,%d1
930486df8bcSAndreas Schwab	cmpl	%d0,%d1
931486df8bcSAndreas Schwab	jls	1f
932486df8bcSAndreas Schwab	lsrl	#1,%d1
933486df8bcSAndreas Schwab1:
934f1a1b635SGeert Uytterhoeven	lea	%pc@(m68k_init_mapped_size),%a0
935f1a1b635SGeert Uytterhoeven	movel	%d1,%a0@
936486df8bcSAndreas Schwab	mmu_map	#PAGE_OFFSET,%pc@(L(phys_kernel_start)),%d1,\
9371da177e4SLinus Torvalds		%pc@(m68k_supervisor_cachemode)
9381da177e4SLinus Torvalds
9391da177e4SLinus Torvalds	putc	'C'
9401da177e4SLinus Torvalds
9411da177e4SLinus Torvalds#ifdef CONFIG_AMIGA
9421da177e4SLinus Torvalds
9431da177e4SLinus TorvaldsL(mmu_init_amiga):
9441da177e4SLinus Torvalds
9451da177e4SLinus Torvalds	is_not_amiga(L(mmu_init_not_amiga))
9461da177e4SLinus Torvalds/*
9471da177e4SLinus Torvalds * mmu_init_amiga
9481da177e4SLinus Torvalds */
9491da177e4SLinus Torvalds
9501da177e4SLinus Torvalds	putc	'D'
9511da177e4SLinus Torvalds
9521da177e4SLinus Torvalds	is_not_040_or_060(1f)
9531da177e4SLinus Torvalds
9541da177e4SLinus Torvalds	/*
9551da177e4SLinus Torvalds	 * 040: Map the 16Meg range physical 0x0 up to logical 0x8000.0000
9561da177e4SLinus Torvalds	 */
9571da177e4SLinus Torvalds	mmu_map		#0x80000000,#0,#0x01000000,#_PAGE_NOCACHE_S
9581da177e4SLinus Torvalds	/*
9591da177e4SLinus Torvalds	 * Map the Zorro III I/O space with transparent translation
9601da177e4SLinus Torvalds	 * for frame buffer memory etc.
9611da177e4SLinus Torvalds	 */
9621da177e4SLinus Torvalds	mmu_map_tt	#1,#0x40000000,#0x20000000,#_PAGE_NOCACHE_S
9631da177e4SLinus Torvalds
9641da177e4SLinus Torvalds	jbra	L(mmu_init_done)
9651da177e4SLinus Torvalds
9661da177e4SLinus Torvalds1:
9671da177e4SLinus Torvalds	/*
9681da177e4SLinus Torvalds	 * 030:	Map the 32Meg range physical 0x0 up to logical 0x8000.0000
9691da177e4SLinus Torvalds	 */
9701da177e4SLinus Torvalds	mmu_map		#0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
9711da177e4SLinus Torvalds	mmu_map_tt	#1,#0x40000000,#0x20000000,#_PAGE_NOCACHE030
9721da177e4SLinus Torvalds
9731da177e4SLinus Torvalds	jbra	L(mmu_init_done)
9741da177e4SLinus Torvalds
9751da177e4SLinus TorvaldsL(mmu_init_not_amiga):
9761da177e4SLinus Torvalds#endif
9771da177e4SLinus Torvalds
9781da177e4SLinus Torvalds#ifdef CONFIG_ATARI
9791da177e4SLinus Torvalds
9801da177e4SLinus TorvaldsL(mmu_init_atari):
9811da177e4SLinus Torvalds
9821da177e4SLinus Torvalds	is_not_atari(L(mmu_init_not_atari))
9831da177e4SLinus Torvalds
9841da177e4SLinus Torvalds	putc	'E'
9851da177e4SLinus Torvalds
9861da177e4SLinus Torvalds/* On the Atari, we map the I/O region (phys. 0x00ffxxxx) by mapping
9871da177e4SLinus Torvalds   the last 16 MB of virtual address space to the first 16 MB (i.e.
9881da177e4SLinus Torvalds   0xffxxxxxx -> 0x00xxxxxx). For this, an additional pointer table is
9891da177e4SLinus Torvalds   needed. I/O ranges are marked non-cachable.
9901da177e4SLinus Torvalds
9911da177e4SLinus Torvalds   For the Medusa it is better to map the I/O region transparently
9921da177e4SLinus Torvalds   (i.e. 0xffxxxxxx -> 0xffxxxxxx), because some I/O registers are
9931da177e4SLinus Torvalds   accessible only in the high area.
9941da177e4SLinus Torvalds
9951da177e4SLinus Torvalds   On the Hades all I/O registers are only accessible in the high
9961da177e4SLinus Torvalds   area.
9971da177e4SLinus Torvalds*/
9981da177e4SLinus Torvalds
9991da177e4SLinus Torvalds	/* I/O base addr for non-Medusa, non-Hades: 0x00000000 */
10001da177e4SLinus Torvalds	moveq	#0,%d0
10011da177e4SLinus Torvalds	movel	%pc@(atari_mch_type),%d3
10021da177e4SLinus Torvalds	cmpl	#ATARI_MACH_MEDUSA,%d3
10031da177e4SLinus Torvalds	jbeq	2f
10041da177e4SLinus Torvalds	cmpl	#ATARI_MACH_HADES,%d3
10051da177e4SLinus Torvalds	jbne	1f
10061da177e4SLinus Torvalds2:	movel	#0xff000000,%d0 /* Medusa/Hades base addr: 0xff000000 */
10071da177e4SLinus Torvalds1:	movel	%d0,%d3
10081da177e4SLinus Torvalds
10091da177e4SLinus Torvalds	is_040_or_060(L(spata68040))
10101da177e4SLinus Torvalds
10111da177e4SLinus Torvalds	/* Map everything non-cacheable, though not all parts really
10121da177e4SLinus Torvalds	 * need to disable caches (crucial only for 0xff8000..0xffffff
10131da177e4SLinus Torvalds	 * (standard I/O) and 0xf00000..0xf3ffff (IDE)). The remainder
10141da177e4SLinus Torvalds	 * isn't really used, except for sometimes peeking into the
10151da177e4SLinus Torvalds	 * ROMs (mirror at phys. 0x0), so caching isn't necessary for
10161da177e4SLinus Torvalds	 * this. */
10171da177e4SLinus Torvalds	mmu_map	#0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE030
10181da177e4SLinus Torvalds
10191da177e4SLinus Torvalds	jbra	L(mmu_init_done)
10201da177e4SLinus Torvalds
10211da177e4SLinus TorvaldsL(spata68040):
10221da177e4SLinus Torvalds
10231da177e4SLinus Torvalds	mmu_map	#0xff000000,%d3,#0x01000000,#_PAGE_NOCACHE_S
10241da177e4SLinus Torvalds
10251da177e4SLinus Torvalds	jbra	L(mmu_init_done)
10261da177e4SLinus Torvalds
10271da177e4SLinus TorvaldsL(mmu_init_not_atari):
10281da177e4SLinus Torvalds#endif
10291da177e4SLinus Torvalds
10301da177e4SLinus Torvalds#ifdef CONFIG_Q40
10311da177e4SLinus Torvalds	is_not_q40(L(notq40))
10321da177e4SLinus Torvalds	/*
10331da177e4SLinus Torvalds	 * add transparent mapping for 0xff00 0000 - 0xffff ffff
10341da177e4SLinus Torvalds	 * non-cached serialized etc..
10351da177e4SLinus Torvalds	 * this includes master chip, DAC, RTC and ISA ports
10361da177e4SLinus Torvalds	 * 0xfe000000-0xfeffffff is for screen and ROM
10371da177e4SLinus Torvalds	 */
10381da177e4SLinus Torvalds
10391da177e4SLinus Torvalds	putc    'Q'
10401da177e4SLinus Torvalds
10411da177e4SLinus Torvalds	mmu_map_tt	#0,#0xfe000000,#0x01000000,#_PAGE_CACHE040W
10421da177e4SLinus Torvalds	mmu_map_tt	#1,#0xff000000,#0x01000000,#_PAGE_NOCACHE_S
10431da177e4SLinus Torvalds
10441da177e4SLinus Torvalds	jbra	L(mmu_init_done)
10451da177e4SLinus Torvalds
10461da177e4SLinus TorvaldsL(notq40):
10471da177e4SLinus Torvalds#endif
10481da177e4SLinus Torvalds
10491da177e4SLinus Torvalds#ifdef CONFIG_HP300
10501da177e4SLinus Torvalds	is_not_hp300(L(nothp300))
10511da177e4SLinus Torvalds
10521da177e4SLinus Torvalds	/* On the HP300, we map the ROM, INTIO and DIO regions (phys. 0x00xxxxxx)
10531da177e4SLinus Torvalds	 * by mapping 32MB (on 020/030) or 16 MB (on 040) from 0xf0xxxxxx -> 0x00xxxxxx).
10541da177e4SLinus Torvalds	 * The ROM mapping is needed because the LEDs are mapped there too.
10551da177e4SLinus Torvalds	 */
10561da177e4SLinus Torvalds
10571da177e4SLinus Torvalds	is_040(1f)
10581da177e4SLinus Torvalds
10591da177e4SLinus Torvalds	/*
10601da177e4SLinus Torvalds	 * 030: Map the 32Meg range physical 0x0 up to logical 0xf000.0000
10611da177e4SLinus Torvalds	 */
10621da177e4SLinus Torvalds	mmu_map	#0xf0000000,#0,#0x02000000,#_PAGE_NOCACHE030
10631da177e4SLinus Torvalds
10641da177e4SLinus Torvalds	jbra	L(mmu_init_done)
10651da177e4SLinus Torvalds
10661da177e4SLinus Torvalds1:
10671da177e4SLinus Torvalds	/*
10681da177e4SLinus Torvalds	 * 040: Map the 16Meg range physical 0x0 up to logical 0xf000.0000
10691da177e4SLinus Torvalds	 */
10701da177e4SLinus Torvalds	mmu_map #0xf0000000,#0,#0x01000000,#_PAGE_NOCACHE_S
10711da177e4SLinus Torvalds
10721da177e4SLinus Torvalds	jbra	L(mmu_init_done)
10731da177e4SLinus Torvalds
10741da177e4SLinus TorvaldsL(nothp300):
10751da177e4SLinus Torvalds#endif /* CONFIG_HP300 */
10761da177e4SLinus Torvalds
10771da177e4SLinus Torvalds#ifdef CONFIG_MVME147
10781da177e4SLinus Torvalds
10791da177e4SLinus Torvalds	is_not_mvme147(L(not147))
10801da177e4SLinus Torvalds
10811da177e4SLinus Torvalds	/*
10821da177e4SLinus Torvalds	 * On MVME147 we have already created kernel page tables for
10831da177e4SLinus Torvalds	 * 4MB of RAM at address 0, so now need to do a transparent
10841da177e4SLinus Torvalds	 * mapping of the top of memory space.  Make it 0.5GByte for now,
10851da177e4SLinus Torvalds	 * so we can access on-board i/o areas.
10861da177e4SLinus Torvalds	 */
10871da177e4SLinus Torvalds
10881da177e4SLinus Torvalds	mmu_map_tt	#1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE030
10891da177e4SLinus Torvalds
10901da177e4SLinus Torvalds	jbra	L(mmu_init_done)
10911da177e4SLinus Torvalds
10921da177e4SLinus TorvaldsL(not147):
10931da177e4SLinus Torvalds#endif /* CONFIG_MVME147 */
10941da177e4SLinus Torvalds
10951da177e4SLinus Torvalds#ifdef CONFIG_MVME16x
10961da177e4SLinus Torvalds
10971da177e4SLinus Torvalds	is_not_mvme16x(L(not16x))
10981da177e4SLinus Torvalds
10991da177e4SLinus Torvalds	/*
11001da177e4SLinus Torvalds	 * On MVME16x we have already created kernel page tables for
11011da177e4SLinus Torvalds	 * 4MB of RAM at address 0, so now need to do a transparent
11021da177e4SLinus Torvalds	 * mapping of the top of memory space.  Make it 0.5GByte for now.
11031da177e4SLinus Torvalds	 * Supervisor only access, so transparent mapping doesn't
11041da177e4SLinus Torvalds	 * clash with User code virtual address space.
11051da177e4SLinus Torvalds	 * this covers IO devices, PROM and SRAM.  The PROM and SRAM
11061da177e4SLinus Torvalds	 * mapping is needed to allow 167Bug to run.
11071da177e4SLinus Torvalds	 * IO is in the range 0xfff00000 to 0xfffeffff.
11081da177e4SLinus Torvalds	 * PROM is 0xff800000->0xffbfffff and SRAM is
11091da177e4SLinus Torvalds	 * 0xffe00000->0xffe1ffff.
11101da177e4SLinus Torvalds	 */
11111da177e4SLinus Torvalds
11121da177e4SLinus Torvalds	mmu_map_tt	#1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
11131da177e4SLinus Torvalds
11141da177e4SLinus Torvalds	jbra	L(mmu_init_done)
11151da177e4SLinus Torvalds
11161da177e4SLinus TorvaldsL(not16x):
11171da177e4SLinus Torvalds#endif	/* CONFIG_MVME162 | CONFIG_MVME167 */
11181da177e4SLinus Torvalds
11191da177e4SLinus Torvalds#ifdef CONFIG_BVME6000
11201da177e4SLinus Torvalds
11211da177e4SLinus Torvalds	is_not_bvme6000(L(not6000))
11221da177e4SLinus Torvalds
11231da177e4SLinus Torvalds	/*
11241da177e4SLinus Torvalds	 * On BVME6000 we have already created kernel page tables for
11251da177e4SLinus Torvalds	 * 4MB of RAM at address 0, so now need to do a transparent
11261da177e4SLinus Torvalds	 * mapping of the top of memory space.  Make it 0.5GByte for now,
11271da177e4SLinus Torvalds	 * so we can access on-board i/o areas.
11281da177e4SLinus Torvalds	 * Supervisor only access, so transparent mapping doesn't
11291da177e4SLinus Torvalds	 * clash with User code virtual address space.
11301da177e4SLinus Torvalds	 */
11311da177e4SLinus Torvalds
11321da177e4SLinus Torvalds	mmu_map_tt	#1,#0xe0000000,#0x20000000,#_PAGE_NOCACHE_S
11331da177e4SLinus Torvalds
11341da177e4SLinus Torvalds	jbra	L(mmu_init_done)
11351da177e4SLinus Torvalds
11361da177e4SLinus TorvaldsL(not6000):
11371da177e4SLinus Torvalds#endif /* CONFIG_BVME6000 */
11381da177e4SLinus Torvalds
11391da177e4SLinus Torvalds/*
11401da177e4SLinus Torvalds * mmu_init_mac
11411da177e4SLinus Torvalds *
11421da177e4SLinus Torvalds * The Macintosh mappings are less clear.
11431da177e4SLinus Torvalds *
11441da177e4SLinus Torvalds * Even as of this writing, it is unclear how the
11451da177e4SLinus Torvalds * Macintosh mappings will be done.  However, as
11461da177e4SLinus Torvalds * the first author of this code I'm proposing the
11471da177e4SLinus Torvalds * following model:
11481da177e4SLinus Torvalds *
11491da177e4SLinus Torvalds * Map the kernel (that's already done),
11501da177e4SLinus Torvalds * Map the I/O (on most machines that's the
11511da177e4SLinus Torvalds * 0x5000.0000 ... 0x5300.0000 range,
11521da177e4SLinus Torvalds * Map the video frame buffer using as few pages
11531da177e4SLinus Torvalds * as absolutely (this requirement mostly stems from
11541da177e4SLinus Torvalds * the fact that when the frame buffer is at
11551da177e4SLinus Torvalds * 0x0000.0000 then we know there is valid RAM just
11561da177e4SLinus Torvalds * above the screen that we don't want to waste!).
11571da177e4SLinus Torvalds *
11581da177e4SLinus Torvalds * By the way, if the frame buffer is at 0x0000.0000
11591da177e4SLinus Torvalds * then the Macintosh is known as an RBV based Mac.
11601da177e4SLinus Torvalds *
11611da177e4SLinus Torvalds * By the way 2, the code currently maps in a bunch of
11621da177e4SLinus Torvalds * regions.  But I'd like to cut that out.  (And move most
11631da177e4SLinus Torvalds * of the mappings up into the kernel proper ... or only
11641da177e4SLinus Torvalds * map what's necessary.)
11651da177e4SLinus Torvalds */
11661da177e4SLinus Torvalds
11671da177e4SLinus Torvalds#ifdef CONFIG_MAC
11681da177e4SLinus Torvalds
11691da177e4SLinus TorvaldsL(mmu_init_mac):
11701da177e4SLinus Torvalds
11711da177e4SLinus Torvalds	is_not_mac(L(mmu_init_not_mac))
11721da177e4SLinus Torvalds
11731da177e4SLinus Torvalds	putc	'F'
11741da177e4SLinus Torvalds
11751da177e4SLinus Torvalds	is_not_040_or_060(1f)
11761da177e4SLinus Torvalds
11771da177e4SLinus Torvalds	moveq	#_PAGE_NOCACHE_S,%d3
11781da177e4SLinus Torvalds	jbra	2f
11791da177e4SLinus Torvalds1:
11801da177e4SLinus Torvalds	moveq	#_PAGE_NOCACHE030,%d3
11811da177e4SLinus Torvalds2:
11821da177e4SLinus Torvalds	/*
11831da177e4SLinus Torvalds	 * Mac Note: screen address of logical 0xF000.0000 -> <screen physical>
11841da177e4SLinus Torvalds	 *	     we simply map the 4MB that contains the videomem
11851da177e4SLinus Torvalds	 */
11861da177e4SLinus Torvalds
11871da177e4SLinus Torvalds	movel	#VIDEOMEMMASK,%d0
11881da177e4SLinus Torvalds	andl	%pc@(L(mac_videobase)),%d0
11891da177e4SLinus Torvalds
11901da177e4SLinus Torvalds	mmu_map		#VIDEOMEMBASE,%d0,#VIDEOMEMSIZE,%d3
11911da177e4SLinus Torvalds	/* ROM from 4000 0000 to 4200 0000 (only for mac_reset()) */
11921da177e4SLinus Torvalds	mmu_map_eq	#0x40000000,#0x02000000,%d3
11931da177e4SLinus Torvalds	/* IO devices (incl. serial port) from 5000 0000 to 5300 0000 */
11941da177e4SLinus Torvalds	mmu_map_eq	#0x50000000,#0x03000000,%d3
11951da177e4SLinus Torvalds	/* Nubus slot space (video at 0xF0000000, rom at 0xF0F80000) */
11961da177e4SLinus Torvalds	mmu_map_tt	#1,#0xf8000000,#0x08000000,%d3
11971da177e4SLinus Torvalds
11981da177e4SLinus Torvalds	jbra	L(mmu_init_done)
11991da177e4SLinus Torvalds
12001da177e4SLinus TorvaldsL(mmu_init_not_mac):
12011da177e4SLinus Torvalds#endif
12021da177e4SLinus Torvalds
12031da177e4SLinus Torvalds#ifdef CONFIG_SUN3X
12041da177e4SLinus Torvalds	is_not_sun3x(L(notsun3x))
12051da177e4SLinus Torvalds
12061da177e4SLinus Torvalds	/* oh, the pain..  We're gonna want the prom code after
12071da177e4SLinus Torvalds	 * starting the MMU, so we copy the mappings, translating
12081da177e4SLinus Torvalds	 * from 8k -> 4k pages as we go.
12091da177e4SLinus Torvalds	 */
12101da177e4SLinus Torvalds
12111da177e4SLinus Torvalds	/* copy maps from 0xfee00000 to 0xff000000 */
12121da177e4SLinus Torvalds	movel	#0xfee00000, %d0
12131da177e4SLinus Torvalds	moveq	#ROOT_INDEX_SHIFT, %d1
12141da177e4SLinus Torvalds	lsrl	%d1,%d0
12151da177e4SLinus Torvalds	mmu_get_root_table_entry	%d0
12161da177e4SLinus Torvalds
12171da177e4SLinus Torvalds	movel	#0xfee00000, %d0
12181da177e4SLinus Torvalds	moveq	#PTR_INDEX_SHIFT, %d1
12191da177e4SLinus Torvalds	lsrl	%d1,%d0
12201da177e4SLinus Torvalds	andl	#PTR_TABLE_SIZE-1, %d0
12211da177e4SLinus Torvalds	mmu_get_ptr_table_entry		%a0,%d0
12221da177e4SLinus Torvalds
12231da177e4SLinus Torvalds	movel	#0xfee00000, %d0
12241da177e4SLinus Torvalds	moveq	#PAGE_INDEX_SHIFT, %d1
12251da177e4SLinus Torvalds	lsrl	%d1,%d0
12261da177e4SLinus Torvalds	andl	#PAGE_TABLE_SIZE-1, %d0
12271da177e4SLinus Torvalds	mmu_get_page_table_entry	%a0,%d0
12281da177e4SLinus Torvalds
12291da177e4SLinus Torvalds	/* this is where the prom page table lives */
12301da177e4SLinus Torvalds	movel	0xfefe00d4, %a1
12311da177e4SLinus Torvalds	movel	%a1@, %a1
12321da177e4SLinus Torvalds
12331da177e4SLinus Torvalds	movel	#((0x200000 >> 13)-1), %d1
12341da177e4SLinus Torvalds
12351da177e4SLinus Torvalds1:
12361da177e4SLinus Torvalds	movel	%a1@+, %d3
12371da177e4SLinus Torvalds	movel	%d3,%a0@+
12381da177e4SLinus Torvalds	addl	#0x1000,%d3
12391da177e4SLinus Torvalds	movel	%d3,%a0@+
12401da177e4SLinus Torvalds
12411da177e4SLinus Torvalds	dbra	%d1,1b
12421da177e4SLinus Torvalds
12431da177e4SLinus Torvalds	/* setup tt1 for I/O */
12441da177e4SLinus Torvalds	mmu_map_tt	#1,#0x40000000,#0x40000000,#_PAGE_NOCACHE_S
12451da177e4SLinus Torvalds	jbra	L(mmu_init_done)
12461da177e4SLinus Torvalds
12471da177e4SLinus TorvaldsL(notsun3x):
12481da177e4SLinus Torvalds#endif
12491da177e4SLinus Torvalds
1250*05d51e42SLaurent Vivier#ifdef CONFIG_VIRT
1251*05d51e42SLaurent Vivier	is_not_virt(L(novirt))
1252*05d51e42SLaurent Vivier	mmu_map_tt	#1,#0xFF000000,#0x01000000,#_PAGE_NOCACHE_S
1253*05d51e42SLaurent Vivier	jbra    L(mmu_init_done)
1254*05d51e42SLaurent VivierL(novirt):
1255*05d51e42SLaurent Vivier#endif
1256*05d51e42SLaurent Vivier
12571da177e4SLinus Torvalds#ifdef CONFIG_APOLLO
12581da177e4SLinus Torvalds	is_not_apollo(L(notapollo))
12591da177e4SLinus Torvalds
12601da177e4SLinus Torvalds	putc	'P'
12611da177e4SLinus Torvalds	mmu_map         #0x80000000,#0,#0x02000000,#_PAGE_NOCACHE030
12621da177e4SLinus Torvalds
12631da177e4SLinus TorvaldsL(notapollo):
12641da177e4SLinus Torvalds	jbra	L(mmu_init_done)
12651da177e4SLinus Torvalds#endif
12661da177e4SLinus Torvalds
12671da177e4SLinus TorvaldsL(mmu_init_done):
12681da177e4SLinus Torvalds
12691da177e4SLinus Torvalds	putc	'G'
12701da177e4SLinus Torvalds	leds	0x8
12711da177e4SLinus Torvalds
12721da177e4SLinus Torvalds/*
12731da177e4SLinus Torvalds * mmu_fixup
12741da177e4SLinus Torvalds *
12751da177e4SLinus Torvalds * On the 040 class machines, all pages that are used for the
12761da177e4SLinus Torvalds * mmu have to be fixed up. According to Motorola, pages holding mmu
12771da177e4SLinus Torvalds * tables should be non-cacheable on a '040 and write-through on a
12781da177e4SLinus Torvalds * '060. But analysis of the reasons for this, and practical
12791da177e4SLinus Torvalds * experience, showed that write-through also works on a '040.
12801da177e4SLinus Torvalds *
12811da177e4SLinus Torvalds * Allocated memory so far goes from kernel_end to memory_start that
12821da177e4SLinus Torvalds * is used for all kind of tables, for that the cache attributes
12831da177e4SLinus Torvalds * are now fixed.
12841da177e4SLinus Torvalds */
12851da177e4SLinus TorvaldsL(mmu_fixup):
12861da177e4SLinus Torvalds
12871da177e4SLinus Torvalds	is_not_040_or_060(L(mmu_fixup_done))
12881da177e4SLinus Torvalds
12891da177e4SLinus Torvalds#ifdef MMU_NOCACHE_KERNEL
12901da177e4SLinus Torvalds	jbra	L(mmu_fixup_done)
12911da177e4SLinus Torvalds#endif
12921da177e4SLinus Torvalds
12931da177e4SLinus Torvalds	/* first fix the page at the start of the kernel, that
12941da177e4SLinus Torvalds	 * contains also kernel_pg_dir.
12951da177e4SLinus Torvalds	 */
12961da177e4SLinus Torvalds	movel	%pc@(L(phys_kernel_start)),%d0
12971da177e4SLinus Torvalds	subl	#PAGE_OFFSET,%d0
12981da177e4SLinus Torvalds	lea	%pc@(_stext),%a0
12991da177e4SLinus Torvalds	subl	%d0,%a0
13001da177e4SLinus Torvalds	mmu_fixup_page_mmu_cache	%a0
13011da177e4SLinus Torvalds
13021da177e4SLinus Torvalds	movel	%pc@(L(kernel_end)),%a0
13031da177e4SLinus Torvalds	subl	%d0,%a0
13041da177e4SLinus Torvalds	movel	%pc@(L(memory_start)),%a1
13051da177e4SLinus Torvalds	subl	%d0,%a1
13061da177e4SLinus Torvalds	bra	2f
13071da177e4SLinus Torvalds1:
13081da177e4SLinus Torvalds	mmu_fixup_page_mmu_cache	%a0
13091da177e4SLinus Torvalds	addw	#PAGESIZE,%a0
13101da177e4SLinus Torvalds2:
13111da177e4SLinus Torvalds	cmpl	%a0,%a1
13121da177e4SLinus Torvalds	jgt	1b
13131da177e4SLinus Torvalds
13141da177e4SLinus TorvaldsL(mmu_fixup_done):
13151da177e4SLinus Torvalds
13161da177e4SLinus Torvalds#ifdef MMU_PRINT
13171da177e4SLinus Torvalds	mmu_print
13181da177e4SLinus Torvalds#endif
13191da177e4SLinus Torvalds
13201da177e4SLinus Torvalds/*
13211da177e4SLinus Torvalds * mmu_engage
13221da177e4SLinus Torvalds *
13231da177e4SLinus Torvalds * This chunk of code performs the gruesome task of engaging the MMU.
13245661bccbSFinn Thain * The reason it's gruesome is because when the MMU becomes engaged it
13251da177e4SLinus Torvalds * maps logical addresses to physical addresses.  The Program Counter
13261da177e4SLinus Torvalds * register is then passed through the MMU before the next instruction
13271da177e4SLinus Torvalds * is fetched (the instruction following the engage MMU instruction).
13281da177e4SLinus Torvalds * This may mean one of two things:
13291da177e4SLinus Torvalds * 1. The Program Counter falls within the logical address space of
13301da177e4SLinus Torvalds *    the kernel of which there are two sub-possibilities:
13311da177e4SLinus Torvalds *    A. The PC maps to the correct instruction (logical PC == physical
13321da177e4SLinus Torvalds *       code location), or
13331da177e4SLinus Torvalds *    B. The PC does not map through and the processor will read some
13341da177e4SLinus Torvalds *       data (or instruction) which is not the logically next instr.
13351da177e4SLinus Torvalds *    As you can imagine, A is good and B is bad.
13361da177e4SLinus Torvalds * Alternatively,
13371da177e4SLinus Torvalds * 2. The Program Counter does not map through the MMU.  The processor
13381da177e4SLinus Torvalds *    will take a Bus Error.
13391da177e4SLinus Torvalds * Clearly, 2 is bad.
13401da177e4SLinus Torvalds * It doesn't take a wiz kid to figure you want 1.A.
13411da177e4SLinus Torvalds * This code creates that possibility.
13421da177e4SLinus Torvalds * There are two possible 1.A. states (we now ignore the other above states):
13431da177e4SLinus Torvalds * A. The kernel is located at physical memory addressed the same as
13441da177e4SLinus Torvalds *    the logical memory for the kernel, i.e., 0x01000.
13451da177e4SLinus Torvalds * B. The kernel is located some where else.  e.g., 0x0400.0000
13461da177e4SLinus Torvalds *
13471da177e4SLinus Torvalds *    Under some conditions the Macintosh can look like A or B.
13481da177e4SLinus Torvalds * [A friend and I once noted that Apple hardware engineers should be
13491da177e4SLinus Torvalds * wacked twice each day: once when they show up at work (as in, Whack!,
13501da177e4SLinus Torvalds * "This is for the screwy hardware we know you're going to design today."),
13511da177e4SLinus Torvalds * and also at the end of the day (as in, Whack! "I don't know what
13521da177e4SLinus Torvalds * you designed today, but I'm sure it wasn't good."). -- rst]
13531da177e4SLinus Torvalds *
13541da177e4SLinus Torvalds * This code works on the following premise:
13551da177e4SLinus Torvalds * If the kernel start (%d5) is within the first 16 Meg of RAM,
13561da177e4SLinus Torvalds * then create a mapping for the kernel at logical 0x8000.0000 to
13571da177e4SLinus Torvalds * the physical location of the pc.  And, create a transparent
13581da177e4SLinus Torvalds * translation register for the first 16 Meg.  Then, after the MMU
13591da177e4SLinus Torvalds * is engaged, the PC can be moved up into the 0x8000.0000 range
13601da177e4SLinus Torvalds * and then the transparent translation can be turned off and then
13611da177e4SLinus Torvalds * the PC can jump to the correct logical location and it will be
13621da177e4SLinus Torvalds * home (finally).  This is essentially the code that the Amiga used
13631da177e4SLinus Torvalds * to use.  Now, it's generalized for all processors.  Which means
13641da177e4SLinus Torvalds * that a fresh (but temporary) mapping has to be created.  The mapping
13651da177e4SLinus Torvalds * is made in page 0 (an as of yet unused location -- except for the
13661da177e4SLinus Torvalds * stack!).  This temporary mapping will only require 1 pointer table
13671da177e4SLinus Torvalds * and a single page table (it can map 256K).
13681da177e4SLinus Torvalds *
13691da177e4SLinus Torvalds * OK, alternatively, imagine that the Program Counter is not within
13701da177e4SLinus Torvalds * the first 16 Meg.  Then, just use Transparent Translation registers
13711da177e4SLinus Torvalds * to do the right thing.
13721da177e4SLinus Torvalds *
13731da177e4SLinus Torvalds * Last, if _start is already at 0x01000, then there's nothing special
13741da177e4SLinus Torvalds * to do (in other words, in a degenerate case of the first case above,
13751da177e4SLinus Torvalds * do nothing).
13761da177e4SLinus Torvalds *
13771da177e4SLinus Torvalds * Let's do it.
13781da177e4SLinus Torvalds *
13791da177e4SLinus Torvalds *
13801da177e4SLinus Torvalds */
13811da177e4SLinus Torvalds
13821da177e4SLinus Torvalds	putc	'H'
13831da177e4SLinus Torvalds
13841da177e4SLinus Torvalds	mmu_engage
13851da177e4SLinus Torvalds
13861da177e4SLinus Torvalds/*
13871da177e4SLinus Torvalds * After this point no new memory is allocated and
13881da177e4SLinus Torvalds * the start of available memory is stored in availmem.
13895661bccbSFinn Thain * (The bootmem allocator requires now the physical address.)
13901da177e4SLinus Torvalds */
13911da177e4SLinus Torvalds
13921da177e4SLinus Torvalds	movel	L(memory_start),availmem
13931da177e4SLinus Torvalds
13941da177e4SLinus Torvalds#ifdef CONFIG_AMIGA
13951da177e4SLinus Torvalds	is_not_amiga(1f)
13961da177e4SLinus Torvalds	/* fixup the Amiga custom register location before printing */
13971da177e4SLinus Torvalds	clrl	L(custom)
13981da177e4SLinus Torvalds1:
13991da177e4SLinus Torvalds#endif
14001da177e4SLinus Torvalds
14011da177e4SLinus Torvalds#ifdef CONFIG_ATARI
14021da177e4SLinus Torvalds	is_not_atari(1f)
14031da177e4SLinus Torvalds	/* fixup the Atari iobase register location before printing */
14041da177e4SLinus Torvalds	movel	#0xff000000,L(iobase)
14051da177e4SLinus Torvalds1:
14061da177e4SLinus Torvalds#endif
14071da177e4SLinus Torvalds
14081da177e4SLinus Torvalds#ifdef CONFIG_MAC
14091da177e4SLinus Torvalds	is_not_mac(1f)
14101da177e4SLinus Torvalds	movel	#~VIDEOMEMMASK,%d0
14111da177e4SLinus Torvalds	andl	L(mac_videobase),%d0
14121da177e4SLinus Torvalds	addl	#VIDEOMEMBASE,%d0
14131da177e4SLinus Torvalds	movel	%d0,L(mac_videobase)
141497f3f68cSFinn Thain#ifdef CONSOLE_DEBUG
14151da177e4SLinus Torvalds	movel	%pc@(L(phys_kernel_start)),%d0
14161da177e4SLinus Torvalds	subl	#PAGE_OFFSET,%d0
14171da177e4SLinus Torvalds	subl	%d0,L(console_font)
14181da177e4SLinus Torvalds	subl	%d0,L(console_font_data)
14191da177e4SLinus Torvalds#endif
14201da177e4SLinus Torvalds	orl	#0x50000000,L(mac_sccbase)
14211da177e4SLinus Torvalds1:
14221da177e4SLinus Torvalds#endif
14231da177e4SLinus Torvalds
14241da177e4SLinus Torvalds#ifdef CONFIG_HP300
14253f365e8eSGeert Uytterhoeven	is_not_hp300(2f)
14261da177e4SLinus Torvalds	/*
14271da177e4SLinus Torvalds	 * Fix up the iobase register to point to the new location of the LEDs.
14281da177e4SLinus Torvalds	 */
14291da177e4SLinus Torvalds	movel	#0xf0000000,L(iobase)
14301da177e4SLinus Torvalds
14311da177e4SLinus Torvalds	/*
14321da177e4SLinus Torvalds	 * Energise the FPU and caches.
14331da177e4SLinus Torvalds	 */
14341da177e4SLinus Torvalds	is_040(1f)
14351da177e4SLinus Torvalds	movel	#0x60,0xf05f400c
14361da177e4SLinus Torvalds	jbra	2f
14371da177e4SLinus Torvalds
14381da177e4SLinus Torvalds	/*
14391da177e4SLinus Torvalds	 * 040: slightly different, apparently.
14401da177e4SLinus Torvalds	 */
14411da177e4SLinus Torvalds1:	movew	#0,0xf05f400e
14421da177e4SLinus Torvalds	movew	#0x64,0xf05f400e
14431da177e4SLinus Torvalds2:
14441da177e4SLinus Torvalds#endif
14451da177e4SLinus Torvalds
14461da177e4SLinus Torvalds#ifdef CONFIG_SUN3X
14471da177e4SLinus Torvalds	is_not_sun3x(1f)
14481da177e4SLinus Torvalds
14491da177e4SLinus Torvalds	/* enable copro */
14501da177e4SLinus Torvalds	oriw	#0x4000,0x61000000
14511da177e4SLinus Torvalds1:
14521da177e4SLinus Torvalds#endif
14531da177e4SLinus Torvalds
14541da177e4SLinus Torvalds#ifdef CONFIG_APOLLO
14551da177e4SLinus Torvalds	is_not_apollo(1f)
14561da177e4SLinus Torvalds
14571da177e4SLinus Torvalds	/*
14581da177e4SLinus Torvalds	 * Fix up the iobase before printing
14591da177e4SLinus Torvalds	 */
14601da177e4SLinus Torvalds	movel	#0x80000000,L(iobase)
14611da177e4SLinus Torvalds1:
14621da177e4SLinus Torvalds#endif
14631da177e4SLinus Torvalds
14641da177e4SLinus Torvalds	putc	'I'
14651da177e4SLinus Torvalds	leds	0x10
14661da177e4SLinus Torvalds
14671da177e4SLinus Torvalds/*
14681da177e4SLinus Torvalds * Enable caches
14691da177e4SLinus Torvalds */
14701da177e4SLinus Torvalds
14711da177e4SLinus Torvalds	is_not_040_or_060(L(cache_not_680460))
14721da177e4SLinus Torvalds
14731da177e4SLinus TorvaldsL(cache680460):
14741da177e4SLinus Torvalds	.chip	68040
14751da177e4SLinus Torvalds	nop
14761da177e4SLinus Torvalds	cpusha	%bc
14771da177e4SLinus Torvalds	nop
14781da177e4SLinus Torvalds
14791da177e4SLinus Torvalds	is_060(L(cache68060))
14801da177e4SLinus Torvalds
14811da177e4SLinus Torvalds	movel	#CC6_ENABLE_D+CC6_ENABLE_I,%d0
14821da177e4SLinus Torvalds	/* MMU stuff works in copyback mode now, so enable the cache */
14831da177e4SLinus Torvalds	movec	%d0,%cacr
14841da177e4SLinus Torvalds	jra	L(cache_done)
14851da177e4SLinus Torvalds
14861da177e4SLinus TorvaldsL(cache68060):
14871da177e4SLinus Torvalds	movel	#CC6_ENABLE_D+CC6_ENABLE_I+CC6_ENABLE_SB+CC6_PUSH_DPI+CC6_ENABLE_B+CC6_CLRA_B,%d0
14881da177e4SLinus Torvalds	/* MMU stuff works in copyback mode now, so enable the cache */
14891da177e4SLinus Torvalds	movec	%d0,%cacr
14901da177e4SLinus Torvalds	/* enable superscalar dispatch in PCR */
14911da177e4SLinus Torvalds	moveq	#1,%d0
14921da177e4SLinus Torvalds	.chip	68060
14931da177e4SLinus Torvalds	movec	%d0,%pcr
14941da177e4SLinus Torvalds
14951da177e4SLinus Torvalds	jbra	L(cache_done)
14961da177e4SLinus TorvaldsL(cache_not_680460):
14971da177e4SLinus TorvaldsL(cache68030):
14981da177e4SLinus Torvalds	.chip	68030
14991da177e4SLinus Torvalds	movel	#CC3_ENABLE_DB+CC3_CLR_D+CC3_ENABLE_D+CC3_ENABLE_IB+CC3_CLR_I+CC3_ENABLE_I,%d0
15001da177e4SLinus Torvalds	movec	%d0,%cacr
15011da177e4SLinus Torvalds
15021da177e4SLinus Torvalds	jra	L(cache_done)
15031da177e4SLinus Torvalds	.chip	68k
15041da177e4SLinus TorvaldsL(cache_done):
15051da177e4SLinus Torvalds
15061da177e4SLinus Torvalds	putc	'J'
15071da177e4SLinus Torvalds
15081da177e4SLinus Torvalds/*
15091da177e4SLinus Torvalds * Setup initial stack pointer
15101da177e4SLinus Torvalds */
15111da177e4SLinus Torvalds	lea	init_task,%curptr
15121da177e4SLinus Torvalds	lea	init_thread_union+THREAD_SIZE,%sp
15131da177e4SLinus Torvalds
15141da177e4SLinus Torvalds	putc	'K'
15151da177e4SLinus Torvalds
15161da177e4SLinus Torvalds	subl	%a6,%a6		/* clear a6 for gdb */
15171da177e4SLinus Torvalds
15181da177e4SLinus Torvalds/*
15191da177e4SLinus Torvalds * The new 64bit printf support requires an early exception initialization.
15201da177e4SLinus Torvalds */
15211da177e4SLinus Torvalds	jbsr	base_trap_init
15221da177e4SLinus Torvalds
15231da177e4SLinus Torvalds/* jump to the kernel start */
15241da177e4SLinus Torvalds
15251da177e4SLinus Torvalds	putc	'\n'
15261da177e4SLinus Torvalds	leds	0x55
15271da177e4SLinus Torvalds
15281da177e4SLinus Torvalds	jbsr	start_kernel
15291da177e4SLinus Torvalds
15301da177e4SLinus Torvalds/*
15311da177e4SLinus Torvalds * Find a tag record in the bootinfo structure
153229a20203SGeert Uytterhoeven * The bootinfo structure is located right after the kernel
15331da177e4SLinus Torvalds * Returns: d0: size (-1 if not found)
15341da177e4SLinus Torvalds *          a0: data pointer (end-of-records if not found)
15351da177e4SLinus Torvalds */
15361da177e4SLinus Torvaldsfunc_start	get_bi_record,%d1
15371da177e4SLinus Torvalds
15381da177e4SLinus Torvalds	movel	ARG1,%d0
15391da177e4SLinus Torvalds	lea	%pc@(_end),%a0
15401da177e4SLinus Torvalds1:	tstw	%a0@(BIR_TAG)
15411da177e4SLinus Torvalds	jeq	3f
15421da177e4SLinus Torvalds	cmpw	%a0@(BIR_TAG),%d0
15431da177e4SLinus Torvalds	jeq	2f
15441da177e4SLinus Torvalds	addw	%a0@(BIR_SIZE),%a0
15451da177e4SLinus Torvalds	jra	1b
15461da177e4SLinus Torvalds2:	moveq	#0,%d0
15471da177e4SLinus Torvalds	movew	%a0@(BIR_SIZE),%d0
15481da177e4SLinus Torvalds	lea	%a0@(BIR_DATA),%a0
15491da177e4SLinus Torvalds	jra	4f
15501da177e4SLinus Torvalds3:	moveq	#-1,%d0
15511da177e4SLinus Torvalds	lea	%a0@(BIR_SIZE),%a0
15521da177e4SLinus Torvalds4:
15531da177e4SLinus Torvaldsfunc_return	get_bi_record
15541da177e4SLinus Torvalds
15551da177e4SLinus Torvalds
15561da177e4SLinus Torvalds/*
15571da177e4SLinus Torvalds *	MMU Initialization Begins Here
15581da177e4SLinus Torvalds *
15591da177e4SLinus Torvalds *	The structure of the MMU tables on the 68k machines
15601da177e4SLinus Torvalds *	is thus:
15611da177e4SLinus Torvalds *	Root Table
15621da177e4SLinus Torvalds *		Logical addresses are translated through
15631da177e4SLinus Torvalds *	a hierarchical translation mechanism where the high-order
15641da177e4SLinus Torvalds *	seven bits of the logical address (LA) are used as an
15651da177e4SLinus Torvalds *	index into the "root table."  Each entry in the root
15661da177e4SLinus Torvalds *	table has a bit which specifies if it's a valid pointer to a
15675661bccbSFinn Thain *	pointer table.  Each entry defines a 32Meg range of memory.
15681da177e4SLinus Torvalds *	If an entry is invalid then that logical range of 32M is
15691da177e4SLinus Torvalds *	invalid and references to that range of memory (when the MMU
15701da177e4SLinus Torvalds *	is enabled) will fault.  If the entry is valid, then it does
15711da177e4SLinus Torvalds *	one of two things.  On 040/060 class machines, it points to
15721da177e4SLinus Torvalds *	a pointer table which then describes more finely the memory
15731da177e4SLinus Torvalds *	within that 32M range.  On 020/030 class machines, a technique
15741da177e4SLinus Torvalds *	called "early terminating descriptors" are used.  This technique
15751da177e4SLinus Torvalds *	allows an entire 32Meg to be described by a single entry in the
15761da177e4SLinus Torvalds *	root table.  Thus, this entry in the root table, contains the
15771da177e4SLinus Torvalds *	physical address of the memory or I/O at the logical address
15781da177e4SLinus Torvalds *	which the entry represents and it also contains the necessary
15791da177e4SLinus Torvalds *	cache bits for this region.
15801da177e4SLinus Torvalds *
15811da177e4SLinus Torvalds *	Pointer Tables
15821da177e4SLinus Torvalds *		Per the Root Table, there will be one or more
15831da177e4SLinus Torvalds *	pointer tables.  Each pointer table defines a 32M range.
15841da177e4SLinus Torvalds *	Not all of the 32M range need be defined.  Again, the next
15851da177e4SLinus Torvalds *	seven bits of the logical address are used an index into
15861da177e4SLinus Torvalds *	the pointer table to point to page tables (if the pointer
15871da177e4SLinus Torvalds *	is valid).  There will undoubtedly be more than one
15881da177e4SLinus Torvalds *	pointer table for the kernel because each pointer table
15891da177e4SLinus Torvalds *	defines a range of only 32M.  Valid pointer table entries
15901da177e4SLinus Torvalds *	point to page tables, or are early terminating entries
15911da177e4SLinus Torvalds *	themselves.
15921da177e4SLinus Torvalds *
15931da177e4SLinus Torvalds *	Page Tables
15941da177e4SLinus Torvalds *		Per the Pointer Tables, each page table entry points
15951da177e4SLinus Torvalds *	to the physical page in memory that supports the logical
15961da177e4SLinus Torvalds *	address that translates to the particular index.
15971da177e4SLinus Torvalds *
15981da177e4SLinus Torvalds *	In short, the Logical Address gets translated as follows:
15991da177e4SLinus Torvalds *		bits 31..26 - index into the Root Table
16001da177e4SLinus Torvalds *		bits 25..18 - index into the Pointer Table
16011da177e4SLinus Torvalds *		bits 17..12 - index into the Page Table
16021da177e4SLinus Torvalds *		bits 11..0  - offset into a particular 4K page
16031da177e4SLinus Torvalds *
16045661bccbSFinn Thain *	The algorithms which follow do one thing: they abstract
16051da177e4SLinus Torvalds *	the MMU hardware.  For example, there are three kinds of
16061da177e4SLinus Torvalds *	cache settings that are relevant.  Either, memory is
16071da177e4SLinus Torvalds *	being mapped in which case it is either Kernel Code (or
16081da177e4SLinus Torvalds *	the RamDisk) or it is MMU data.  On the 030, the MMU data
16091da177e4SLinus Torvalds *	option also describes the kernel.  Or, I/O is being mapped
16101da177e4SLinus Torvalds *	in which case it has its own kind of cache bits.  There
16111da177e4SLinus Torvalds *	are constants which abstract these notions from the code that
16121da177e4SLinus Torvalds *	actually makes the call to map some range of memory.
16131da177e4SLinus Torvalds *
16141da177e4SLinus Torvalds *
16151da177e4SLinus Torvalds *
16161da177e4SLinus Torvalds */
16171da177e4SLinus Torvalds
16181da177e4SLinus Torvalds#ifdef MMU_PRINT
16191da177e4SLinus Torvalds/*
16201da177e4SLinus Torvalds *	mmu_print
16211da177e4SLinus Torvalds *
16221da177e4SLinus Torvalds *	This algorithm will print out the current MMU mappings.
16231da177e4SLinus Torvalds *
16241da177e4SLinus Torvalds *	Input:
16251da177e4SLinus Torvalds *		%a5 points to the root table.  Everything else is calculated
16261da177e4SLinus Torvalds *			from this.
16271da177e4SLinus Torvalds */
16281da177e4SLinus Torvalds
16291da177e4SLinus Torvalds#define mmu_next_valid		0
16301da177e4SLinus Torvalds#define mmu_start_logical	4
16311da177e4SLinus Torvalds#define mmu_next_logical	8
16321da177e4SLinus Torvalds#define mmu_start_physical	12
16331da177e4SLinus Torvalds#define mmu_next_physical	16
16341da177e4SLinus Torvalds
16351da177e4SLinus Torvalds#define MMU_PRINT_INVALID		-1
16361da177e4SLinus Torvalds#define MMU_PRINT_VALID			1
16371da177e4SLinus Torvalds#define MMU_PRINT_UNINITED		0
16381da177e4SLinus Torvalds
16391da177e4SLinus Torvalds#define putZc(z,n)		jbne 1f; putc z; jbra 2f; 1: putc n; 2:
16401da177e4SLinus Torvalds
16411da177e4SLinus Torvaldsfunc_start	mmu_print,%a0-%a6/%d0-%d7
16421da177e4SLinus Torvalds
16431da177e4SLinus Torvalds	movel	%pc@(L(kernel_pgdir_ptr)),%a5
16441da177e4SLinus Torvalds	lea	%pc@(L(mmu_print_data)),%a0
16451da177e4SLinus Torvalds	movel	#MMU_PRINT_UNINITED,%a0@(mmu_next_valid)
16461da177e4SLinus Torvalds
16471da177e4SLinus Torvalds	is_not_040_or_060(mmu_030_print)
16481da177e4SLinus Torvalds
16491da177e4SLinus Torvaldsmmu_040_print:
16501da177e4SLinus Torvalds	puts	"\nMMU040\n"
16511da177e4SLinus Torvalds	puts	"rp:"
16521da177e4SLinus Torvalds	putn	%a5
16531da177e4SLinus Torvalds	putc	'\n'
16541da177e4SLinus Torvalds#if 0
16551da177e4SLinus Torvalds	/*
16561da177e4SLinus Torvalds	 * The following #if/#endif block is a tight algorithm for dumping the 040
16571da177e4SLinus Torvalds	 * MMU Map in gory detail.  It really isn't that practical unless the
16581da177e4SLinus Torvalds	 * MMU Map algorithm appears to go awry and you need to debug it at the
16591da177e4SLinus Torvalds	 * entry per entry level.
16601da177e4SLinus Torvalds	 */
16611da177e4SLinus Torvalds	movel	#ROOT_TABLE_SIZE,%d5
16621da177e4SLinus Torvalds#if 0
16631da177e4SLinus Torvalds	movel	%a5@+,%d7		| Burn an entry to skip the kernel mappings,
16641da177e4SLinus Torvalds	subql	#1,%d5			| they (might) work
16651da177e4SLinus Torvalds#endif
16661da177e4SLinus Torvalds1:	tstl	%d5
16671da177e4SLinus Torvalds	jbeq	mmu_print_done
16681da177e4SLinus Torvalds	subq	#1,%d5
16691da177e4SLinus Torvalds	movel	%a5@+,%d7
16701da177e4SLinus Torvalds	btst	#1,%d7
16711da177e4SLinus Torvalds	jbeq	1b
16721da177e4SLinus Torvalds
16731da177e4SLinus Torvalds2:	putn	%d7
16741da177e4SLinus Torvalds	andil	#0xFFFFFE00,%d7
16751da177e4SLinus Torvalds	movel	%d7,%a4
16761da177e4SLinus Torvalds	movel	#PTR_TABLE_SIZE,%d4
16771da177e4SLinus Torvalds	putc	' '
16781da177e4SLinus Torvalds3:	tstl	%d4
16791da177e4SLinus Torvalds	jbeq	11f
16801da177e4SLinus Torvalds	subq	#1,%d4
16811da177e4SLinus Torvalds	movel	%a4@+,%d7
16821da177e4SLinus Torvalds	btst	#1,%d7
16831da177e4SLinus Torvalds	jbeq	3b
16841da177e4SLinus Torvalds
16851da177e4SLinus Torvalds4:	putn	%d7
16861da177e4SLinus Torvalds	andil	#0xFFFFFF00,%d7
16871da177e4SLinus Torvalds	movel	%d7,%a3
16881da177e4SLinus Torvalds	movel	#PAGE_TABLE_SIZE,%d3
16891da177e4SLinus Torvalds5:	movel	#8,%d2
16901da177e4SLinus Torvalds6:	tstl	%d3
16911da177e4SLinus Torvalds	jbeq	31f
16921da177e4SLinus Torvalds	subq	#1,%d3
16931da177e4SLinus Torvalds	movel	%a3@+,%d6
16941da177e4SLinus Torvalds	btst	#0,%d6
16951da177e4SLinus Torvalds	jbeq	6b
16961da177e4SLinus Torvalds7:	tstl	%d2
16971da177e4SLinus Torvalds	jbeq	8f
16981da177e4SLinus Torvalds	subq	#1,%d2
16991da177e4SLinus Torvalds	putc	' '
17001da177e4SLinus Torvalds	jbra	91f
17011da177e4SLinus Torvalds8:	putc	'\n'
17021da177e4SLinus Torvalds	movel	#8+1+8+1+1,%d2
17031da177e4SLinus Torvalds9:	putc	' '
17041da177e4SLinus Torvalds	dbra	%d2,9b
17051da177e4SLinus Torvalds	movel	#7,%d2
17061da177e4SLinus Torvalds91:	putn	%d6
17071da177e4SLinus Torvalds	jbra	6b
17081da177e4SLinus Torvalds
17091da177e4SLinus Torvalds31:	putc	'\n'
17101da177e4SLinus Torvalds	movel	#8+1,%d2
17111da177e4SLinus Torvalds32:	putc	' '
17121da177e4SLinus Torvalds	dbra	%d2,32b
17131da177e4SLinus Torvalds	jbra	3b
17141da177e4SLinus Torvalds
17151da177e4SLinus Torvalds11:	putc	'\n'
17161da177e4SLinus Torvalds	jbra	1b
17171da177e4SLinus Torvalds#endif /* MMU 040 Dumping code that's gory and detailed */
17181da177e4SLinus Torvalds
17191da177e4SLinus Torvalds	lea	%pc@(kernel_pg_dir),%a5
17201da177e4SLinus Torvalds	movel	%a5,%a0			/* a0 has the address of the root table ptr */
17211da177e4SLinus Torvalds	movel	#0x00000000,%a4		/* logical address */
17221da177e4SLinus Torvalds	moveql	#0,%d0
17231da177e4SLinus Torvalds40:
17241da177e4SLinus Torvalds	/* Increment the logical address and preserve in d5 */
17251da177e4SLinus Torvalds	movel	%a4,%d5
17261da177e4SLinus Torvalds	addil	#PAGESIZE<<13,%d5
17271da177e4SLinus Torvalds	movel	%a0@+,%d6
17281da177e4SLinus Torvalds	btst	#1,%d6
17291da177e4SLinus Torvalds	jbne	41f
17301da177e4SLinus Torvalds	jbsr	mmu_print_tuple_invalidate
17311da177e4SLinus Torvalds	jbra	48f
17321da177e4SLinus Torvalds41:
17331da177e4SLinus Torvalds	movel	#0,%d1
17341da177e4SLinus Torvalds	andil	#0xfffffe00,%d6
17351da177e4SLinus Torvalds	movel	%d6,%a1
17361da177e4SLinus Torvalds42:
17371da177e4SLinus Torvalds	movel	%a4,%d5
17381da177e4SLinus Torvalds	addil	#PAGESIZE<<6,%d5
17391da177e4SLinus Torvalds	movel	%a1@+,%d6
17401da177e4SLinus Torvalds	btst	#1,%d6
17411da177e4SLinus Torvalds	jbne	43f
17421da177e4SLinus Torvalds	jbsr	mmu_print_tuple_invalidate
17431da177e4SLinus Torvalds	jbra	47f
17441da177e4SLinus Torvalds43:
17451da177e4SLinus Torvalds	movel	#0,%d2
17461da177e4SLinus Torvalds	andil	#0xffffff00,%d6
17471da177e4SLinus Torvalds	movel	%d6,%a2
17481da177e4SLinus Torvalds44:
17491da177e4SLinus Torvalds	movel	%a4,%d5
17501da177e4SLinus Torvalds	addil	#PAGESIZE,%d5
17511da177e4SLinus Torvalds	movel	%a2@+,%d6
17521da177e4SLinus Torvalds	btst	#0,%d6
17531da177e4SLinus Torvalds	jbne	45f
17541da177e4SLinus Torvalds	jbsr	mmu_print_tuple_invalidate
17551da177e4SLinus Torvalds	jbra	46f
17561da177e4SLinus Torvalds45:
17571da177e4SLinus Torvalds	moveml	%d0-%d1,%sp@-
17581da177e4SLinus Torvalds	movel	%a4,%d0
17591da177e4SLinus Torvalds	movel	%d6,%d1
17601da177e4SLinus Torvalds	andil	#0xfffff4e0,%d1
17611da177e4SLinus Torvalds	lea	%pc@(mmu_040_print_flags),%a6
17621da177e4SLinus Torvalds	jbsr	mmu_print_tuple
17631da177e4SLinus Torvalds	moveml	%sp@+,%d0-%d1
17641da177e4SLinus Torvalds46:
17651da177e4SLinus Torvalds	movel	%d5,%a4
17661da177e4SLinus Torvalds	addq	#1,%d2
17671da177e4SLinus Torvalds	cmpib	#64,%d2
17681da177e4SLinus Torvalds	jbne	44b
17691da177e4SLinus Torvalds47:
17701da177e4SLinus Torvalds	movel	%d5,%a4
17711da177e4SLinus Torvalds	addq	#1,%d1
17721da177e4SLinus Torvalds	cmpib	#128,%d1
17731da177e4SLinus Torvalds	jbne	42b
17741da177e4SLinus Torvalds48:
17751da177e4SLinus Torvalds	movel	%d5,%a4			/* move to the next logical address */
17761da177e4SLinus Torvalds	addq	#1,%d0
17771da177e4SLinus Torvalds	cmpib	#128,%d0
17781da177e4SLinus Torvalds	jbne	40b
17791da177e4SLinus Torvalds
17801da177e4SLinus Torvalds	.chip	68040
17811da177e4SLinus Torvalds	movec	%dtt1,%d0
17821da177e4SLinus Torvalds	movel	%d0,%d1
17831da177e4SLinus Torvalds	andiw	#0x8000,%d1		/* is it valid ? */
17841da177e4SLinus Torvalds	jbeq	1f			/* No, bail out */
17851da177e4SLinus Torvalds
17861da177e4SLinus Torvalds	movel	%d0,%d1
17871da177e4SLinus Torvalds	andil	#0xff000000,%d1		/* Get the address */
17881da177e4SLinus Torvalds	putn	%d1
17891da177e4SLinus Torvalds	puts	"=="
17901da177e4SLinus Torvalds	putn	%d1
17911da177e4SLinus Torvalds
17921da177e4SLinus Torvalds	movel	%d0,%d6
17931da177e4SLinus Torvalds	jbsr	mmu_040_print_flags_tt
17941da177e4SLinus Torvalds1:
17951da177e4SLinus Torvalds	movec	%dtt0,%d0
17961da177e4SLinus Torvalds	movel	%d0,%d1
17971da177e4SLinus Torvalds	andiw	#0x8000,%d1		/* is it valid ? */
17981da177e4SLinus Torvalds	jbeq	1f			/* No, bail out */
17991da177e4SLinus Torvalds
18001da177e4SLinus Torvalds	movel	%d0,%d1
18011da177e4SLinus Torvalds	andil	#0xff000000,%d1		/* Get the address */
18021da177e4SLinus Torvalds	putn	%d1
18031da177e4SLinus Torvalds	puts	"=="
18041da177e4SLinus Torvalds	putn	%d1
18051da177e4SLinus Torvalds
18061da177e4SLinus Torvalds	movel	%d0,%d6
18071da177e4SLinus Torvalds	jbsr	mmu_040_print_flags_tt
18081da177e4SLinus Torvalds1:
18091da177e4SLinus Torvalds	.chip	68k
18101da177e4SLinus Torvalds
18111da177e4SLinus Torvalds	jbra	mmu_print_done
18121da177e4SLinus Torvalds
18131da177e4SLinus Torvaldsmmu_040_print_flags:
18141da177e4SLinus Torvalds	btstl	#10,%d6
18151da177e4SLinus Torvalds	putZc(' ','G')	/* global bit */
18161da177e4SLinus Torvalds	btstl	#7,%d6
18171da177e4SLinus Torvalds	putZc(' ','S')	/* supervisor bit */
18181da177e4SLinus Torvaldsmmu_040_print_flags_tt:
18191da177e4SLinus Torvalds	btstl	#6,%d6
18201da177e4SLinus Torvalds	jbne	3f
18211da177e4SLinus Torvalds	putc	'C'
18221da177e4SLinus Torvalds	btstl	#5,%d6
18231da177e4SLinus Torvalds	putZc('w','c')	/* write through or copy-back */
18241da177e4SLinus Torvalds	jbra	4f
18251da177e4SLinus Torvalds3:
18261da177e4SLinus Torvalds	putc	'N'
18271da177e4SLinus Torvalds	btstl	#5,%d6
18281da177e4SLinus Torvalds	putZc('s',' ')	/* serialized non-cacheable, or non-cacheable */
18291da177e4SLinus Torvalds4:
18301da177e4SLinus Torvalds	rts
18311da177e4SLinus Torvalds
18321da177e4SLinus Torvaldsmmu_030_print_flags:
18331da177e4SLinus Torvalds	btstl	#6,%d6
18341da177e4SLinus Torvalds	putZc('C','I')	/* write through or copy-back */
18351da177e4SLinus Torvalds	rts
18361da177e4SLinus Torvalds
18371da177e4SLinus Torvaldsmmu_030_print:
18381da177e4SLinus Torvalds	puts	"\nMMU030\n"
18391da177e4SLinus Torvalds	puts	"\nrp:"
18401da177e4SLinus Torvalds	putn	%a5
18411da177e4SLinus Torvalds	putc	'\n'
18421da177e4SLinus Torvalds	movel	%a5,%d0
18431da177e4SLinus Torvalds	andil	#0xfffffff0,%d0
18441da177e4SLinus Torvalds	movel	%d0,%a0
18451da177e4SLinus Torvalds	movel	#0x00000000,%a4		/* logical address */
18461da177e4SLinus Torvalds	movel	#0,%d0
18471da177e4SLinus Torvalds30:
18481da177e4SLinus Torvalds	movel	%a4,%d5
18491da177e4SLinus Torvalds	addil	#PAGESIZE<<13,%d5
18501da177e4SLinus Torvalds	movel	%a0@+,%d6
18511da177e4SLinus Torvalds	btst	#1,%d6			/* is it a table ptr? */
18521da177e4SLinus Torvalds	jbne	31f			/* yes */
18531da177e4SLinus Torvalds	btst	#0,%d6			/* is it early terminating? */
18541da177e4SLinus Torvalds	jbeq	1f			/* no */
18551da177e4SLinus Torvalds	jbsr	mmu_030_print_helper
18561da177e4SLinus Torvalds	jbra	38f
18571da177e4SLinus Torvalds1:
18581da177e4SLinus Torvalds	jbsr	mmu_print_tuple_invalidate
18591da177e4SLinus Torvalds	jbra	38f
18601da177e4SLinus Torvalds31:
18611da177e4SLinus Torvalds	movel	#0,%d1
18621da177e4SLinus Torvalds	andil	#0xfffffff0,%d6
18631da177e4SLinus Torvalds	movel	%d6,%a1
18641da177e4SLinus Torvalds32:
18651da177e4SLinus Torvalds	movel	%a4,%d5
18661da177e4SLinus Torvalds	addil	#PAGESIZE<<6,%d5
18671da177e4SLinus Torvalds	movel	%a1@+,%d6
18681da177e4SLinus Torvalds	btst	#1,%d6			/* is it a table ptr? */
18691da177e4SLinus Torvalds	jbne	33f			/* yes */
18701da177e4SLinus Torvalds	btst	#0,%d6			/* is it a page descriptor? */
18711da177e4SLinus Torvalds	jbeq	1f			/* no */
18721da177e4SLinus Torvalds	jbsr	mmu_030_print_helper
18731da177e4SLinus Torvalds	jbra	37f
18741da177e4SLinus Torvalds1:
18751da177e4SLinus Torvalds	jbsr	mmu_print_tuple_invalidate
18761da177e4SLinus Torvalds	jbra	37f
18771da177e4SLinus Torvalds33:
18781da177e4SLinus Torvalds	movel	#0,%d2
18791da177e4SLinus Torvalds	andil	#0xfffffff0,%d6
18801da177e4SLinus Torvalds	movel	%d6,%a2
18811da177e4SLinus Torvalds34:
18821da177e4SLinus Torvalds	movel	%a4,%d5
18831da177e4SLinus Torvalds	addil	#PAGESIZE,%d5
18841da177e4SLinus Torvalds	movel	%a2@+,%d6
18851da177e4SLinus Torvalds	btst	#0,%d6
18861da177e4SLinus Torvalds	jbne	35f
18871da177e4SLinus Torvalds	jbsr	mmu_print_tuple_invalidate
18881da177e4SLinus Torvalds	jbra	36f
18891da177e4SLinus Torvalds35:
18901da177e4SLinus Torvalds	jbsr	mmu_030_print_helper
18911da177e4SLinus Torvalds36:
18921da177e4SLinus Torvalds	movel	%d5,%a4
18931da177e4SLinus Torvalds	addq	#1,%d2
18941da177e4SLinus Torvalds	cmpib	#64,%d2
18951da177e4SLinus Torvalds	jbne	34b
18961da177e4SLinus Torvalds37:
18971da177e4SLinus Torvalds	movel	%d5,%a4
18981da177e4SLinus Torvalds	addq	#1,%d1
18991da177e4SLinus Torvalds	cmpib	#128,%d1
19001da177e4SLinus Torvalds	jbne	32b
19011da177e4SLinus Torvalds38:
19021da177e4SLinus Torvalds	movel	%d5,%a4			/* move to the next logical address */
19031da177e4SLinus Torvalds	addq	#1,%d0
19041da177e4SLinus Torvalds	cmpib	#128,%d0
19051da177e4SLinus Torvalds	jbne	30b
19061da177e4SLinus Torvalds
19071da177e4SLinus Torvaldsmmu_print_done:
190893edd023SFinn Thain	puts	"\n"
19091da177e4SLinus Torvalds
19101da177e4SLinus Torvaldsfunc_return	mmu_print
19111da177e4SLinus Torvalds
19121da177e4SLinus Torvalds
19131da177e4SLinus Torvaldsmmu_030_print_helper:
19141da177e4SLinus Torvalds	moveml	%d0-%d1,%sp@-
19151da177e4SLinus Torvalds	movel	%a4,%d0
19161da177e4SLinus Torvalds	movel	%d6,%d1
19171da177e4SLinus Torvalds	lea	%pc@(mmu_030_print_flags),%a6
19181da177e4SLinus Torvalds	jbsr	mmu_print_tuple
19191da177e4SLinus Torvalds	moveml	%sp@+,%d0-%d1
19201da177e4SLinus Torvalds	rts
19211da177e4SLinus Torvalds
19221da177e4SLinus Torvaldsmmu_print_tuple_invalidate:
19231da177e4SLinus Torvalds	moveml	%a0/%d7,%sp@-
19241da177e4SLinus Torvalds
19251da177e4SLinus Torvalds	lea	%pc@(L(mmu_print_data)),%a0
19261da177e4SLinus Torvalds	tstl	%a0@(mmu_next_valid)
19271da177e4SLinus Torvalds	jbmi	mmu_print_tuple_invalidate_exit
19281da177e4SLinus Torvalds
19291da177e4SLinus Torvalds	movel	#MMU_PRINT_INVALID,%a0@(mmu_next_valid)
19301da177e4SLinus Torvalds
19311da177e4SLinus Torvalds	putn	%a4
19321da177e4SLinus Torvalds
19331da177e4SLinus Torvalds	puts	"##\n"
19341da177e4SLinus Torvalds
19351da177e4SLinus Torvaldsmmu_print_tuple_invalidate_exit:
19361da177e4SLinus Torvalds	moveml	%sp@+,%a0/%d7
19371da177e4SLinus Torvalds	rts
19381da177e4SLinus Torvalds
19391da177e4SLinus Torvalds
19401da177e4SLinus Torvaldsmmu_print_tuple:
19411da177e4SLinus Torvalds	moveml	%d0-%d7/%a0,%sp@-
19421da177e4SLinus Torvalds
19431da177e4SLinus Torvalds	lea	%pc@(L(mmu_print_data)),%a0
19441da177e4SLinus Torvalds
19451da177e4SLinus Torvalds	tstl	%a0@(mmu_next_valid)
19461da177e4SLinus Torvalds	jble	mmu_print_tuple_print
19471da177e4SLinus Torvalds
19481da177e4SLinus Torvalds	cmpl	%a0@(mmu_next_physical),%d1
19491da177e4SLinus Torvalds	jbeq	mmu_print_tuple_increment
19501da177e4SLinus Torvalds
19511da177e4SLinus Torvaldsmmu_print_tuple_print:
19521da177e4SLinus Torvalds	putn	%d0
19531da177e4SLinus Torvalds	puts	"->"
19541da177e4SLinus Torvalds	putn	%d1
19551da177e4SLinus Torvalds
19561da177e4SLinus Torvalds	movel	%d1,%d6
19571da177e4SLinus Torvalds	jbsr	%a6@
19581da177e4SLinus Torvalds
19591da177e4SLinus Torvaldsmmu_print_tuple_record:
19601da177e4SLinus Torvalds	movel	#MMU_PRINT_VALID,%a0@(mmu_next_valid)
19611da177e4SLinus Torvalds
19621da177e4SLinus Torvalds	movel	%d1,%a0@(mmu_next_physical)
19631da177e4SLinus Torvalds
19641da177e4SLinus Torvaldsmmu_print_tuple_increment:
19651da177e4SLinus Torvalds	movel	%d5,%d7
19661da177e4SLinus Torvalds	subl	%a4,%d7
19671da177e4SLinus Torvalds	addl	%d7,%a0@(mmu_next_physical)
19681da177e4SLinus Torvalds
19691da177e4SLinus Torvaldsmmu_print_tuple_exit:
19701da177e4SLinus Torvalds	moveml	%sp@+,%d0-%d7/%a0
19711da177e4SLinus Torvalds	rts
19721da177e4SLinus Torvalds
19731da177e4SLinus Torvaldsmmu_print_machine_cpu_types:
19741da177e4SLinus Torvalds	puts	"machine: "
19751da177e4SLinus Torvalds
19761da177e4SLinus Torvalds	is_not_amiga(1f)
19771da177e4SLinus Torvalds	puts	"amiga"
19781da177e4SLinus Torvalds	jbra	9f
19791da177e4SLinus Torvalds1:
19801da177e4SLinus Torvalds	is_not_atari(2f)
19811da177e4SLinus Torvalds	puts	"atari"
19821da177e4SLinus Torvalds	jbra	9f
19831da177e4SLinus Torvalds2:
19841da177e4SLinus Torvalds	is_not_mac(3f)
19851da177e4SLinus Torvalds	puts	"macintosh"
19861da177e4SLinus Torvalds	jbra	9f
19871da177e4SLinus Torvalds3:	puts	"unknown"
19881da177e4SLinus Torvalds9:	putc	'\n'
19891da177e4SLinus Torvalds
19901da177e4SLinus Torvalds	puts	"cputype: 0"
19911da177e4SLinus Torvalds	is_not_060(1f)
19921da177e4SLinus Torvalds	putc	'6'
19931da177e4SLinus Torvalds	jbra	9f
19941da177e4SLinus Torvalds1:
19951da177e4SLinus Torvalds	is_not_040_or_060(2f)
19961da177e4SLinus Torvalds	putc	'4'
19971da177e4SLinus Torvalds	jbra	9f
19981da177e4SLinus Torvalds2:	putc	'3'
19991da177e4SLinus Torvalds9:	putc	'0'
20001da177e4SLinus Torvalds	putc	'\n'
20011da177e4SLinus Torvalds
20021da177e4SLinus Torvalds	rts
20031da177e4SLinus Torvalds#endif /* MMU_PRINT */
20041da177e4SLinus Torvalds
20051da177e4SLinus Torvalds/*
20061da177e4SLinus Torvalds * mmu_map_tt
20071da177e4SLinus Torvalds *
20081da177e4SLinus Torvalds * This is a specific function which works on all 680x0 machines.
20091da177e4SLinus Torvalds * On 030, 040 & 060 it will attempt to use Transparent Translation
20101da177e4SLinus Torvalds * registers (tt1).
20111da177e4SLinus Torvalds * On 020 it will call the standard mmu_map which will use early
20121da177e4SLinus Torvalds * terminating descriptors.
20131da177e4SLinus Torvalds */
20141da177e4SLinus Torvaldsfunc_start	mmu_map_tt,%d0/%d1/%a0,4
20151da177e4SLinus Torvalds
20161da177e4SLinus Torvalds	dputs	"mmu_map_tt:"
20171da177e4SLinus Torvalds	dputn	ARG1
20181da177e4SLinus Torvalds	dputn	ARG2
20191da177e4SLinus Torvalds	dputn	ARG3
20201da177e4SLinus Torvalds	dputn	ARG4
20211da177e4SLinus Torvalds	dputc	'\n'
20221da177e4SLinus Torvalds
20231da177e4SLinus Torvalds	is_020(L(do_map))
20241da177e4SLinus Torvalds
20251da177e4SLinus Torvalds	/* Extract the highest bit set
20261da177e4SLinus Torvalds	 */
20271da177e4SLinus Torvalds	bfffo	ARG3{#0,#32},%d1
20281da177e4SLinus Torvalds	cmpw	#8,%d1
20291da177e4SLinus Torvalds	jcc	L(do_map)
20301da177e4SLinus Torvalds
20311da177e4SLinus Torvalds	/* And get the mask
20321da177e4SLinus Torvalds	 */
20331da177e4SLinus Torvalds	moveq	#-1,%d0
20341da177e4SLinus Torvalds	lsrl	%d1,%d0
20351da177e4SLinus Torvalds	lsrl	#1,%d0
20361da177e4SLinus Torvalds
20371da177e4SLinus Torvalds	/* Mask the address
20381da177e4SLinus Torvalds	 */
20391da177e4SLinus Torvalds	movel	%d0,%d1
20401da177e4SLinus Torvalds	notl	%d1
20411da177e4SLinus Torvalds	andl	ARG2,%d1
20421da177e4SLinus Torvalds
20431da177e4SLinus Torvalds	/* Generate the upper 16bit of the tt register
20441da177e4SLinus Torvalds	 */
20451da177e4SLinus Torvalds	lsrl	#8,%d0
20461da177e4SLinus Torvalds	orl	%d0,%d1
20471da177e4SLinus Torvalds	clrw	%d1
20481da177e4SLinus Torvalds
20491da177e4SLinus Torvalds	is_040_or_060(L(mmu_map_tt_040))
20501da177e4SLinus Torvalds
20511da177e4SLinus Torvalds	/* set 030 specific bits (read/write access for supervisor mode
20521da177e4SLinus Torvalds	 * (highest function code set, lower two bits masked))
20531da177e4SLinus Torvalds	 */
20541da177e4SLinus Torvalds	orw	#TTR_ENABLE+TTR_RWM+TTR_FCB2+TTR_FCM1+TTR_FCM0,%d1
20551da177e4SLinus Torvalds	movel	ARG4,%d0
20561da177e4SLinus Torvalds	btst	#6,%d0
20571da177e4SLinus Torvalds	jeq	1f
20581da177e4SLinus Torvalds	orw	#TTR_CI,%d1
20591da177e4SLinus Torvalds
20601da177e4SLinus Torvalds1:	lea	STACK,%a0
20611da177e4SLinus Torvalds	dputn	%d1
20621da177e4SLinus Torvalds	movel	%d1,%a0@
20631da177e4SLinus Torvalds	.chip	68030
20641da177e4SLinus Torvalds	tstl	ARG1
20651da177e4SLinus Torvalds	jne	1f
20661da177e4SLinus Torvalds	pmove	%a0@,%tt0
20671da177e4SLinus Torvalds	jra	2f
20681da177e4SLinus Torvalds1:	pmove	%a0@,%tt1
20691da177e4SLinus Torvalds2:	.chip	68k
20701da177e4SLinus Torvalds	jra	L(mmu_map_tt_done)
20711da177e4SLinus Torvalds
20721da177e4SLinus Torvalds	/* set 040 specific bits
20731da177e4SLinus Torvalds	 */
20741da177e4SLinus TorvaldsL(mmu_map_tt_040):
20751da177e4SLinus Torvalds	orw	#TTR_ENABLE+TTR_KERNELMODE,%d1
20761da177e4SLinus Torvalds	orl	ARG4,%d1
20771da177e4SLinus Torvalds	dputn	%d1
20781da177e4SLinus Torvalds
20791da177e4SLinus Torvalds	.chip	68040
20801da177e4SLinus Torvalds	tstl	ARG1
20811da177e4SLinus Torvalds	jne	1f
20821da177e4SLinus Torvalds	movec	%d1,%itt0
20831da177e4SLinus Torvalds	movec	%d1,%dtt0
20841da177e4SLinus Torvalds	jra	2f
20851da177e4SLinus Torvalds1:	movec	%d1,%itt1
20861da177e4SLinus Torvalds	movec	%d1,%dtt1
20871da177e4SLinus Torvalds2:	.chip	68k
20881da177e4SLinus Torvalds
20891da177e4SLinus Torvalds	jra	L(mmu_map_tt_done)
20901da177e4SLinus Torvalds
20911da177e4SLinus TorvaldsL(do_map):
20921da177e4SLinus Torvalds	mmu_map_eq	ARG2,ARG3,ARG4
20931da177e4SLinus Torvalds
20941da177e4SLinus TorvaldsL(mmu_map_tt_done):
20951da177e4SLinus Torvalds
20961da177e4SLinus Torvaldsfunc_return	mmu_map_tt
20971da177e4SLinus Torvalds
20981da177e4SLinus Torvalds/*
20991da177e4SLinus Torvalds *	mmu_map
21001da177e4SLinus Torvalds *
21011da177e4SLinus Torvalds *	This routine will map a range of memory using a pointer
21025661bccbSFinn Thain *	table and allocate the pages on the fly from the kernel.
21031da177e4SLinus Torvalds *	The pointer table does not have to be already linked into
21041da177e4SLinus Torvalds *	the root table, this routine will do that if necessary.
21051da177e4SLinus Torvalds *
21061da177e4SLinus Torvalds *	NOTE
21071da177e4SLinus Torvalds *	This routine will assert failure and use the serial_putc
21081da177e4SLinus Torvalds *	routines in the case of a run-time error.  For example,
21091da177e4SLinus Torvalds *	if the address is already mapped.
21101da177e4SLinus Torvalds *
21111da177e4SLinus Torvalds *	NOTE-2
21121da177e4SLinus Torvalds *	This routine will use early terminating descriptors
21131da177e4SLinus Torvalds *	where possible for the 68020+68851 and 68030 type
21141da177e4SLinus Torvalds *	processors.
21151da177e4SLinus Torvalds */
21161da177e4SLinus Torvaldsfunc_start	mmu_map,%d0-%d4/%a0-%a4
21171da177e4SLinus Torvalds
21181da177e4SLinus Torvalds	dputs	"\nmmu_map:"
21191da177e4SLinus Torvalds	dputn	ARG1
21201da177e4SLinus Torvalds	dputn	ARG2
21211da177e4SLinus Torvalds	dputn	ARG3
21221da177e4SLinus Torvalds	dputn	ARG4
21231da177e4SLinus Torvalds	dputc	'\n'
21241da177e4SLinus Torvalds
21251da177e4SLinus Torvalds	/* Get logical address and round it down to 256KB
21261da177e4SLinus Torvalds	 */
21271da177e4SLinus Torvalds	movel	ARG1,%d0
21281da177e4SLinus Torvalds	andl	#-(PAGESIZE*PAGE_TABLE_SIZE),%d0
21291da177e4SLinus Torvalds	movel	%d0,%a3
21301da177e4SLinus Torvalds
21311da177e4SLinus Torvalds	/* Get the end address
21321da177e4SLinus Torvalds	 */
21331da177e4SLinus Torvalds	movel	ARG1,%a4
21341da177e4SLinus Torvalds	addl	ARG3,%a4
21351da177e4SLinus Torvalds	subql	#1,%a4
21361da177e4SLinus Torvalds
21371da177e4SLinus Torvalds	/* Get physical address and round it down to 256KB
21381da177e4SLinus Torvalds	 */
21391da177e4SLinus Torvalds	movel	ARG2,%d0
21401da177e4SLinus Torvalds	andl	#-(PAGESIZE*PAGE_TABLE_SIZE),%d0
21411da177e4SLinus Torvalds	movel	%d0,%a2
21421da177e4SLinus Torvalds
21431da177e4SLinus Torvalds	/* Add page attributes to the physical address
21441da177e4SLinus Torvalds	 */
21451da177e4SLinus Torvalds	movel	ARG4,%d0
21461da177e4SLinus Torvalds	orw	#_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
21471da177e4SLinus Torvalds	addw	%d0,%a2
21481da177e4SLinus Torvalds
21491da177e4SLinus Torvalds	dputn	%a2
21501da177e4SLinus Torvalds	dputn	%a3
21511da177e4SLinus Torvalds	dputn	%a4
21521da177e4SLinus Torvalds
21531da177e4SLinus Torvalds	is_not_040_or_060(L(mmu_map_030))
21541da177e4SLinus Torvalds
21551da177e4SLinus Torvalds	addw	#_PAGE_GLOBAL040,%a2
21561da177e4SLinus Torvalds/*
21571da177e4SLinus Torvalds *	MMU 040 & 060 Support
21581da177e4SLinus Torvalds *
21591da177e4SLinus Torvalds *	The MMU usage for the 040 and 060 is different enough from
21601da177e4SLinus Torvalds *	the 030 and 68851 that there is separate code.  This comment
21611da177e4SLinus Torvalds *	block describes the data structures and algorithms built by
21621da177e4SLinus Torvalds *	this code.
21631da177e4SLinus Torvalds *
21641da177e4SLinus Torvalds *	The 040 does not support early terminating descriptors, as
21651da177e4SLinus Torvalds *	the 030 does.  Therefore, a third level of table is needed
21661da177e4SLinus Torvalds *	for the 040, and that would be the page table.  In Linux,
21671da177e4SLinus Torvalds *	page tables are allocated directly from the memory above the
21681da177e4SLinus Torvalds *	kernel.
21691da177e4SLinus Torvalds *
21701da177e4SLinus Torvalds */
21711da177e4SLinus Torvalds
21721da177e4SLinus TorvaldsL(mmu_map_040):
21731da177e4SLinus Torvalds	/* Calculate the offset into the root table
21741da177e4SLinus Torvalds	 */
21751da177e4SLinus Torvalds	movel	%a3,%d0
21761da177e4SLinus Torvalds	moveq	#ROOT_INDEX_SHIFT,%d1
21771da177e4SLinus Torvalds	lsrl	%d1,%d0
21781da177e4SLinus Torvalds	mmu_get_root_table_entry	%d0
21791da177e4SLinus Torvalds
21801da177e4SLinus Torvalds	/* Calculate the offset into the pointer table
21811da177e4SLinus Torvalds	 */
21821da177e4SLinus Torvalds	movel	%a3,%d0
21831da177e4SLinus Torvalds	moveq	#PTR_INDEX_SHIFT,%d1
21841da177e4SLinus Torvalds	lsrl	%d1,%d0
21851da177e4SLinus Torvalds	andl	#PTR_TABLE_SIZE-1,%d0
21861da177e4SLinus Torvalds	mmu_get_ptr_table_entry		%a0,%d0
21871da177e4SLinus Torvalds
21881da177e4SLinus Torvalds	/* Calculate the offset into the page table
21891da177e4SLinus Torvalds	 */
21901da177e4SLinus Torvalds	movel	%a3,%d0
21911da177e4SLinus Torvalds	moveq	#PAGE_INDEX_SHIFT,%d1
21921da177e4SLinus Torvalds	lsrl	%d1,%d0
21931da177e4SLinus Torvalds	andl	#PAGE_TABLE_SIZE-1,%d0
21941da177e4SLinus Torvalds	mmu_get_page_table_entry	%a0,%d0
21951da177e4SLinus Torvalds
21961da177e4SLinus Torvalds	/* The page table entry must not no be busy
21971da177e4SLinus Torvalds	 */
21981da177e4SLinus Torvalds	tstl	%a0@
21991da177e4SLinus Torvalds	jne	L(mmu_map_error)
22001da177e4SLinus Torvalds
22011da177e4SLinus Torvalds	/* Do the mapping and advance the pointers
22021da177e4SLinus Torvalds	 */
22031da177e4SLinus Torvalds	movel	%a2,%a0@
22041da177e4SLinus Torvalds2:
22051da177e4SLinus Torvalds	addw	#PAGESIZE,%a2
22061da177e4SLinus Torvalds	addw	#PAGESIZE,%a3
22071da177e4SLinus Torvalds
22081da177e4SLinus Torvalds	/* Ready with mapping?
22091da177e4SLinus Torvalds	 */
22101da177e4SLinus Torvalds	lea	%a3@(-1),%a0
22111da177e4SLinus Torvalds	cmpl	%a0,%a4
22121da177e4SLinus Torvalds	jhi	L(mmu_map_040)
22131da177e4SLinus Torvalds	jra	L(mmu_map_done)
22141da177e4SLinus Torvalds
22151da177e4SLinus TorvaldsL(mmu_map_030):
22161da177e4SLinus Torvalds	/* Calculate the offset into the root table
22171da177e4SLinus Torvalds	 */
22181da177e4SLinus Torvalds	movel	%a3,%d0
22191da177e4SLinus Torvalds	moveq	#ROOT_INDEX_SHIFT,%d1
22201da177e4SLinus Torvalds	lsrl	%d1,%d0
22211da177e4SLinus Torvalds	mmu_get_root_table_entry	%d0
22221da177e4SLinus Torvalds
22231da177e4SLinus Torvalds	/* Check if logical address 32MB aligned,
22241da177e4SLinus Torvalds	 * so we can try to map it once
22251da177e4SLinus Torvalds	 */
22261da177e4SLinus Torvalds	movel	%a3,%d0
22271da177e4SLinus Torvalds	andl	#(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1)&(-ROOT_TABLE_SIZE),%d0
22281da177e4SLinus Torvalds	jne	1f
22291da177e4SLinus Torvalds
22301da177e4SLinus Torvalds	/* Is there enough to map for 32MB at once
22311da177e4SLinus Torvalds	 */
22321da177e4SLinus Torvalds	lea	%a3@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE-1),%a1
22331da177e4SLinus Torvalds	cmpl	%a1,%a4
22341da177e4SLinus Torvalds	jcs	1f
22351da177e4SLinus Torvalds
22361da177e4SLinus Torvalds	addql	#1,%a1
22371da177e4SLinus Torvalds
22381da177e4SLinus Torvalds	/* The root table entry must not no be busy
22391da177e4SLinus Torvalds	 */
22401da177e4SLinus Torvalds	tstl	%a0@
22411da177e4SLinus Torvalds	jne	L(mmu_map_error)
22421da177e4SLinus Torvalds
22431da177e4SLinus Torvalds	/* Do the mapping and advance the pointers
22441da177e4SLinus Torvalds	 */
22451da177e4SLinus Torvalds	dputs	"early term1"
22461da177e4SLinus Torvalds	dputn	%a2
22471da177e4SLinus Torvalds	dputn	%a3
22481da177e4SLinus Torvalds	dputn	%a1
22491da177e4SLinus Torvalds	dputc	'\n'
22501da177e4SLinus Torvalds	movel	%a2,%a0@
22511da177e4SLinus Torvalds
22521da177e4SLinus Torvalds	movel	%a1,%a3
22531da177e4SLinus Torvalds	lea	%a2@(PTR_TABLE_SIZE*PAGE_TABLE_SIZE*PAGESIZE),%a2
22541da177e4SLinus Torvalds	jra	L(mmu_mapnext_030)
22551da177e4SLinus Torvalds1:
22561da177e4SLinus Torvalds	/* Calculate the offset into the pointer table
22571da177e4SLinus Torvalds	 */
22581da177e4SLinus Torvalds	movel	%a3,%d0
22591da177e4SLinus Torvalds	moveq	#PTR_INDEX_SHIFT,%d1
22601da177e4SLinus Torvalds	lsrl	%d1,%d0
22611da177e4SLinus Torvalds	andl	#PTR_TABLE_SIZE-1,%d0
22621da177e4SLinus Torvalds	mmu_get_ptr_table_entry		%a0,%d0
22631da177e4SLinus Torvalds
22641da177e4SLinus Torvalds	/* The pointer table entry must not no be busy
22651da177e4SLinus Torvalds	 */
22661da177e4SLinus Torvalds	tstl	%a0@
22671da177e4SLinus Torvalds	jne	L(mmu_map_error)
22681da177e4SLinus Torvalds
22691da177e4SLinus Torvalds	/* Do the mapping and advance the pointers
22701da177e4SLinus Torvalds	 */
22711da177e4SLinus Torvalds	dputs	"early term2"
22721da177e4SLinus Torvalds	dputn	%a2
22731da177e4SLinus Torvalds	dputn	%a3
22741da177e4SLinus Torvalds	dputc	'\n'
22751da177e4SLinus Torvalds	movel	%a2,%a0@
22761da177e4SLinus Torvalds
22771da177e4SLinus Torvalds	addl	#PAGE_TABLE_SIZE*PAGESIZE,%a2
22781da177e4SLinus Torvalds	addl	#PAGE_TABLE_SIZE*PAGESIZE,%a3
22791da177e4SLinus Torvalds
22801da177e4SLinus TorvaldsL(mmu_mapnext_030):
22811da177e4SLinus Torvalds	/* Ready with mapping?
22821da177e4SLinus Torvalds	 */
22831da177e4SLinus Torvalds	lea	%a3@(-1),%a0
22841da177e4SLinus Torvalds	cmpl	%a0,%a4
22851da177e4SLinus Torvalds	jhi	L(mmu_map_030)
22861da177e4SLinus Torvalds	jra	L(mmu_map_done)
22871da177e4SLinus Torvalds
22881da177e4SLinus TorvaldsL(mmu_map_error):
22891da177e4SLinus Torvalds
22901da177e4SLinus Torvalds	dputs	"mmu_map error:"
22911da177e4SLinus Torvalds	dputn	%a2
22921da177e4SLinus Torvalds	dputn	%a3
22931da177e4SLinus Torvalds	dputc	'\n'
22941da177e4SLinus Torvalds
22951da177e4SLinus TorvaldsL(mmu_map_done):
22961da177e4SLinus Torvalds
22971da177e4SLinus Torvaldsfunc_return	mmu_map
22981da177e4SLinus Torvalds
22991da177e4SLinus Torvalds/*
23001da177e4SLinus Torvalds *	mmu_fixup
23011da177e4SLinus Torvalds *
23021da177e4SLinus Torvalds *	On the 040 class machines, all pages that are used for the
23031da177e4SLinus Torvalds *	mmu have to be fixed up.
23041da177e4SLinus Torvalds */
23051da177e4SLinus Torvalds
23061da177e4SLinus Torvaldsfunc_start	mmu_fixup_page_mmu_cache,%d0/%a0
23071da177e4SLinus Torvalds
23081da177e4SLinus Torvalds	dputs	"mmu_fixup_page_mmu_cache"
23091da177e4SLinus Torvalds	dputn	ARG1
23101da177e4SLinus Torvalds
23111da177e4SLinus Torvalds	/* Calculate the offset into the root table
23121da177e4SLinus Torvalds	 */
23131da177e4SLinus Torvalds	movel	ARG1,%d0
23141da177e4SLinus Torvalds	moveq	#ROOT_INDEX_SHIFT,%d1
23151da177e4SLinus Torvalds	lsrl	%d1,%d0
23161da177e4SLinus Torvalds	mmu_get_root_table_entry	%d0
23171da177e4SLinus Torvalds
23181da177e4SLinus Torvalds	/* Calculate the offset into the pointer table
23191da177e4SLinus Torvalds	 */
23201da177e4SLinus Torvalds	movel	ARG1,%d0
23211da177e4SLinus Torvalds	moveq	#PTR_INDEX_SHIFT,%d1
23221da177e4SLinus Torvalds	lsrl	%d1,%d0
23231da177e4SLinus Torvalds	andl	#PTR_TABLE_SIZE-1,%d0
23241da177e4SLinus Torvalds	mmu_get_ptr_table_entry		%a0,%d0
23251da177e4SLinus Torvalds
23261da177e4SLinus Torvalds	/* Calculate the offset into the page table
23271da177e4SLinus Torvalds	 */
23281da177e4SLinus Torvalds	movel	ARG1,%d0
23291da177e4SLinus Torvalds	moveq	#PAGE_INDEX_SHIFT,%d1
23301da177e4SLinus Torvalds	lsrl	%d1,%d0
23311da177e4SLinus Torvalds	andl	#PAGE_TABLE_SIZE-1,%d0
23321da177e4SLinus Torvalds	mmu_get_page_table_entry	%a0,%d0
23331da177e4SLinus Torvalds
23341da177e4SLinus Torvalds	movel	%a0@,%d0
23351da177e4SLinus Torvalds	andil	#_CACHEMASK040,%d0
23361da177e4SLinus Torvalds	orl	%pc@(m68k_pgtable_cachemode),%d0
23371da177e4SLinus Torvalds	movel	%d0,%a0@
23381da177e4SLinus Torvalds
23391da177e4SLinus Torvalds	dputc	'\n'
23401da177e4SLinus Torvalds
23411da177e4SLinus Torvaldsfunc_return	mmu_fixup_page_mmu_cache
23421da177e4SLinus Torvalds
23431da177e4SLinus Torvalds/*
23441da177e4SLinus Torvalds *	mmu_temp_map
23451da177e4SLinus Torvalds *
23461da177e4SLinus Torvalds *	create a temporary mapping to enable the mmu,
23471da177e4SLinus Torvalds *	this we don't need any transparation translation tricks.
23481da177e4SLinus Torvalds */
23491da177e4SLinus Torvalds
23501da177e4SLinus Torvaldsfunc_start	mmu_temp_map,%d0/%d1/%a0/%a1
23511da177e4SLinus Torvalds
23521da177e4SLinus Torvalds	dputs	"mmu_temp_map"
23531da177e4SLinus Torvalds	dputn	ARG1
23541da177e4SLinus Torvalds	dputn	ARG2
23551da177e4SLinus Torvalds	dputc	'\n'
23561da177e4SLinus Torvalds
23571da177e4SLinus Torvalds	lea	%pc@(L(temp_mmap_mem)),%a1
23581da177e4SLinus Torvalds
23591da177e4SLinus Torvalds	/* Calculate the offset in the root table
23601da177e4SLinus Torvalds	 */
23611da177e4SLinus Torvalds	movel	ARG2,%d0
23621da177e4SLinus Torvalds	moveq	#ROOT_INDEX_SHIFT,%d1
23631da177e4SLinus Torvalds	lsrl	%d1,%d0
23641da177e4SLinus Torvalds	mmu_get_root_table_entry	%d0
23651da177e4SLinus Torvalds
23661da177e4SLinus Torvalds	/* Check if the table is temporary allocated, so we have to reuse it
23671da177e4SLinus Torvalds	 */
23681da177e4SLinus Torvalds	movel	%a0@,%d0
23691da177e4SLinus Torvalds	cmpl	%pc@(L(memory_start)),%d0
23701da177e4SLinus Torvalds	jcc	1f
23711da177e4SLinus Torvalds
23721da177e4SLinus Torvalds	/* Temporary allocate a ptr table and insert it into the root table
23731da177e4SLinus Torvalds	 */
23741da177e4SLinus Torvalds	movel	%a1@,%d0
23751da177e4SLinus Torvalds	addl	#PTR_TABLE_SIZE*4,%a1@
23761da177e4SLinus Torvalds	orw	#_PAGE_TABLE+_PAGE_ACCESSED,%d0
23771da177e4SLinus Torvalds	movel	%d0,%a0@
23781da177e4SLinus Torvalds	dputs	" (new)"
23791da177e4SLinus Torvalds1:
23801da177e4SLinus Torvalds	dputn	%d0
23811da177e4SLinus Torvalds	/* Mask the root table entry for the ptr table
23821da177e4SLinus Torvalds	 */
23831da177e4SLinus Torvalds	andw	#-ROOT_TABLE_SIZE,%d0
23841da177e4SLinus Torvalds	movel	%d0,%a0
23851da177e4SLinus Torvalds
23861da177e4SLinus Torvalds	/* Calculate the offset into the pointer table
23871da177e4SLinus Torvalds	 */
23881da177e4SLinus Torvalds	movel	ARG2,%d0
23891da177e4SLinus Torvalds	moveq	#PTR_INDEX_SHIFT,%d1
23901da177e4SLinus Torvalds	lsrl	%d1,%d0
23911da177e4SLinus Torvalds	andl	#PTR_TABLE_SIZE-1,%d0
23921da177e4SLinus Torvalds	lea	%a0@(%d0*4),%a0
23931da177e4SLinus Torvalds	dputn	%a0
23941da177e4SLinus Torvalds
23951da177e4SLinus Torvalds	/* Check if a temporary page table is already allocated
23961da177e4SLinus Torvalds	 */
23971da177e4SLinus Torvalds	movel	%a0@,%d0
23981da177e4SLinus Torvalds	jne	1f
23991da177e4SLinus Torvalds
24001da177e4SLinus Torvalds	/* Temporary allocate a page table and insert it into the ptr table
24011da177e4SLinus Torvalds	 */
24021da177e4SLinus Torvalds	movel	%a1@,%d0
24031da177e4SLinus Torvalds	/* The 512 should be PAGE_TABLE_SIZE*4, but that violates the
24041da177e4SLinus Torvalds	   alignment restriction for pointer tables on the '0[46]0.  */
24051da177e4SLinus Torvalds	addl	#512,%a1@
24061da177e4SLinus Torvalds	orw	#_PAGE_TABLE+_PAGE_ACCESSED,%d0
24071da177e4SLinus Torvalds	movel	%d0,%a0@
24081da177e4SLinus Torvalds	dputs	" (new)"
24091da177e4SLinus Torvalds1:
24101da177e4SLinus Torvalds	dputn	%d0
24111da177e4SLinus Torvalds	/* Mask the ptr table entry for the page table
24121da177e4SLinus Torvalds	 */
24131da177e4SLinus Torvalds	andw	#-PTR_TABLE_SIZE,%d0
24141da177e4SLinus Torvalds	movel	%d0,%a0
24151da177e4SLinus Torvalds
24161da177e4SLinus Torvalds	/* Calculate the offset into the page table
24171da177e4SLinus Torvalds	 */
24181da177e4SLinus Torvalds	movel	ARG2,%d0
24191da177e4SLinus Torvalds	moveq	#PAGE_INDEX_SHIFT,%d1
24201da177e4SLinus Torvalds	lsrl	%d1,%d0
24211da177e4SLinus Torvalds	andl	#PAGE_TABLE_SIZE-1,%d0
24221da177e4SLinus Torvalds	lea	%a0@(%d0*4),%a0
24231da177e4SLinus Torvalds	dputn	%a0
24241da177e4SLinus Torvalds
24251da177e4SLinus Torvalds	/* Insert the address into the page table
24261da177e4SLinus Torvalds	 */
24271da177e4SLinus Torvalds	movel	ARG1,%d0
24281da177e4SLinus Torvalds	andw	#-PAGESIZE,%d0
24291da177e4SLinus Torvalds	orw	#_PAGE_PRESENT+_PAGE_ACCESSED+_PAGE_DIRTY,%d0
24301da177e4SLinus Torvalds	movel	%d0,%a0@
24311da177e4SLinus Torvalds	dputn	%d0
24321da177e4SLinus Torvalds
24331da177e4SLinus Torvalds	dputc	'\n'
24341da177e4SLinus Torvalds
24351da177e4SLinus Torvaldsfunc_return	mmu_temp_map
24361da177e4SLinus Torvalds
24371da177e4SLinus Torvaldsfunc_start	mmu_engage,%d0-%d2/%a0-%a3
24381da177e4SLinus Torvalds
24391da177e4SLinus Torvalds	moveq	#ROOT_TABLE_SIZE-1,%d0
24401da177e4SLinus Torvalds	/* Temporarily use a different root table.  */
24411da177e4SLinus Torvalds	lea	%pc@(L(kernel_pgdir_ptr)),%a0
24421da177e4SLinus Torvalds	movel	%a0@,%a2
24431da177e4SLinus Torvalds	movel	%pc@(L(memory_start)),%a1
24441da177e4SLinus Torvalds	movel	%a1,%a0@
24451da177e4SLinus Torvalds	movel	%a2,%a0
24461da177e4SLinus Torvalds1:
24471da177e4SLinus Torvalds	movel	%a0@+,%a1@+
24481da177e4SLinus Torvalds	dbra	%d0,1b
24491da177e4SLinus Torvalds
24501da177e4SLinus Torvalds	lea	%pc@(L(temp_mmap_mem)),%a0
24511da177e4SLinus Torvalds	movel	%a1,%a0@
24521da177e4SLinus Torvalds
24531da177e4SLinus Torvalds	movew	#PAGESIZE-1,%d0
24541da177e4SLinus Torvalds1:
24551da177e4SLinus Torvalds	clrl	%a1@+
24561da177e4SLinus Torvalds	dbra	%d0,1b
24571da177e4SLinus Torvalds
24581da177e4SLinus Torvalds	lea	%pc@(1b),%a0
24591da177e4SLinus Torvalds	movel	#1b,%a1
24601da177e4SLinus Torvalds	/* Skip temp mappings if phys == virt */
24611da177e4SLinus Torvalds	cmpl	%a0,%a1
24621da177e4SLinus Torvalds	jeq	1f
24631da177e4SLinus Torvalds
24641da177e4SLinus Torvalds	mmu_temp_map	%a0,%a0
24651da177e4SLinus Torvalds	mmu_temp_map	%a0,%a1
24661da177e4SLinus Torvalds
24671da177e4SLinus Torvalds	addw	#PAGESIZE,%a0
24681da177e4SLinus Torvalds	addw	#PAGESIZE,%a1
24691da177e4SLinus Torvalds	mmu_temp_map	%a0,%a0
24701da177e4SLinus Torvalds	mmu_temp_map	%a0,%a1
24711da177e4SLinus Torvalds1:
24721da177e4SLinus Torvalds	movel	%pc@(L(memory_start)),%a3
24731da177e4SLinus Torvalds	movel	%pc@(L(phys_kernel_start)),%d2
24741da177e4SLinus Torvalds
24751da177e4SLinus Torvalds	is_not_040_or_060(L(mmu_engage_030))
24761da177e4SLinus Torvalds
24771da177e4SLinus TorvaldsL(mmu_engage_040):
24781da177e4SLinus Torvalds	.chip	68040
24791da177e4SLinus Torvalds	nop
24801da177e4SLinus Torvalds	cinva	%bc
24811da177e4SLinus Torvalds	nop
24821da177e4SLinus Torvalds	pflusha
24831da177e4SLinus Torvalds	nop
24841da177e4SLinus Torvalds	movec	%a3,%srp
24851da177e4SLinus Torvalds	movel	#TC_ENABLE+TC_PAGE4K,%d0
24861da177e4SLinus Torvalds	movec	%d0,%tc		/* enable the MMU */
24871da177e4SLinus Torvalds	jmp	1f:l
24881da177e4SLinus Torvalds1:	nop
24891da177e4SLinus Torvalds	movec	%a2,%srp
24901da177e4SLinus Torvalds	nop
24911da177e4SLinus Torvalds	cinva	%bc
24921da177e4SLinus Torvalds	nop
24931da177e4SLinus Torvalds	pflusha
24941da177e4SLinus Torvalds	.chip	68k
24951da177e4SLinus Torvalds	jra	L(mmu_engage_cleanup)
24961da177e4SLinus Torvalds
24971da177e4SLinus TorvaldsL(mmu_engage_030_temp):
24981da177e4SLinus Torvalds	.space	12
24991da177e4SLinus TorvaldsL(mmu_engage_030):
25001da177e4SLinus Torvalds	.chip	68030
25011da177e4SLinus Torvalds	lea	%pc@(L(mmu_engage_030_temp)),%a0
25021da177e4SLinus Torvalds	movel	#0x80000002,%a0@
25031da177e4SLinus Torvalds	movel	%a3,%a0@(4)
25041da177e4SLinus Torvalds	movel	#0x0808,%d0
25051da177e4SLinus Torvalds	movec	%d0,%cacr
25061da177e4SLinus Torvalds	pmove	%a0@,%srp
25071da177e4SLinus Torvalds	pflusha
25081da177e4SLinus Torvalds	/*
25091da177e4SLinus Torvalds	 * enable,super root enable,4096 byte pages,7 bit root index,
25101da177e4SLinus Torvalds	 * 7 bit pointer index, 6 bit page table index.
25111da177e4SLinus Torvalds	 */
25121da177e4SLinus Torvalds	movel	#0x82c07760,%a0@(8)
25131da177e4SLinus Torvalds	pmove	%a0@(8),%tc	/* enable the MMU */
25141da177e4SLinus Torvalds	jmp	1f:l
25151da177e4SLinus Torvalds1:	movel	%a2,%a0@(4)
25161da177e4SLinus Torvalds	movel	#0x0808,%d0
25171da177e4SLinus Torvalds	movec	%d0,%cacr
25181da177e4SLinus Torvalds	pmove	%a0@,%srp
25191da177e4SLinus Torvalds	pflusha
25201da177e4SLinus Torvalds	.chip	68k
25211da177e4SLinus Torvalds
25221da177e4SLinus TorvaldsL(mmu_engage_cleanup):
25231da177e4SLinus Torvalds	subl	#PAGE_OFFSET,%d2
25241da177e4SLinus Torvalds	subl	%d2,%a2
25251da177e4SLinus Torvalds	movel	%a2,L(kernel_pgdir_ptr)
25261da177e4SLinus Torvalds	subl	%d2,%fp
25271da177e4SLinus Torvalds	subl	%d2,%sp
25281da177e4SLinus Torvalds	subl	%d2,ARG0
25291da177e4SLinus Torvalds
25301da177e4SLinus Torvaldsfunc_return	mmu_engage
25311da177e4SLinus Torvalds
25321da177e4SLinus Torvaldsfunc_start	mmu_get_root_table_entry,%d0/%a1
25331da177e4SLinus Torvalds
25341da177e4SLinus Torvalds#if 0
25351da177e4SLinus Torvalds	dputs	"mmu_get_root_table_entry:"
25361da177e4SLinus Torvalds	dputn	ARG1
25371da177e4SLinus Torvalds	dputs	" ="
25381da177e4SLinus Torvalds#endif
25391da177e4SLinus Torvalds
25401da177e4SLinus Torvalds	movel	%pc@(L(kernel_pgdir_ptr)),%a0
25411da177e4SLinus Torvalds	tstl	%a0
25421da177e4SLinus Torvalds	jne	2f
25431da177e4SLinus Torvalds
25441da177e4SLinus Torvalds	dputs	"\nmmu_init:"
25451da177e4SLinus Torvalds
25461da177e4SLinus Torvalds	/* Find the start of free memory, get_bi_record does this for us,
25471da177e4SLinus Torvalds	 * as the bootinfo structure is located directly behind the kernel
25485661bccbSFinn Thain	 * we simply search for the last entry.
25491da177e4SLinus Torvalds	 */
25501da177e4SLinus Torvalds	get_bi_record	BI_LAST
25511da177e4SLinus Torvalds	addw	#PAGESIZE-1,%a0
25521da177e4SLinus Torvalds	movel	%a0,%d0
25531da177e4SLinus Torvalds	andw	#-PAGESIZE,%d0
25541da177e4SLinus Torvalds
25551da177e4SLinus Torvalds	dputn	%d0
25561da177e4SLinus Torvalds
25571da177e4SLinus Torvalds	lea	%pc@(L(memory_start)),%a0
25581da177e4SLinus Torvalds	movel	%d0,%a0@
25591da177e4SLinus Torvalds	lea	%pc@(L(kernel_end)),%a0
25601da177e4SLinus Torvalds	movel	%d0,%a0@
25611da177e4SLinus Torvalds
25621da177e4SLinus Torvalds	/* we have to return the first page at _stext since the init code
25631da177e4SLinus Torvalds	 * in mm/init.c simply expects kernel_pg_dir there, the rest of
25641da177e4SLinus Torvalds	 * page is used for further ptr tables in get_ptr_table.
25651da177e4SLinus Torvalds	 */
25661da177e4SLinus Torvalds	lea	%pc@(_stext),%a0
25671da177e4SLinus Torvalds	lea	%pc@(L(mmu_cached_pointer_tables)),%a1
25681da177e4SLinus Torvalds	movel	%a0,%a1@
25691da177e4SLinus Torvalds	addl	#ROOT_TABLE_SIZE*4,%a1@
25701da177e4SLinus Torvalds
25711da177e4SLinus Torvalds	lea	%pc@(L(mmu_num_pointer_tables)),%a1
25721da177e4SLinus Torvalds	addql	#1,%a1@
25731da177e4SLinus Torvalds
25741da177e4SLinus Torvalds	/* clear the page
25751da177e4SLinus Torvalds	 */
25761da177e4SLinus Torvalds	movel	%a0,%a1
25771da177e4SLinus Torvalds	movew	#PAGESIZE/4-1,%d0
25781da177e4SLinus Torvalds1:
25791da177e4SLinus Torvalds	clrl	%a1@+
25801da177e4SLinus Torvalds	dbra	%d0,1b
25811da177e4SLinus Torvalds
25821da177e4SLinus Torvalds	lea	%pc@(L(kernel_pgdir_ptr)),%a1
25831da177e4SLinus Torvalds	movel	%a0,%a1@
25841da177e4SLinus Torvalds
25851da177e4SLinus Torvalds	dputn	%a0
25861da177e4SLinus Torvalds	dputc	'\n'
25871da177e4SLinus Torvalds2:
25881da177e4SLinus Torvalds	movel	ARG1,%d0
25891da177e4SLinus Torvalds	lea	%a0@(%d0*4),%a0
25901da177e4SLinus Torvalds
25911da177e4SLinus Torvalds#if 0
25921da177e4SLinus Torvalds	dputn	%a0
25931da177e4SLinus Torvalds	dputc	'\n'
25941da177e4SLinus Torvalds#endif
25951da177e4SLinus Torvalds
25961da177e4SLinus Torvaldsfunc_return	mmu_get_root_table_entry
25971da177e4SLinus Torvalds
25981da177e4SLinus Torvalds
25991da177e4SLinus Torvalds
26001da177e4SLinus Torvaldsfunc_start	mmu_get_ptr_table_entry,%d0/%a1
26011da177e4SLinus Torvalds
26021da177e4SLinus Torvalds#if 0
26031da177e4SLinus Torvalds	dputs	"mmu_get_ptr_table_entry:"
26041da177e4SLinus Torvalds	dputn	ARG1
26051da177e4SLinus Torvalds	dputn	ARG2
26061da177e4SLinus Torvalds	dputs	" ="
26071da177e4SLinus Torvalds#endif
26081da177e4SLinus Torvalds
26091da177e4SLinus Torvalds	movel	ARG1,%a0
26101da177e4SLinus Torvalds	movel	%a0@,%d0
26111da177e4SLinus Torvalds	jne	2f
26121da177e4SLinus Torvalds
26131da177e4SLinus Torvalds	/* Keep track of the number of pointer tables we use
26141da177e4SLinus Torvalds	 */
26151da177e4SLinus Torvalds	dputs	"\nmmu_get_new_ptr_table:"
26161da177e4SLinus Torvalds	lea	%pc@(L(mmu_num_pointer_tables)),%a0
26171da177e4SLinus Torvalds	movel	%a0@,%d0
26181da177e4SLinus Torvalds	addql	#1,%a0@
26191da177e4SLinus Torvalds
26201da177e4SLinus Torvalds	/* See if there is a free pointer table in our cache of pointer tables
26211da177e4SLinus Torvalds	 */
26221da177e4SLinus Torvalds	lea	%pc@(L(mmu_cached_pointer_tables)),%a1
26231da177e4SLinus Torvalds	andw	#7,%d0
26241da177e4SLinus Torvalds	jne	1f
26251da177e4SLinus Torvalds
26261da177e4SLinus Torvalds	/* Get a new pointer table page from above the kernel memory
26271da177e4SLinus Torvalds	 */
26281da177e4SLinus Torvalds	get_new_page
26291da177e4SLinus Torvalds	movel	%a0,%a1@
26301da177e4SLinus Torvalds1:
26311da177e4SLinus Torvalds	/* There is an unused pointer table in our cache... use it
26321da177e4SLinus Torvalds	 */
26331da177e4SLinus Torvalds	movel	%a1@,%d0
26341da177e4SLinus Torvalds	addl	#PTR_TABLE_SIZE*4,%a1@
26351da177e4SLinus Torvalds
26361da177e4SLinus Torvalds	dputn	%d0
26371da177e4SLinus Torvalds	dputc	'\n'
26381da177e4SLinus Torvalds
26391da177e4SLinus Torvalds	/* Insert the new pointer table into the root table
26401da177e4SLinus Torvalds	 */
26411da177e4SLinus Torvalds	movel	ARG1,%a0
26421da177e4SLinus Torvalds	orw	#_PAGE_TABLE+_PAGE_ACCESSED,%d0
26431da177e4SLinus Torvalds	movel	%d0,%a0@
26441da177e4SLinus Torvalds2:
26451da177e4SLinus Torvalds	/* Extract the pointer table entry
26461da177e4SLinus Torvalds	 */
26471da177e4SLinus Torvalds	andw	#-PTR_TABLE_SIZE,%d0
26481da177e4SLinus Torvalds	movel	%d0,%a0
26491da177e4SLinus Torvalds	movel	ARG2,%d0
26501da177e4SLinus Torvalds	lea	%a0@(%d0*4),%a0
26511da177e4SLinus Torvalds
26521da177e4SLinus Torvalds#if 0
26531da177e4SLinus Torvalds	dputn	%a0
26541da177e4SLinus Torvalds	dputc	'\n'
26551da177e4SLinus Torvalds#endif
26561da177e4SLinus Torvalds
26571da177e4SLinus Torvaldsfunc_return	mmu_get_ptr_table_entry
26581da177e4SLinus Torvalds
26591da177e4SLinus Torvalds
26601da177e4SLinus Torvaldsfunc_start	mmu_get_page_table_entry,%d0/%a1
26611da177e4SLinus Torvalds
26621da177e4SLinus Torvalds#if 0
26631da177e4SLinus Torvalds	dputs	"mmu_get_page_table_entry:"
26641da177e4SLinus Torvalds	dputn	ARG1
26651da177e4SLinus Torvalds	dputn	ARG2
26661da177e4SLinus Torvalds	dputs	" ="
26671da177e4SLinus Torvalds#endif
26681da177e4SLinus Torvalds
26691da177e4SLinus Torvalds	movel	ARG1,%a0
26701da177e4SLinus Torvalds	movel	%a0@,%d0
26711da177e4SLinus Torvalds	jne	2f
26721da177e4SLinus Torvalds
26731da177e4SLinus Torvalds	/* If the page table entry doesn't exist, we allocate a complete new
26745661bccbSFinn Thain	 * page and use it as one continuous big page table which can cover
26751da177e4SLinus Torvalds	 * 4MB of memory, nearly almost all mappings have that alignment.
26761da177e4SLinus Torvalds	 */
26771da177e4SLinus Torvalds	get_new_page
26781da177e4SLinus Torvalds	addw	#_PAGE_TABLE+_PAGE_ACCESSED,%a0
26791da177e4SLinus Torvalds
26801da177e4SLinus Torvalds	/* align pointer table entry for a page of page tables
26811da177e4SLinus Torvalds	 */
26821da177e4SLinus Torvalds	movel	ARG1,%d0
26831da177e4SLinus Torvalds	andw	#-(PAGESIZE/PAGE_TABLE_SIZE),%d0
26841da177e4SLinus Torvalds	movel	%d0,%a1
26851da177e4SLinus Torvalds
26861da177e4SLinus Torvalds	/* Insert the page tables into the pointer entries
26871da177e4SLinus Torvalds	 */
26881da177e4SLinus Torvalds	moveq	#PAGESIZE/PAGE_TABLE_SIZE/4-1,%d0
26891da177e4SLinus Torvalds1:
26901da177e4SLinus Torvalds	movel	%a0,%a1@+
26911da177e4SLinus Torvalds	lea	%a0@(PAGE_TABLE_SIZE*4),%a0
26921da177e4SLinus Torvalds	dbra	%d0,1b
26931da177e4SLinus Torvalds
26941da177e4SLinus Torvalds	/* Now we can get the initialized pointer table entry
26951da177e4SLinus Torvalds	 */
26961da177e4SLinus Torvalds	movel	ARG1,%a0
26971da177e4SLinus Torvalds	movel	%a0@,%d0
26981da177e4SLinus Torvalds2:
26991da177e4SLinus Torvalds	/* Extract the page table entry
27001da177e4SLinus Torvalds	 */
27011da177e4SLinus Torvalds	andw	#-PAGE_TABLE_SIZE,%d0
27021da177e4SLinus Torvalds	movel	%d0,%a0
27031da177e4SLinus Torvalds	movel	ARG2,%d0
27041da177e4SLinus Torvalds	lea	%a0@(%d0*4),%a0
27051da177e4SLinus Torvalds
27061da177e4SLinus Torvalds#if 0
27071da177e4SLinus Torvalds	dputn	%a0
27081da177e4SLinus Torvalds	dputc	'\n'
27091da177e4SLinus Torvalds#endif
27101da177e4SLinus Torvalds
27111da177e4SLinus Torvaldsfunc_return	mmu_get_page_table_entry
27121da177e4SLinus Torvalds
27131da177e4SLinus Torvalds/*
27141da177e4SLinus Torvalds *	get_new_page
27151da177e4SLinus Torvalds *
27161da177e4SLinus Torvalds *	Return a new page from the memory start and clear it.
27171da177e4SLinus Torvalds */
27181da177e4SLinus Torvaldsfunc_start	get_new_page,%d0/%a1
27191da177e4SLinus Torvalds
27201da177e4SLinus Torvalds	dputs	"\nget_new_page:"
27211da177e4SLinus Torvalds
27221da177e4SLinus Torvalds	/* allocate the page and adjust memory_start
27231da177e4SLinus Torvalds	 */
27241da177e4SLinus Torvalds	lea	%pc@(L(memory_start)),%a0
27251da177e4SLinus Torvalds	movel	%a0@,%a1
27261da177e4SLinus Torvalds	addl	#PAGESIZE,%a0@
27271da177e4SLinus Torvalds
27281da177e4SLinus Torvalds	/* clear the new page
27291da177e4SLinus Torvalds	 */
27301da177e4SLinus Torvalds	movel	%a1,%a0
27311da177e4SLinus Torvalds	movew	#PAGESIZE/4-1,%d0
27321da177e4SLinus Torvalds1:
27331da177e4SLinus Torvalds	clrl	%a1@+
27341da177e4SLinus Torvalds	dbra	%d0,1b
27351da177e4SLinus Torvalds
27361da177e4SLinus Torvalds	dputn	%a0
27371da177e4SLinus Torvalds	dputc	'\n'
27381da177e4SLinus Torvalds
27391da177e4SLinus Torvaldsfunc_return	get_new_page
27401da177e4SLinus Torvalds
27411da177e4SLinus Torvalds
27421da177e4SLinus Torvalds
27431da177e4SLinus Torvalds/*
27441da177e4SLinus Torvalds * Debug output support
27451da177e4SLinus Torvalds * Atarians have a choice between the parallel port, the serial port
27461da177e4SLinus Torvalds * from the MFP or a serial port of the SCC
27471da177e4SLinus Torvalds */
27481da177e4SLinus Torvalds
27491da177e4SLinus Torvalds#ifdef CONFIG_MAC
275097f3f68cSFinn Thain/* You may define either or both of these. */
275197f3f68cSFinn Thain#define MAC_USE_SCC_A /* Modem port */
275297f3f68cSFinn Thain#define MAC_USE_SCC_B /* Printer port */
27531da177e4SLinus Torvalds
275497f3f68cSFinn Thain#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
275583adc181SFinn Thain/* Initialisation table for SCC with 3.6864 MHz PCLK */
27561da177e4SLinus TorvaldsL(scc_initable_mac):
27571da177e4SLinus Torvalds	.byte	4,0x44		/* x16, 1 stopbit, no parity */
27581da177e4SLinus Torvalds	.byte	3,0xc0		/* receiver: 8 bpc */
27591da177e4SLinus Torvalds	.byte	5,0xe2		/* transmitter: 8 bpc, assert dtr/rts */
27601da177e4SLinus Torvalds	.byte	10,0		/* NRZ */
27611da177e4SLinus Torvalds	.byte	11,0x50		/* use baud rate generator */
276293edd023SFinn Thain	.byte	12,1,13,0	/* 38400 baud */
27631da177e4SLinus Torvalds	.byte	14,1		/* Baud rate generator enable */
27641da177e4SLinus Torvalds	.byte	3,0xc1		/* enable receiver */
27651da177e4SLinus Torvalds	.byte	5,0xea		/* enable transmitter */
27661da177e4SLinus Torvalds	.byte	-1
27671da177e4SLinus Torvalds	.even
27681da177e4SLinus Torvalds#endif
276997f3f68cSFinn Thain#endif /* CONFIG_MAC */
27701da177e4SLinus Torvalds
27711da177e4SLinus Torvalds#ifdef CONFIG_ATARI
27721da177e4SLinus Torvalds/* #define USE_PRINTER */
27731da177e4SLinus Torvalds/* #define USE_SCC_B */
27741da177e4SLinus Torvalds/* #define USE_SCC_A */
27751da177e4SLinus Torvalds#define USE_MFP
27761da177e4SLinus Torvalds
27771da177e4SLinus Torvalds#if defined(USE_SCC_A) || defined(USE_SCC_B)
277883adc181SFinn Thain/* Initialisation table for SCC with 7.9872 MHz PCLK */
277983adc181SFinn Thain/* PCLK == 8.0539 gives baud == 9680.1 */
278083adc181SFinn ThainL(scc_initable_atari):
27811da177e4SLinus Torvalds	.byte	4,0x44		/* x16, 1 stopbit, no parity */
27821da177e4SLinus Torvalds	.byte	3,0xc0		/* receiver: 8 bpc */
27831da177e4SLinus Torvalds	.byte	5,0xe2		/* transmitter: 8 bpc, assert dtr/rts */
27841da177e4SLinus Torvalds	.byte	10,0		/* NRZ */
27851da177e4SLinus Torvalds	.byte	11,0x50		/* use baud rate generator */
27861da177e4SLinus Torvalds	.byte	12,24,13,0	/* 9600 baud */
27871da177e4SLinus Torvalds	.byte	14,2,14,3	/* use master clock for BRG, enable */
27881da177e4SLinus Torvalds	.byte	3,0xc1		/* enable receiver */
27891da177e4SLinus Torvalds	.byte	5,0xea		/* enable transmitter */
27901da177e4SLinus Torvalds	.byte	-1
27911da177e4SLinus Torvalds	.even
27921da177e4SLinus Torvalds#endif
27931da177e4SLinus Torvalds
27941da177e4SLinus Torvalds#ifdef USE_PRINTER
27951da177e4SLinus Torvalds
27961da177e4SLinus TorvaldsLPSG_SELECT	= 0xff8800
27971da177e4SLinus TorvaldsLPSG_READ	= 0xff8800
27981da177e4SLinus TorvaldsLPSG_WRITE	= 0xff8802
27991da177e4SLinus TorvaldsLPSG_IO_A	= 14
28001da177e4SLinus TorvaldsLPSG_IO_B	= 15
28011da177e4SLinus TorvaldsLPSG_CONTROL	= 7
28021da177e4SLinus TorvaldsLSTMFP_GPIP	= 0xfffa01
28031da177e4SLinus TorvaldsLSTMFP_DDR	= 0xfffa05
28041da177e4SLinus TorvaldsLSTMFP_IERB	= 0xfffa09
28051da177e4SLinus Torvalds
28061da177e4SLinus Torvalds#elif defined(USE_SCC_B)
28071da177e4SLinus Torvalds
28081da177e4SLinus TorvaldsLSCC_CTRL	= 0xff8c85
28091da177e4SLinus TorvaldsLSCC_DATA	= 0xff8c87
28101da177e4SLinus Torvalds
28111da177e4SLinus Torvalds#elif defined(USE_SCC_A)
28121da177e4SLinus Torvalds
28131da177e4SLinus TorvaldsLSCC_CTRL	= 0xff8c81
28141da177e4SLinus TorvaldsLSCC_DATA	= 0xff8c83
28151da177e4SLinus Torvalds
28161da177e4SLinus Torvalds#elif defined(USE_MFP)
28171da177e4SLinus Torvalds
28181da177e4SLinus TorvaldsLMFP_UCR     = 0xfffa29
28191da177e4SLinus TorvaldsLMFP_TDCDR   = 0xfffa1d
28201da177e4SLinus TorvaldsLMFP_TDDR    = 0xfffa25
28211da177e4SLinus TorvaldsLMFP_TSR     = 0xfffa2d
28221da177e4SLinus TorvaldsLMFP_UDR     = 0xfffa2f
28231da177e4SLinus Torvalds
28241da177e4SLinus Torvalds#endif
28251da177e4SLinus Torvalds#endif	/* CONFIG_ATARI */
28261da177e4SLinus Torvalds
28271da177e4SLinus Torvalds/*
28281da177e4SLinus Torvalds * Serial port output support.
28291da177e4SLinus Torvalds */
28301da177e4SLinus Torvalds
28311da177e4SLinus Torvalds/*
283283adc181SFinn Thain * Initialize serial port hardware
28331da177e4SLinus Torvalds */
28341da177e4SLinus Torvaldsfunc_start	serial_init,%d0/%d1/%a0/%a1
28351da177e4SLinus Torvalds	/*
28361da177e4SLinus Torvalds	 *	Some of the register usage that follows
28371da177e4SLinus Torvalds	 *	CONFIG_AMIGA
28381da177e4SLinus Torvalds	 *		a0 = pointer to boot info record
28391da177e4SLinus Torvalds	 *		d0 = boot info offset
28401da177e4SLinus Torvalds	 *	CONFIG_ATARI
28411da177e4SLinus Torvalds	 *		a0 = address of SCC
284283adc181SFinn Thain	 *		a1 = Liobase address/address of scc_initable_atari
28431da177e4SLinus Torvalds	 *		d0 = init data for serial port
28441da177e4SLinus Torvalds	 *	CONFIG_MAC
28451da177e4SLinus Torvalds	 *		a0 = address of SCC
28461da177e4SLinus Torvalds	 *		a1 = address of scc_initable_mac
28471da177e4SLinus Torvalds	 *		d0 = init data for serial port
28481da177e4SLinus Torvalds	 */
28491da177e4SLinus Torvalds
28501da177e4SLinus Torvalds#ifdef CONFIG_AMIGA
28511da177e4SLinus Torvalds#define SERIAL_DTR	7
28521da177e4SLinus Torvalds#define SERIAL_CNTRL	CIABBASE+C_PRA
28531da177e4SLinus Torvalds
28541da177e4SLinus Torvalds	is_not_amiga(1f)
28551da177e4SLinus Torvalds	lea	%pc@(L(custom)),%a0
28561da177e4SLinus Torvalds	movel	#-ZTWOBASE,%a0@
28571da177e4SLinus Torvalds	bclr	#SERIAL_DTR,SERIAL_CNTRL-ZTWOBASE
28581da177e4SLinus Torvalds	get_bi_record	BI_AMIGA_SERPER
28591da177e4SLinus Torvalds	movew	%a0@,CUSTOMBASE+C_SERPER-ZTWOBASE
28601da177e4SLinus Torvalds|	movew	#61,CUSTOMBASE+C_SERPER-ZTWOBASE
28611da177e4SLinus Torvalds1:
28621da177e4SLinus Torvalds#endif
286397f3f68cSFinn Thain
28641da177e4SLinus Torvalds#ifdef CONFIG_ATARI
28651da177e4SLinus Torvalds	is_not_atari(4f)
28661da177e4SLinus Torvalds	movel	%pc@(L(iobase)),%a1
28671da177e4SLinus Torvalds#if defined(USE_PRINTER)
28681da177e4SLinus Torvalds	bclr	#0,%a1@(LSTMFP_IERB)
28691da177e4SLinus Torvalds	bclr	#0,%a1@(LSTMFP_DDR)
28701da177e4SLinus Torvalds	moveb	#LPSG_CONTROL,%a1@(LPSG_SELECT)
28711da177e4SLinus Torvalds	moveb	#0xff,%a1@(LPSG_WRITE)
28721da177e4SLinus Torvalds	moveb	#LPSG_IO_B,%a1@(LPSG_SELECT)
28731da177e4SLinus Torvalds	clrb	%a1@(LPSG_WRITE)
28741da177e4SLinus Torvalds	moveb	#LPSG_IO_A,%a1@(LPSG_SELECT)
28751da177e4SLinus Torvalds	moveb	%a1@(LPSG_READ),%d0
28761da177e4SLinus Torvalds	bset	#5,%d0
28771da177e4SLinus Torvalds	moveb	%d0,%a1@(LPSG_WRITE)
287883adc181SFinn Thain#elif defined(USE_SCC_A) || defined(USE_SCC_B)
28791da177e4SLinus Torvalds	lea	%a1@(LSCC_CTRL),%a0
288083adc181SFinn Thain	/* Reset SCC register pointer */
288183adc181SFinn Thain	moveb	%a0@,%d0
288283adc181SFinn Thain	/* Reset SCC device: write register pointer then register value */
288383adc181SFinn Thain	moveb	#9,%a0@
288483adc181SFinn Thain	moveb	#0xc0,%a0@
288583adc181SFinn Thain	/* Wait for 5 PCLK cycles, which is about 63 CPU cycles */
288683adc181SFinn Thain	/* 5 / 7.9872 MHz = approx. 0.63 us = 63 / 100 MHz */
288783adc181SFinn Thain	movel	#32,%d0
288883adc181SFinn Thain2:
288983adc181SFinn Thain	subq	#1,%d0
289083adc181SFinn Thain	jne	2b
289183adc181SFinn Thain	/* Initialize channel */
289283adc181SFinn Thain	lea	%pc@(L(scc_initable_atari)),%a1
28931da177e4SLinus Torvalds2:	moveb	%a1@+,%d0
28941da177e4SLinus Torvalds	jmi	3f
28951da177e4SLinus Torvalds	moveb	%d0,%a0@
28961da177e4SLinus Torvalds	moveb	%a1@+,%a0@
28971da177e4SLinus Torvalds	jra	2b
28981da177e4SLinus Torvalds3:	clrb	%a0@
28991da177e4SLinus Torvalds#elif defined(USE_MFP)
29001da177e4SLinus Torvalds	bclr	#1,%a1@(LMFP_TSR)
29011da177e4SLinus Torvalds	moveb   #0x88,%a1@(LMFP_UCR)
29021da177e4SLinus Torvalds	andb	#0x70,%a1@(LMFP_TDCDR)
29031da177e4SLinus Torvalds	moveb   #2,%a1@(LMFP_TDDR)
29041da177e4SLinus Torvalds	orb	#1,%a1@(LMFP_TDCDR)
29051da177e4SLinus Torvalds	bset	#1,%a1@(LMFP_TSR)
29061da177e4SLinus Torvalds#endif
29071da177e4SLinus Torvalds	jra	L(serial_init_done)
29081da177e4SLinus Torvalds4:
29091da177e4SLinus Torvalds#endif
291097f3f68cSFinn Thain
29111da177e4SLinus Torvalds#ifdef CONFIG_MAC
29121da177e4SLinus Torvalds	is_not_mac(L(serial_init_not_mac))
291397f3f68cSFinn Thain#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
29141da177e4SLinus Torvalds#define mac_scc_cha_b_ctrl_offset	0x0
29151da177e4SLinus Torvalds#define mac_scc_cha_a_ctrl_offset	0x2
29161da177e4SLinus Torvalds#define mac_scc_cha_b_data_offset	0x4
29171da177e4SLinus Torvalds#define mac_scc_cha_a_data_offset	0x6
2918df66834aSFinn Thain	movel	%pc@(L(mac_sccbase)),%a0
291956931d73SFinn Thain	/* Reset SCC register pointer */
292056931d73SFinn Thain	moveb	%a0@(mac_scc_cha_a_ctrl_offset),%d0
292156931d73SFinn Thain	/* Reset SCC device: write register pointer then register value */
2922df66834aSFinn Thain	moveb	#9,%a0@(mac_scc_cha_a_ctrl_offset)
2923df66834aSFinn Thain	moveb	#0xc0,%a0@(mac_scc_cha_a_ctrl_offset)
2924df66834aSFinn Thain	/* Wait for 5 PCLK cycles, which is about 68 CPU cycles */
2925df66834aSFinn Thain	/* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */
2926df66834aSFinn Thain	movel	#35,%d0
2927df66834aSFinn Thain5:
2928df66834aSFinn Thain	subq	#1,%d0
2929df66834aSFinn Thain	jne	5b
2930df66834aSFinn Thain#endif
29311da177e4SLinus Torvalds#ifdef MAC_USE_SCC_A
29321da177e4SLinus Torvalds	/* Initialize channel A */
29331da177e4SLinus Torvalds	lea	%pc@(L(scc_initable_mac)),%a1
29341da177e4SLinus Torvalds5:	moveb	%a1@+,%d0
29351da177e4SLinus Torvalds	jmi	6f
29361da177e4SLinus Torvalds	moveb	%d0,%a0@(mac_scc_cha_a_ctrl_offset)
29371da177e4SLinus Torvalds	moveb	%a1@+,%a0@(mac_scc_cha_a_ctrl_offset)
29381da177e4SLinus Torvalds	jra	5b
29391da177e4SLinus Torvalds6:
29401da177e4SLinus Torvalds#endif	/* MAC_USE_SCC_A */
29411da177e4SLinus Torvalds#ifdef MAC_USE_SCC_B
29421da177e4SLinus Torvalds	/* Initialize channel B */
29431da177e4SLinus Torvalds	lea	%pc@(L(scc_initable_mac)),%a1
29441da177e4SLinus Torvalds7:	moveb	%a1@+,%d0
29451da177e4SLinus Torvalds	jmi	8f
29461da177e4SLinus Torvalds	moveb	%d0,%a0@(mac_scc_cha_b_ctrl_offset)
29471da177e4SLinus Torvalds	moveb	%a1@+,%a0@(mac_scc_cha_b_ctrl_offset)
29481da177e4SLinus Torvalds	jra	7b
29491da177e4SLinus Torvalds8:
29501da177e4SLinus Torvalds#endif	/* MAC_USE_SCC_B */
29511da177e4SLinus Torvalds	jra	L(serial_init_done)
29521da177e4SLinus TorvaldsL(serial_init_not_mac):
29531da177e4SLinus Torvalds#endif	/* CONFIG_MAC */
29541da177e4SLinus Torvalds
29551da177e4SLinus Torvalds#ifdef CONFIG_Q40
29561da177e4SLinus Torvalds	is_not_q40(2f)
29571da177e4SLinus Torvalds/* debug output goes into SRAM, so we don't do it unless requested
29581da177e4SLinus Torvalds   - check for '%LX$' signature in SRAM   */
29591da177e4SLinus Torvalds	lea	%pc@(q40_mem_cptr),%a1
29601da177e4SLinus Torvalds	move.l	#0xff020010,%a1@  /* must be inited - also used by debug=mem */
29611da177e4SLinus Torvalds	move.l	#0xff020000,%a1
29621da177e4SLinus Torvalds	cmp.b	#'%',%a1@
29631da177e4SLinus Torvalds	bne	2f	/*nodbg*/
29641da177e4SLinus Torvalds	addq.w	#4,%a1
29651da177e4SLinus Torvalds	cmp.b	#'L',%a1@
29661da177e4SLinus Torvalds	bne	2f	/*nodbg*/
29671da177e4SLinus Torvalds	addq.w	#4,%a1
29681da177e4SLinus Torvalds	cmp.b	#'X',%a1@
29691da177e4SLinus Torvalds	bne	2f	/*nodbg*/
29701da177e4SLinus Torvalds	addq.w	#4,%a1
29711da177e4SLinus Torvalds	cmp.b	#'$',%a1@
29721da177e4SLinus Torvalds	bne	2f	/*nodbg*/
29731da177e4SLinus Torvalds	/* signature OK */
29741da177e4SLinus Torvalds	lea	%pc@(L(q40_do_debug)),%a1
29751da177e4SLinus Torvalds	tas	%a1@
29761da177e4SLinus Torvalds/*nodbg: q40_do_debug is 0 by default*/
29771da177e4SLinus Torvalds2:
29781da177e4SLinus Torvalds#endif
29791da177e4SLinus Torvalds
2980c46f46d0SFinn Thain#ifdef CONFIG_MVME16x
2981c46f46d0SFinn Thain	is_not_mvme16x(L(serial_init_not_mvme16x))
2982c46f46d0SFinn Thain	moveb	#0x10,M167_PCSCCMICR
2983c46f46d0SFinn Thain	moveb	#0x10,M167_PCSCCTICR
2984c46f46d0SFinn Thain	moveb	#0x10,M167_PCSCCRICR
2985c46f46d0SFinn Thain	jra	L(serial_init_done)
2986c46f46d0SFinn ThainL(serial_init_not_mvme16x):
2987c46f46d0SFinn Thain#endif
2988c46f46d0SFinn Thain
29891da177e4SLinus Torvalds#ifdef CONFIG_APOLLO
29901da177e4SLinus Torvalds/* We count on the PROM initializing SIO1 */
29911da177e4SLinus Torvalds#endif
29921da177e4SLinus Torvalds
29931da177e4SLinus Torvalds#ifdef CONFIG_HP300
29941da177e4SLinus Torvalds/* We count on the boot loader initialising the UART */
29951da177e4SLinus Torvalds#endif
29961da177e4SLinus Torvalds
29971da177e4SLinus TorvaldsL(serial_init_done):
29981da177e4SLinus Torvaldsfunc_return	serial_init
29991da177e4SLinus Torvalds
30001da177e4SLinus Torvalds/*
30011da177e4SLinus Torvalds * Output character on serial port.
30021da177e4SLinus Torvalds */
30031da177e4SLinus Torvaldsfunc_start	serial_putc,%d0/%d1/%a0/%a1
30041da177e4SLinus Torvalds
30051da177e4SLinus Torvalds	movel	ARG1,%d0
30061da177e4SLinus Torvalds	cmpib	#'\n',%d0
30071da177e4SLinus Torvalds	jbne	1f
30081da177e4SLinus Torvalds
30091da177e4SLinus Torvalds	/* A little safe recursion is good for the soul */
30101da177e4SLinus Torvalds	serial_putc	#'\r'
30111da177e4SLinus Torvalds1:
30121da177e4SLinus Torvalds
30131da177e4SLinus Torvalds#ifdef CONFIG_AMIGA
30141da177e4SLinus Torvalds	is_not_amiga(2f)
30151da177e4SLinus Torvalds	andw	#0x00ff,%d0
30161da177e4SLinus Torvalds	oriw	#0x0100,%d0
30171da177e4SLinus Torvalds	movel	%pc@(L(custom)),%a0
30181da177e4SLinus Torvalds	movew	%d0,%a0@(CUSTOMBASE+C_SERDAT)
30191da177e4SLinus Torvalds1:	movew	%a0@(CUSTOMBASE+C_SERDATR),%d0
30201da177e4SLinus Torvalds	andw	#0x2000,%d0
30211da177e4SLinus Torvalds	jeq	1b
30221da177e4SLinus Torvalds	jra	L(serial_putc_done)
30231da177e4SLinus Torvalds2:
30241da177e4SLinus Torvalds#endif
30251da177e4SLinus Torvalds
30261da177e4SLinus Torvalds#ifdef CONFIG_MAC
30271da177e4SLinus Torvalds	is_not_mac(5f)
3028df66834aSFinn Thain#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B)
30291da177e4SLinus Torvalds	movel	%pc@(L(mac_sccbase)),%a1
3030df66834aSFinn Thain#endif
3031df66834aSFinn Thain#ifdef MAC_USE_SCC_A
30321da177e4SLinus Torvalds3:	btst	#2,%a1@(mac_scc_cha_a_ctrl_offset)
30331da177e4SLinus Torvalds	jeq	3b
30341da177e4SLinus Torvalds	moveb	%d0,%a1@(mac_scc_cha_a_data_offset)
30351da177e4SLinus Torvalds#endif	/* MAC_USE_SCC_A */
30361da177e4SLinus Torvalds#ifdef MAC_USE_SCC_B
30371da177e4SLinus Torvalds4:	btst	#2,%a1@(mac_scc_cha_b_ctrl_offset)
30381da177e4SLinus Torvalds	jeq	4b
30391da177e4SLinus Torvalds	moveb	%d0,%a1@(mac_scc_cha_b_data_offset)
30401da177e4SLinus Torvalds#endif	/* MAC_USE_SCC_B */
30411da177e4SLinus Torvalds	jra	L(serial_putc_done)
30421da177e4SLinus Torvalds5:
30431da177e4SLinus Torvalds#endif	/* CONFIG_MAC */
30441da177e4SLinus Torvalds
30451da177e4SLinus Torvalds#ifdef CONFIG_ATARI
30461da177e4SLinus Torvalds	is_not_atari(4f)
30471da177e4SLinus Torvalds	movel	%pc@(L(iobase)),%a1
30481da177e4SLinus Torvalds#if defined(USE_PRINTER)
30491da177e4SLinus Torvalds3:	btst	#0,%a1@(LSTMFP_GPIP)
30501da177e4SLinus Torvalds	jne	3b
30511da177e4SLinus Torvalds	moveb	#LPSG_IO_B,%a1@(LPSG_SELECT)
30521da177e4SLinus Torvalds	moveb	%d0,%a1@(LPSG_WRITE)
30531da177e4SLinus Torvalds	moveb	#LPSG_IO_A,%a1@(LPSG_SELECT)
30541da177e4SLinus Torvalds	moveb	%a1@(LPSG_READ),%d0
30551da177e4SLinus Torvalds	bclr	#5,%d0
30561da177e4SLinus Torvalds	moveb	%d0,%a1@(LPSG_WRITE)
30571da177e4SLinus Torvalds	nop
30581da177e4SLinus Torvalds	nop
30591da177e4SLinus Torvalds	bset	#5,%d0
30601da177e4SLinus Torvalds	moveb	%d0,%a1@(LPSG_WRITE)
306183adc181SFinn Thain#elif defined(USE_SCC_A) || defined(USE_SCC_B)
30621da177e4SLinus Torvalds3:	btst	#2,%a1@(LSCC_CTRL)
30631da177e4SLinus Torvalds	jeq	3b
30641da177e4SLinus Torvalds	moveb	%d0,%a1@(LSCC_DATA)
30651da177e4SLinus Torvalds#elif defined(USE_MFP)
30661da177e4SLinus Torvalds3:	btst	#7,%a1@(LMFP_TSR)
30671da177e4SLinus Torvalds	jeq	3b
30681da177e4SLinus Torvalds	moveb	%d0,%a1@(LMFP_UDR)
30691da177e4SLinus Torvalds#endif
30701da177e4SLinus Torvalds	jra	L(serial_putc_done)
30711da177e4SLinus Torvalds4:
30721da177e4SLinus Torvalds#endif	/* CONFIG_ATARI */
30731da177e4SLinus Torvalds
30741da177e4SLinus Torvalds#ifdef CONFIG_MVME147
30751da177e4SLinus Torvalds	is_not_mvme147(2f)
30761da177e4SLinus Torvalds1:	btst	#2,M147_SCC_CTRL_A
30771da177e4SLinus Torvalds	jeq	1b
30781da177e4SLinus Torvalds	moveb	%d0,M147_SCC_DATA_A
30791da177e4SLinus Torvalds	jbra	L(serial_putc_done)
30801da177e4SLinus Torvalds2:
30811da177e4SLinus Torvalds#endif
30821da177e4SLinus Torvalds
30831da177e4SLinus Torvalds#ifdef CONFIG_MVME16x
30841da177e4SLinus Torvalds	is_not_mvme16x(2f)
30851da177e4SLinus Torvalds	/*
30861da177e4SLinus Torvalds	 * If the loader gave us a board type then we can use that to
30871da177e4SLinus Torvalds	 * select an appropriate output routine; otherwise we just use
308825985edcSLucas De Marchi	 * the Bug code.  If we have to use the Bug that means the Bug
30891da177e4SLinus Torvalds	 * workspace has to be valid, which means the Bug has to use
30901da177e4SLinus Torvalds	 * the SRAM, which is non-standard.
30911da177e4SLinus Torvalds	 */
30921da177e4SLinus Torvalds	moveml	%d0-%d7/%a2-%a6,%sp@-
30931da177e4SLinus Torvalds	movel	vme_brdtype,%d1
30941da177e4SLinus Torvalds	jeq	1f			| No tag - use the Bug
30951da177e4SLinus Torvalds	cmpi	#VME_TYPE_MVME162,%d1
30961da177e4SLinus Torvalds	jeq	6f
30971da177e4SLinus Torvalds	cmpi	#VME_TYPE_MVME172,%d1
30981da177e4SLinus Torvalds	jne	5f
30991da177e4SLinus Torvalds	/* 162/172; it's an SCC */
31001da177e4SLinus Torvalds6:	btst	#2,M162_SCC_CTRL_A
31011da177e4SLinus Torvalds	nop
31021da177e4SLinus Torvalds	nop
31031da177e4SLinus Torvalds	nop
31041da177e4SLinus Torvalds	jeq	6b
31051da177e4SLinus Torvalds	moveb	#8,M162_SCC_CTRL_A
31061da177e4SLinus Torvalds	nop
31071da177e4SLinus Torvalds	nop
31081da177e4SLinus Torvalds	nop
31091da177e4SLinus Torvalds	moveb	%d0,M162_SCC_CTRL_A
31101da177e4SLinus Torvalds	jra	3f
31111da177e4SLinus Torvalds5:
31121da177e4SLinus Torvalds	/* 166/167/177; it's a CD2401 */
31131da177e4SLinus Torvalds	moveb	#0,M167_CYCAR
31141da177e4SLinus Torvalds	moveb	M167_CYIER,%d2
31151da177e4SLinus Torvalds	moveb	#0x02,M167_CYIER
31161da177e4SLinus Torvalds7:
31171da177e4SLinus Torvalds	btst	#5,M167_PCSCCTICR
31181da177e4SLinus Torvalds	jeq	7b
31191da177e4SLinus Torvalds	moveb	M167_PCTPIACKR,%d1
31201da177e4SLinus Torvalds	moveb	M167_CYLICR,%d1
31211da177e4SLinus Torvalds	jeq	8f
31221da177e4SLinus Torvalds	moveb	#0x08,M167_CYTEOIR
31231da177e4SLinus Torvalds	jra	7b
31241da177e4SLinus Torvalds8:
31251da177e4SLinus Torvalds	moveb	%d0,M167_CYTDR
31261da177e4SLinus Torvalds	moveb	#0,M167_CYTEOIR
31271da177e4SLinus Torvalds	moveb	%d2,M167_CYIER
31281da177e4SLinus Torvalds	jra	3f
31291da177e4SLinus Torvalds1:
31301da177e4SLinus Torvalds	moveb	%d0,%sp@-
31311da177e4SLinus Torvalds	trap	#15
31321da177e4SLinus Torvalds	.word	0x0020	/* TRAP 0x020 */
31331da177e4SLinus Torvalds3:
31341da177e4SLinus Torvalds	moveml	%sp@+,%d0-%d7/%a2-%a6
31351da177e4SLinus Torvalds	jbra	L(serial_putc_done)
31361da177e4SLinus Torvalds2:
31371da177e4SLinus Torvalds#endif /* CONFIG_MVME16x */
31381da177e4SLinus Torvalds
31391da177e4SLinus Torvalds#ifdef CONFIG_BVME6000
31401da177e4SLinus Torvalds	is_not_bvme6000(2f)
31411da177e4SLinus Torvalds	/*
31421da177e4SLinus Torvalds	 * The BVME6000 machine has a serial port ...
31431da177e4SLinus Torvalds	 */
31441da177e4SLinus Torvalds1:	btst	#2,BVME_SCC_CTRL_A
31451da177e4SLinus Torvalds	jeq	1b
31461da177e4SLinus Torvalds	moveb	%d0,BVME_SCC_DATA_A
31471da177e4SLinus Torvalds	jbra	L(serial_putc_done)
31481da177e4SLinus Torvalds2:
31491da177e4SLinus Torvalds#endif
31501da177e4SLinus Torvalds
31511da177e4SLinus Torvalds#ifdef CONFIG_SUN3X
31521da177e4SLinus Torvalds	is_not_sun3x(2f)
31531da177e4SLinus Torvalds	movel	%d0,-(%sp)
31541da177e4SLinus Torvalds	movel	0xFEFE0018,%a1
31551da177e4SLinus Torvalds	jbsr	(%a1)
31561da177e4SLinus Torvalds	addq	#4,%sp
31571da177e4SLinus Torvalds	jbra	L(serial_putc_done)
31581da177e4SLinus Torvalds2:
31591da177e4SLinus Torvalds#endif
31601da177e4SLinus Torvalds
31611da177e4SLinus Torvalds#ifdef CONFIG_Q40
31621da177e4SLinus Torvalds	is_not_q40(2f)
31631da177e4SLinus Torvalds	tst.l	%pc@(L(q40_do_debug))	/* only debug if requested */
31641da177e4SLinus Torvalds	beq	2f
31651da177e4SLinus Torvalds	lea	%pc@(q40_mem_cptr),%a1
31661da177e4SLinus Torvalds	move.l	%a1@,%a0
31671da177e4SLinus Torvalds	move.b	%d0,%a0@
31681da177e4SLinus Torvalds	addq.l	#4,%a0
31691da177e4SLinus Torvalds	move.l	%a0,%a1@
31701da177e4SLinus Torvalds	jbra    L(serial_putc_done)
31711da177e4SLinus Torvalds2:
31721da177e4SLinus Torvalds#endif
31731da177e4SLinus Torvalds
31741da177e4SLinus Torvalds#ifdef CONFIG_APOLLO
31751da177e4SLinus Torvalds	is_not_apollo(2f)
31761da177e4SLinus Torvalds	movl    %pc@(L(iobase)),%a1
31771da177e4SLinus Torvalds	moveb	%d0,%a1@(LTHRB0)
31781da177e4SLinus Torvalds1:      moveb   %a1@(LSRB0),%d0
31791da177e4SLinus Torvalds	andb	#0x4,%d0
31801da177e4SLinus Torvalds	beq	1b
31811da177e4SLinus Torvalds	jbra	L(serial_putc_done)
31821da177e4SLinus Torvalds2:
31831da177e4SLinus Torvalds#endif
31841da177e4SLinus Torvalds
31851da177e4SLinus Torvalds#ifdef CONFIG_HP300
31861da177e4SLinus Torvalds	is_not_hp300(3f)
31871da177e4SLinus Torvalds	movl    %pc@(L(iobase)),%a1
31881da177e4SLinus Torvalds	addl	%pc@(L(uartbase)),%a1
31891da177e4SLinus Torvalds	movel	%pc@(L(uart_scode)),%d1	/* Check the scode */
31901da177e4SLinus Torvalds	jmi	3f			/* Unset? Exit */
31911da177e4SLinus Torvalds	cmpi	#256,%d1		/* APCI scode? */
31921da177e4SLinus Torvalds	jeq	2f
31931da177e4SLinus Torvalds1:      moveb   %a1@(DCALSR),%d1	/* Output to DCA */
31941da177e4SLinus Torvalds	andb	#0x20,%d1
31951da177e4SLinus Torvalds	beq	1b
31961da177e4SLinus Torvalds	moveb	%d0,%a1@(DCADATA)
31971da177e4SLinus Torvalds	jbra	L(serial_putc_done)
31981da177e4SLinus Torvalds2:	moveb	%a1@(APCILSR),%d1	/* Output to APCI */
31991da177e4SLinus Torvalds	andb	#0x20,%d1
32001da177e4SLinus Torvalds	beq	2b
32011da177e4SLinus Torvalds	moveb	%d0,%a1@(APCIDATA)
32021da177e4SLinus Torvalds	jbra	L(serial_putc_done)
32031da177e4SLinus Torvalds3:
32041da177e4SLinus Torvalds#endif
32051da177e4SLinus Torvalds
3206*05d51e42SLaurent Vivier#ifdef CONFIG_VIRT
3207*05d51e42SLaurent Vivier	is_not_virt(1f)
3208*05d51e42SLaurent Vivier
3209*05d51e42SLaurent Vivier	movel L(virt_gf_tty_base),%a1
3210*05d51e42SLaurent Vivier	movel %d0,%a1@(GF_PUT_CHAR)
3211*05d51e42SLaurent Vivier1:
3212*05d51e42SLaurent Vivier#endif
3213*05d51e42SLaurent Vivier
32141da177e4SLinus TorvaldsL(serial_putc_done):
32151da177e4SLinus Torvaldsfunc_return	serial_putc
32161da177e4SLinus Torvalds
32171da177e4SLinus Torvalds/*
32181da177e4SLinus Torvalds * Output a string.
32191da177e4SLinus Torvalds */
32201da177e4SLinus Torvaldsfunc_start	puts,%d0/%a0
32211da177e4SLinus Torvalds
32221da177e4SLinus Torvalds	movel	ARG1,%a0
32231da177e4SLinus Torvalds	jra	2f
32241da177e4SLinus Torvalds1:
322597f3f68cSFinn Thain#ifdef CONSOLE_DEBUG
32261da177e4SLinus Torvalds	console_putc	%d0
32271da177e4SLinus Torvalds#endif
32281da177e4SLinus Torvalds#ifdef SERIAL_DEBUG
32291da177e4SLinus Torvalds	serial_putc	%d0
32301da177e4SLinus Torvalds#endif
32311da177e4SLinus Torvalds2:	moveb	%a0@+,%d0
32321da177e4SLinus Torvalds	jne	1b
32331da177e4SLinus Torvalds
32341da177e4SLinus Torvaldsfunc_return	puts
32351da177e4SLinus Torvalds
32361da177e4SLinus Torvalds/*
32371da177e4SLinus Torvalds * Output number in hex notation.
32381da177e4SLinus Torvalds */
32391da177e4SLinus Torvalds
32401da177e4SLinus Torvaldsfunc_start	putn,%d0-%d2
32411da177e4SLinus Torvalds
32421da177e4SLinus Torvalds	putc	' '
32431da177e4SLinus Torvalds
32441da177e4SLinus Torvalds	movel	ARG1,%d0
32451da177e4SLinus Torvalds	moveq	#7,%d1
32461da177e4SLinus Torvalds1:	roll	#4,%d0
32471da177e4SLinus Torvalds	move	%d0,%d2
32481da177e4SLinus Torvalds	andb	#0x0f,%d2
32491da177e4SLinus Torvalds	addb	#'0',%d2
32501da177e4SLinus Torvalds	cmpb	#'9',%d2
32511da177e4SLinus Torvalds	jls	2f
32521da177e4SLinus Torvalds	addb	#'A'-('9'+1),%d2
32531da177e4SLinus Torvalds2:
325497f3f68cSFinn Thain#ifdef CONSOLE_DEBUG
32551da177e4SLinus Torvalds	console_putc	%d2
32561da177e4SLinus Torvalds#endif
32571da177e4SLinus Torvalds#ifdef SERIAL_DEBUG
32581da177e4SLinus Torvalds	serial_putc	%d2
32591da177e4SLinus Torvalds#endif
32601da177e4SLinus Torvalds	dbra	%d1,1b
32611da177e4SLinus Torvalds
32621da177e4SLinus Torvaldsfunc_return	putn
32631da177e4SLinus Torvalds
32647913ad1aSFinn Thain#ifdef CONFIG_EARLY_PRINTK
32651da177e4SLinus Torvalds/*
32661da177e4SLinus Torvalds *	This routine takes its parameters on the stack.  It then
326793edd023SFinn Thain *	turns around and calls the internal routines.  This routine
326893edd023SFinn Thain *	is used by the boot console.
32691da177e4SLinus Torvalds *
32701da177e4SLinus Torvalds *	The calling parameters are:
32717913ad1aSFinn Thain *		void debug_cons_nputs(const char *str, unsigned length)
32721da177e4SLinus Torvalds *
32731da177e4SLinus Torvalds *	This routine does NOT understand variable arguments only
32741da177e4SLinus Torvalds *	simple strings!
32751da177e4SLinus Torvalds */
32767913ad1aSFinn ThainENTRY(debug_cons_nputs)
327793edd023SFinn Thain	moveml	%d0/%d1/%a0,%sp@-
327893edd023SFinn Thain	movew	%sr,%sp@-
32791da177e4SLinus Torvalds	ori	#0x0700,%sr
328093edd023SFinn Thain	movel	%sp@(18),%a0		/* fetch parameter */
328193edd023SFinn Thain	movel	%sp@(22),%d1		/* fetch parameter */
32821da177e4SLinus Torvalds	jra	2f
328393edd023SFinn Thain1:
328497f3f68cSFinn Thain#ifdef CONSOLE_DEBUG
328593edd023SFinn Thain	console_putc	%d0
32861da177e4SLinus Torvalds#endif
328793edd023SFinn Thain#ifdef SERIAL_DEBUG
328893edd023SFinn Thain	serial_putc	%d0
328993edd023SFinn Thain#endif
329093edd023SFinn Thain	subq	#1,%d1
329193edd023SFinn Thain2:	jeq	3f
329293edd023SFinn Thain	moveb	%a0@+,%d0
329393edd023SFinn Thain	jne	1b
329493edd023SFinn Thain3:
329593edd023SFinn Thain	movew	%sp@+,%sr
329693edd023SFinn Thain	moveml	%sp@+,%d0/%d1/%a0
32971da177e4SLinus Torvalds	rts
32987913ad1aSFinn Thain#endif /* CONFIG_EARLY_PRINTK */
32991da177e4SLinus Torvalds
33001da177e4SLinus Torvalds#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
33011da177e4SLinus Torvaldsfunc_start	set_leds,%d0/%a0
33021da177e4SLinus Torvalds	movel	ARG1,%d0
33031da177e4SLinus Torvalds#ifdef CONFIG_HP300
33041da177e4SLinus Torvalds	is_not_hp300(1f)
33051da177e4SLinus Torvalds	movel	%pc@(L(iobase)),%a0
33061da177e4SLinus Torvalds	moveb	%d0,%a0@(0x1ffff)
33071da177e4SLinus Torvalds	jra	2f
33081da177e4SLinus Torvalds#endif
33091da177e4SLinus Torvalds1:
33101da177e4SLinus Torvalds#ifdef CONFIG_APOLLO
33111da177e4SLinus Torvalds	movel   %pc@(L(iobase)),%a0
33121da177e4SLinus Torvalds	lsll    #8,%d0
33131da177e4SLinus Torvalds	eorw    #0xff00,%d0
33141da177e4SLinus Torvalds	moveb	%d0,%a0@(LCPUCTRL)
33151da177e4SLinus Torvalds#endif
33161da177e4SLinus Torvalds2:
33171da177e4SLinus Torvaldsfunc_return	set_leds
33181da177e4SLinus Torvalds#endif
33191da177e4SLinus Torvalds
332097f3f68cSFinn Thain#ifdef CONSOLE_DEBUG
33211da177e4SLinus Torvalds/*
33221da177e4SLinus Torvalds *	For continuity, see the data alignment
33231da177e4SLinus Torvalds *	to which this structure is tied.
33241da177e4SLinus Torvalds */
33251da177e4SLinus Torvalds#define Lconsole_struct_cur_column	0
33261da177e4SLinus Torvalds#define Lconsole_struct_cur_row		4
33271da177e4SLinus Torvalds#define Lconsole_struct_num_columns	8
33281da177e4SLinus Torvalds#define Lconsole_struct_num_rows	12
33291da177e4SLinus Torvalds#define Lconsole_struct_left_edge	16
33301da177e4SLinus Torvalds
33311da177e4SLinus Torvaldsfunc_start	console_init,%a0-%a4/%d0-%d7
33321da177e4SLinus Torvalds	/*
33331da177e4SLinus Torvalds	 *	Some of the register usage that follows
33341da177e4SLinus Torvalds	 *		a0 = pointer to boot_info
33351da177e4SLinus Torvalds	 *		a1 = pointer to screen
3336ecc79d49SGeert Uytterhoeven	 *		a2 = pointer to console_globals
33371da177e4SLinus Torvalds	 *		d3 = pixel width of screen
33381da177e4SLinus Torvalds	 *		d4 = pixel height of screen
33391da177e4SLinus Torvalds	 *		(d3,d4) ~= (x,y) of a point just below
33401da177e4SLinus Torvalds	 *			and to the right of the screen
33411da177e4SLinus Torvalds	 *			NOT on the screen!
33421da177e4SLinus Torvalds	 *		d5 = number of bytes per scan line
33431da177e4SLinus Torvalds	 *		d6 = number of bytes on the entire screen
33441da177e4SLinus Torvalds	 */
33451da177e4SLinus Torvalds
33461da177e4SLinus Torvalds	lea	%pc@(L(console_globals)),%a2
33471da177e4SLinus Torvalds	movel	%pc@(L(mac_videobase)),%a1
33481da177e4SLinus Torvalds	movel	%pc@(L(mac_rowbytes)),%d5
33491da177e4SLinus Torvalds	movel	%pc@(L(mac_dimensions)),%d3	/* -> low byte */
33501da177e4SLinus Torvalds	movel	%d3,%d4
33511da177e4SLinus Torvalds	swap	%d4		/* -> high byte */
33521da177e4SLinus Torvalds	andl	#0xffff,%d3	/* d3 = screen width in pixels */
33531da177e4SLinus Torvalds	andl	#0xffff,%d4	/* d4 = screen height in pixels */
33541da177e4SLinus Torvalds
33551da177e4SLinus Torvalds	movel	%d5,%d6
33561da177e4SLinus Torvalds|	subl	#20,%d6
33571da177e4SLinus Torvalds	mulul	%d4,%d6		/* scan line bytes x num scan lines */
33581da177e4SLinus Torvalds	divul	#8,%d6		/* we'll clear 8 bytes at a time */
33591da177e4SLinus Torvalds	moveq	#-1,%d0		/* Mac_black */
33601da177e4SLinus Torvalds	subq	#1,%d6
33611da177e4SLinus Torvalds
33621da177e4SLinus TorvaldsL(console_clear_loop):
33631da177e4SLinus Torvalds	movel	%d0,%a1@+
33641da177e4SLinus Torvalds	movel	%d0,%a1@+
33651da177e4SLinus Torvalds	dbra	%d6,L(console_clear_loop)
33661da177e4SLinus Torvalds
33671da177e4SLinus Torvalds	/* Calculate font size */
33681da177e4SLinus Torvalds
33691da177e4SLinus Torvalds#if   defined(FONT_8x8) && defined(CONFIG_FONT_8x8)
33701da177e4SLinus Torvalds	lea	%pc@(font_vga_8x8),%a0
33711da177e4SLinus Torvalds#elif defined(FONT_8x16) && defined(CONFIG_FONT_8x16)
33721da177e4SLinus Torvalds	lea	%pc@(font_vga_8x16),%a0
33731da177e4SLinus Torvalds#elif defined(FONT_6x11) && defined(CONFIG_FONT_6x11)
33741da177e4SLinus Torvalds	lea	%pc@(font_vga_6x11),%a0
33751da177e4SLinus Torvalds#elif defined(CONFIG_FONT_8x8) /* default */
33761da177e4SLinus Torvalds	lea	%pc@(font_vga_8x8),%a0
33771da177e4SLinus Torvalds#else /* no compiled-in font */
33781da177e4SLinus Torvalds	lea	0,%a0
33791da177e4SLinus Torvalds#endif
33801da177e4SLinus Torvalds
33811da177e4SLinus Torvalds	/*
33821da177e4SLinus Torvalds	 *	At this point we make a shift in register usage
33831da177e4SLinus Torvalds	 *	a1 = address of console_font pointer
33841da177e4SLinus Torvalds	 */
33851da177e4SLinus Torvalds	lea	%pc@(L(console_font)),%a1
33861da177e4SLinus Torvalds	movel	%a0,%a1@	/* store pointer to struct fbcon_font_desc in console_font */
33871da177e4SLinus Torvalds	tstl	%a0
33881da177e4SLinus Torvalds	jeq	1f
33891da177e4SLinus Torvalds	lea	%pc@(L(console_font_data)),%a4
33901da177e4SLinus Torvalds	movel	%a0@(FONT_DESC_DATA),%d0
33911da177e4SLinus Torvalds	subl	#L(console_font),%a1
33921da177e4SLinus Torvalds	addl	%a1,%d0
33931da177e4SLinus Torvalds	movel	%d0,%a4@
33941da177e4SLinus Torvalds
33951da177e4SLinus Torvalds	/*
33961da177e4SLinus Torvalds	 *	Calculate global maxs
33971da177e4SLinus Torvalds	 *	Note - we can use either an
33981da177e4SLinus Torvalds	 *	8 x 16 or 8 x 8 character font
33991da177e4SLinus Torvalds	 *	6 x 11 also supported
34001da177e4SLinus Torvalds	 */
34011da177e4SLinus Torvalds		/* ASSERT: a0 = contents of Lconsole_font */
34021da177e4SLinus Torvalds	movel	%d3,%d0				/* screen width in pixels */
34031da177e4SLinus Torvalds	divul	%a0@(FONT_DESC_WIDTH),%d0	/* d0 = max num chars per row */
34041da177e4SLinus Torvalds
34051da177e4SLinus Torvalds	movel	%d4,%d1				/* screen height in pixels */
34061da177e4SLinus Torvalds	divul	%a0@(FONT_DESC_HEIGHT),%d1	/* d1 = max num rows */
34071da177e4SLinus Torvalds
34081da177e4SLinus Torvalds	movel	%d0,%a2@(Lconsole_struct_num_columns)
34091da177e4SLinus Torvalds	movel	%d1,%a2@(Lconsole_struct_num_rows)
34101da177e4SLinus Torvalds
34111da177e4SLinus Torvalds	/*
34121da177e4SLinus Torvalds	 *	Clear the current row and column
34131da177e4SLinus Torvalds	 */
34141da177e4SLinus Torvalds	clrl	%a2@(Lconsole_struct_cur_column)
34151da177e4SLinus Torvalds	clrl	%a2@(Lconsole_struct_cur_row)
34161da177e4SLinus Torvalds	clrl	%a2@(Lconsole_struct_left_edge)
34171da177e4SLinus Torvalds
34181da177e4SLinus Torvalds	/*
34191da177e4SLinus Torvalds	 * Initialization is complete
34201da177e4SLinus Torvalds	 */
34211da177e4SLinus Torvalds1:
34221da177e4SLinus Torvaldsfunc_return	console_init
34231da177e4SLinus Torvalds
3424a91c406cSFinn Thain#ifdef CONFIG_LOGO
34251da177e4SLinus Torvaldsfunc_start	console_put_penguin,%a0-%a1/%d0-%d7
34261da177e4SLinus Torvalds	/*
34271da177e4SLinus Torvalds	 *	Get 'that_penguin' onto the screen in the upper right corner
34281da177e4SLinus Torvalds	 *	penguin is 64 x 74 pixels, align against right edge of screen
34291da177e4SLinus Torvalds	 */
34301da177e4SLinus Torvalds	lea	%pc@(L(mac_dimensions)),%a0
34311da177e4SLinus Torvalds	movel	%a0@,%d0
34321da177e4SLinus Torvalds	andil	#0xffff,%d0
34331da177e4SLinus Torvalds	subil	#64,%d0		/* snug up against the right edge */
34341da177e4SLinus Torvalds	clrl	%d1		/* start at the top */
34351da177e4SLinus Torvalds	movel	#73,%d7
34361da177e4SLinus Torvalds	lea	%pc@(L(that_penguin)),%a1
34371da177e4SLinus TorvaldsL(console_penguin_row):
34381da177e4SLinus Torvalds	movel	#31,%d6
34391da177e4SLinus TorvaldsL(console_penguin_pixel_pair):
34401da177e4SLinus Torvalds	moveb	%a1@,%d2
34411da177e4SLinus Torvalds	lsrb	#4,%d2
34421da177e4SLinus Torvalds	console_plot_pixel %d0,%d1,%d2
34431da177e4SLinus Torvalds	addq	#1,%d0
34441da177e4SLinus Torvalds	moveb	%a1@+,%d2
34451da177e4SLinus Torvalds	console_plot_pixel %d0,%d1,%d2
34461da177e4SLinus Torvalds	addq	#1,%d0
34471da177e4SLinus Torvalds	dbra	%d6,L(console_penguin_pixel_pair)
34481da177e4SLinus Torvalds
34491da177e4SLinus Torvalds	subil	#64,%d0
34501da177e4SLinus Torvalds	addq	#1,%d1
34511da177e4SLinus Torvalds	dbra	%d7,L(console_penguin_row)
34521da177e4SLinus Torvalds
34531da177e4SLinus Torvaldsfunc_return	console_put_penguin
34541da177e4SLinus Torvalds
34551da177e4SLinus Torvalds/* include penguin bitmap */
34561da177e4SLinus TorvaldsL(that_penguin):
34571da177e4SLinus Torvalds#include "../mac/mac_penguin.S"
34581da177e4SLinus Torvalds#endif
34591da177e4SLinus Torvalds
34601da177e4SLinus Torvalds	/*
34611da177e4SLinus Torvalds	 * Calculate source and destination addresses
34621da177e4SLinus Torvalds	 *	output	a1 = dest
34631da177e4SLinus Torvalds	 *		a2 = source
34641da177e4SLinus Torvalds	 */
34651da177e4SLinus Torvalds
34661da177e4SLinus Torvaldsfunc_start	console_scroll,%a0-%a4/%d0-%d7
34671da177e4SLinus Torvalds	lea	%pc@(L(mac_videobase)),%a0
34681da177e4SLinus Torvalds	movel	%a0@,%a1
34691da177e4SLinus Torvalds	movel	%a1,%a2
34701da177e4SLinus Torvalds	lea	%pc@(L(mac_rowbytes)),%a0
34711da177e4SLinus Torvalds	movel	%a0@,%d5
34721da177e4SLinus Torvalds	movel	%pc@(L(console_font)),%a0
34731da177e4SLinus Torvalds	tstl	%a0
34741da177e4SLinus Torvalds	jeq	1f
34751da177e4SLinus Torvalds	mulul	%a0@(FONT_DESC_HEIGHT),%d5	/* account for # scan lines per character */
34761da177e4SLinus Torvalds	addal	%d5,%a2
34771da177e4SLinus Torvalds
34781da177e4SLinus Torvalds	/*
34791da177e4SLinus Torvalds	 * Get dimensions
34801da177e4SLinus Torvalds	 */
34811da177e4SLinus Torvalds	lea	%pc@(L(mac_dimensions)),%a0
34821da177e4SLinus Torvalds	movel	%a0@,%d3
34831da177e4SLinus Torvalds	movel	%d3,%d4
34841da177e4SLinus Torvalds	swap	%d4
34851da177e4SLinus Torvalds	andl	#0xffff,%d3	/* d3 = screen width in pixels */
34861da177e4SLinus Torvalds	andl	#0xffff,%d4	/* d4 = screen height in pixels */
34871da177e4SLinus Torvalds
34881da177e4SLinus Torvalds	/*
34891da177e4SLinus Torvalds	 * Calculate number of bytes to move
34901da177e4SLinus Torvalds	 */
34911da177e4SLinus Torvalds	lea	%pc@(L(mac_rowbytes)),%a0
34921da177e4SLinus Torvalds	movel	%a0@,%d6
34931da177e4SLinus Torvalds	movel	%pc@(L(console_font)),%a0
34941da177e4SLinus Torvalds	subl	%a0@(FONT_DESC_HEIGHT),%d4	/* we're not scrolling the top row! */
34951da177e4SLinus Torvalds	mulul	%d4,%d6		/* scan line bytes x num scan lines */
34961da177e4SLinus Torvalds	divul	#32,%d6		/* we'll move 8 longs at a time */
34971da177e4SLinus Torvalds	subq	#1,%d6
34981da177e4SLinus Torvalds
34991da177e4SLinus TorvaldsL(console_scroll_loop):
35001da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35011da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35021da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35031da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35041da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35051da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35061da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35071da177e4SLinus Torvalds	movel	%a2@+,%a1@+
35081da177e4SLinus Torvalds	dbra	%d6,L(console_scroll_loop)
35091da177e4SLinus Torvalds
35101da177e4SLinus Torvalds	lea	%pc@(L(mac_rowbytes)),%a0
35111da177e4SLinus Torvalds	movel	%a0@,%d6
35121da177e4SLinus Torvalds	movel	%pc@(L(console_font)),%a0
35131da177e4SLinus Torvalds	mulul	%a0@(FONT_DESC_HEIGHT),%d6	/* scan line bytes x font height */
35141da177e4SLinus Torvalds	divul	#32,%d6			/* we'll move 8 words at a time */
35151da177e4SLinus Torvalds	subq	#1,%d6
35161da177e4SLinus Torvalds
35171da177e4SLinus Torvalds	moveq	#-1,%d0
35181da177e4SLinus TorvaldsL(console_scroll_clear_loop):
35191da177e4SLinus Torvalds	movel	%d0,%a1@+
35201da177e4SLinus Torvalds	movel	%d0,%a1@+
35211da177e4SLinus Torvalds	movel	%d0,%a1@+
35221da177e4SLinus Torvalds	movel	%d0,%a1@+
35231da177e4SLinus Torvalds	movel	%d0,%a1@+
35241da177e4SLinus Torvalds	movel	%d0,%a1@+
35251da177e4SLinus Torvalds	movel	%d0,%a1@+
35261da177e4SLinus Torvalds	movel	%d0,%a1@+
35271da177e4SLinus Torvalds	dbra	%d6,L(console_scroll_clear_loop)
35281da177e4SLinus Torvalds
35291da177e4SLinus Torvalds1:
35301da177e4SLinus Torvaldsfunc_return	console_scroll
35311da177e4SLinus Torvalds
35321da177e4SLinus Torvalds
35331da177e4SLinus Torvaldsfunc_start	console_putc,%a0/%a1/%d0-%d7
35341da177e4SLinus Torvalds
35351da177e4SLinus Torvalds	is_not_mac(L(console_exit))
35361da177e4SLinus Torvalds	tstl	%pc@(L(console_font))
35371da177e4SLinus Torvalds	jeq	L(console_exit)
35381da177e4SLinus Torvalds
35391da177e4SLinus Torvalds	/* Output character in d7 on console.
35401da177e4SLinus Torvalds	 */
35411da177e4SLinus Torvalds	movel	ARG1,%d7
35421da177e4SLinus Torvalds	cmpib	#'\n',%d7
35431da177e4SLinus Torvalds	jbne	1f
35441da177e4SLinus Torvalds
35451da177e4SLinus Torvalds	/* A little safe recursion is good for the soul */
35461da177e4SLinus Torvalds	console_putc	#'\r'
35471da177e4SLinus Torvalds1:
35481da177e4SLinus Torvalds	lea	%pc@(L(console_globals)),%a0
35491da177e4SLinus Torvalds
35501da177e4SLinus Torvalds	cmpib	#10,%d7
35511da177e4SLinus Torvalds	jne	L(console_not_lf)
35521da177e4SLinus Torvalds	movel	%a0@(Lconsole_struct_cur_row),%d0
35531da177e4SLinus Torvalds	addil	#1,%d0
35541da177e4SLinus Torvalds	movel	%d0,%a0@(Lconsole_struct_cur_row)
35551da177e4SLinus Torvalds	movel	%a0@(Lconsole_struct_num_rows),%d1
35561da177e4SLinus Torvalds	cmpl	%d1,%d0
35571da177e4SLinus Torvalds	jcs	1f
35581da177e4SLinus Torvalds	subil	#1,%d0
35591da177e4SLinus Torvalds	movel	%d0,%a0@(Lconsole_struct_cur_row)
35601da177e4SLinus Torvalds	console_scroll
35611da177e4SLinus Torvalds1:
35621da177e4SLinus Torvalds	jra	L(console_exit)
35631da177e4SLinus Torvalds
35641da177e4SLinus TorvaldsL(console_not_lf):
35651da177e4SLinus Torvalds	cmpib	#13,%d7
35661da177e4SLinus Torvalds	jne	L(console_not_cr)
35671da177e4SLinus Torvalds	clrl	%a0@(Lconsole_struct_cur_column)
35681da177e4SLinus Torvalds	jra	L(console_exit)
35691da177e4SLinus Torvalds
35701da177e4SLinus TorvaldsL(console_not_cr):
35711da177e4SLinus Torvalds	cmpib	#1,%d7
35721da177e4SLinus Torvalds	jne	L(console_not_home)
35731da177e4SLinus Torvalds	clrl	%a0@(Lconsole_struct_cur_row)
35741da177e4SLinus Torvalds	clrl	%a0@(Lconsole_struct_cur_column)
35751da177e4SLinus Torvalds	jra	L(console_exit)
35761da177e4SLinus Torvalds
35771da177e4SLinus Torvalds/*
35781da177e4SLinus Torvalds *	At this point we know that the %d7 character is going to be
35791da177e4SLinus Torvalds *	rendered on the screen.  Register usage is -
35801da177e4SLinus Torvalds *		a0 = pointer to console globals
35811da177e4SLinus Torvalds *		a1 = font data
35821da177e4SLinus Torvalds *		d0 = cursor column
35831da177e4SLinus Torvalds *		d1 = cursor row to draw the character
35841da177e4SLinus Torvalds *		d7 = character number
35851da177e4SLinus Torvalds */
35861da177e4SLinus TorvaldsL(console_not_home):
35871da177e4SLinus Torvalds	movel	%a0@(Lconsole_struct_cur_column),%d0
35881da177e4SLinus Torvalds	addql	#1,%a0@(Lconsole_struct_cur_column)
35891da177e4SLinus Torvalds	movel	%a0@(Lconsole_struct_num_columns),%d1
35901da177e4SLinus Torvalds	cmpl	%d1,%d0
35911da177e4SLinus Torvalds	jcs	1f
35921da177e4SLinus Torvalds	console_putc	#'\n'	/* recursion is OK! */
35931da177e4SLinus Torvalds1:
35941da177e4SLinus Torvalds	movel	%a0@(Lconsole_struct_cur_row),%d1
35951da177e4SLinus Torvalds
35961da177e4SLinus Torvalds	/*
35971da177e4SLinus Torvalds	 *	At this point we make a shift in register usage
35981da177e4SLinus Torvalds	 *	a0 = address of pointer to font data (fbcon_font_desc)
35991da177e4SLinus Torvalds	 */
36001da177e4SLinus Torvalds	movel	%pc@(L(console_font)),%a0
36011da177e4SLinus Torvalds	movel	%pc@(L(console_font_data)),%a1	/* Load fbcon_font_desc.data into a1 */
36021da177e4SLinus Torvalds	andl	#0x000000ff,%d7
36031da177e4SLinus Torvalds		/* ASSERT: a0 = contents of Lconsole_font */
36041da177e4SLinus Torvalds	mulul	%a0@(FONT_DESC_HEIGHT),%d7	/* d7 = index into font data */
36051da177e4SLinus Torvalds	addl	%d7,%a1			/* a1 = points to char image */
36061da177e4SLinus Torvalds
36071da177e4SLinus Torvalds	/*
36081da177e4SLinus Torvalds	 *	At this point we make a shift in register usage
36091da177e4SLinus Torvalds	 *	d0 = pixel coordinate, x
36101da177e4SLinus Torvalds	 *	d1 = pixel coordinate, y
36111da177e4SLinus Torvalds	 *	d2 = (bit 0) 1/0 for white/black (!) pixel on screen
36121da177e4SLinus Torvalds	 *	d3 = font scan line data (8 pixels)
36131da177e4SLinus Torvalds	 *	d6 = count down for the font's pixel width (8)
36141da177e4SLinus Torvalds	 *	d7 = count down for the font's pixel count in height
36151da177e4SLinus Torvalds	 */
36161da177e4SLinus Torvalds		/* ASSERT: a0 = contents of Lconsole_font */
36171da177e4SLinus Torvalds	mulul	%a0@(FONT_DESC_WIDTH),%d0
36181da177e4SLinus Torvalds	mulul	%a0@(FONT_DESC_HEIGHT),%d1
36191da177e4SLinus Torvalds	movel	%a0@(FONT_DESC_HEIGHT),%d7	/* Load fbcon_font_desc.height into d7 */
36201da177e4SLinus Torvalds	subq	#1,%d7
36211da177e4SLinus TorvaldsL(console_read_char_scanline):
36221da177e4SLinus Torvalds	moveb	%a1@+,%d3
36231da177e4SLinus Torvalds
36241da177e4SLinus Torvalds		/* ASSERT: a0 = contents of Lconsole_font */
36251da177e4SLinus Torvalds	movel	%a0@(FONT_DESC_WIDTH),%d6	/* Load fbcon_font_desc.width into d6 */
36261da177e4SLinus Torvalds	subql	#1,%d6
36271da177e4SLinus Torvalds
36281da177e4SLinus TorvaldsL(console_do_font_scanline):
36291da177e4SLinus Torvalds	lslb	#1,%d3
36301da177e4SLinus Torvalds	scsb	%d2		/* convert 1 bit into a byte */
36311da177e4SLinus Torvalds	console_plot_pixel %d0,%d1,%d2
36321da177e4SLinus Torvalds	addq	#1,%d0
36331da177e4SLinus Torvalds	dbra	%d6,L(console_do_font_scanline)
36341da177e4SLinus Torvalds
36351da177e4SLinus Torvalds		/* ASSERT: a0 = contents of Lconsole_font */
36361da177e4SLinus Torvalds	subl	%a0@(FONT_DESC_WIDTH),%d0
36371da177e4SLinus Torvalds	addq	#1,%d1
36381da177e4SLinus Torvalds	dbra	%d7,L(console_read_char_scanline)
36391da177e4SLinus Torvalds
36401da177e4SLinus TorvaldsL(console_exit):
36411da177e4SLinus Torvaldsfunc_return	console_putc
36421da177e4SLinus Torvalds
36431da177e4SLinus Torvalds	/*
36441da177e4SLinus Torvalds	 *	Input:
36451da177e4SLinus Torvalds	 *		d0 = x coordinate
36461da177e4SLinus Torvalds	 *		d1 = y coordinate
36471da177e4SLinus Torvalds	 *		d2 = (bit 0) 1/0 for white/black (!)
36481da177e4SLinus Torvalds	 *	All registers are preserved
36491da177e4SLinus Torvalds	 */
36501da177e4SLinus Torvaldsfunc_start	console_plot_pixel,%a0-%a1/%d0-%d4
36511da177e4SLinus Torvalds
36521da177e4SLinus Torvalds	movel	%pc@(L(mac_videobase)),%a1
36531da177e4SLinus Torvalds	movel	%pc@(L(mac_videodepth)),%d3
36541da177e4SLinus Torvalds	movel	ARG1,%d0
36551da177e4SLinus Torvalds	movel	ARG2,%d1
36561da177e4SLinus Torvalds	mulul	%pc@(L(mac_rowbytes)),%d1
36571da177e4SLinus Torvalds	movel	ARG3,%d2
36581da177e4SLinus Torvalds
36591da177e4SLinus Torvalds	/*
36601da177e4SLinus Torvalds	 *	Register usage:
36611da177e4SLinus Torvalds	 *		d0 = x coord becomes byte offset into frame buffer
36621da177e4SLinus Torvalds	 *		d1 = y coord
36631da177e4SLinus Torvalds	 *		d2 = black or white (0/1)
36641da177e4SLinus Torvalds	 *		d3 = video depth
36651da177e4SLinus Torvalds	 *		d4 = temp of x (d0) for many bit depths
36661da177e4SLinus Torvalds	 */
36671da177e4SLinus TorvaldsL(test_1bit):
36681da177e4SLinus Torvalds	cmpb	#1,%d3
36691da177e4SLinus Torvalds	jbne	L(test_2bit)
36701da177e4SLinus Torvalds	movel	%d0,%d4		/* we need the low order 3 bits! */
36711da177e4SLinus Torvalds	divul	#8,%d0
36721da177e4SLinus Torvalds	addal	%d0,%a1
36731da177e4SLinus Torvalds	addal	%d1,%a1
36741da177e4SLinus Torvalds	andb	#7,%d4
36751da177e4SLinus Torvalds	eorb	#7,%d4		/* reverse the x-coordinate w/ screen-bit # */
36761da177e4SLinus Torvalds	andb	#1,%d2
36771da177e4SLinus Torvalds	jbne	L(white_1)
36781da177e4SLinus Torvalds	bsetb	%d4,%a1@
36791da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
36801da177e4SLinus TorvaldsL(white_1):
36811da177e4SLinus Torvalds	bclrb	%d4,%a1@
36821da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
36831da177e4SLinus Torvalds
36841da177e4SLinus TorvaldsL(test_2bit):
36851da177e4SLinus Torvalds	cmpb	#2,%d3
36861da177e4SLinus Torvalds	jbne	L(test_4bit)
36871da177e4SLinus Torvalds	movel	%d0,%d4		/* we need the low order 2 bits! */
36881da177e4SLinus Torvalds	divul	#4,%d0
36891da177e4SLinus Torvalds	addal	%d0,%a1
36901da177e4SLinus Torvalds	addal	%d1,%a1
36911da177e4SLinus Torvalds	andb	#3,%d4
36921da177e4SLinus Torvalds	eorb	#3,%d4		/* reverse the x-coordinate w/ screen-bit # */
36931da177e4SLinus Torvalds	lsll	#1,%d4		/* ! */
36941da177e4SLinus Torvalds	andb	#1,%d2
36951da177e4SLinus Torvalds	jbne	L(white_2)
36961da177e4SLinus Torvalds	bsetb	%d4,%a1@
36971da177e4SLinus Torvalds	addq	#1,%d4
36981da177e4SLinus Torvalds	bsetb	%d4,%a1@
36991da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37001da177e4SLinus TorvaldsL(white_2):
37011da177e4SLinus Torvalds	bclrb	%d4,%a1@
37021da177e4SLinus Torvalds	addq	#1,%d4
37031da177e4SLinus Torvalds	bclrb	%d4,%a1@
37041da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37051da177e4SLinus Torvalds
37061da177e4SLinus TorvaldsL(test_4bit):
37071da177e4SLinus Torvalds	cmpb	#4,%d3
37081da177e4SLinus Torvalds	jbne	L(test_8bit)
37091da177e4SLinus Torvalds	movel	%d0,%d4		/* we need the low order bit! */
37101da177e4SLinus Torvalds	divul	#2,%d0
37111da177e4SLinus Torvalds	addal	%d0,%a1
37121da177e4SLinus Torvalds	addal	%d1,%a1
37131da177e4SLinus Torvalds	andb	#1,%d4
37141da177e4SLinus Torvalds	eorb	#1,%d4
37151da177e4SLinus Torvalds	lsll	#2,%d4		/* ! */
37161da177e4SLinus Torvalds	andb	#1,%d2
37171da177e4SLinus Torvalds	jbne	L(white_4)
37181da177e4SLinus Torvalds	bsetb	%d4,%a1@
37191da177e4SLinus Torvalds	addq	#1,%d4
37201da177e4SLinus Torvalds	bsetb	%d4,%a1@
37211da177e4SLinus Torvalds	addq	#1,%d4
37221da177e4SLinus Torvalds	bsetb	%d4,%a1@
37231da177e4SLinus Torvalds	addq	#1,%d4
37241da177e4SLinus Torvalds	bsetb	%d4,%a1@
37251da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37261da177e4SLinus TorvaldsL(white_4):
37271da177e4SLinus Torvalds	bclrb	%d4,%a1@
37281da177e4SLinus Torvalds	addq	#1,%d4
37291da177e4SLinus Torvalds	bclrb	%d4,%a1@
37301da177e4SLinus Torvalds	addq	#1,%d4
37311da177e4SLinus Torvalds	bclrb	%d4,%a1@
37321da177e4SLinus Torvalds	addq	#1,%d4
37331da177e4SLinus Torvalds	bclrb	%d4,%a1@
37341da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37351da177e4SLinus Torvalds
37361da177e4SLinus TorvaldsL(test_8bit):
37371da177e4SLinus Torvalds	cmpb	#8,%d3
37381da177e4SLinus Torvalds	jbne	L(test_16bit)
37391da177e4SLinus Torvalds	addal	%d0,%a1
37401da177e4SLinus Torvalds	addal	%d1,%a1
37411da177e4SLinus Torvalds	andb	#1,%d2
37421da177e4SLinus Torvalds	jbne	L(white_8)
37431da177e4SLinus Torvalds	moveb	#0xff,%a1@
37441da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37451da177e4SLinus TorvaldsL(white_8):
37461da177e4SLinus Torvalds	clrb	%a1@
37471da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37481da177e4SLinus Torvalds
37491da177e4SLinus TorvaldsL(test_16bit):
37501da177e4SLinus Torvalds	cmpb	#16,%d3
37511da177e4SLinus Torvalds	jbne	L(console_plot_pixel_exit)
37521da177e4SLinus Torvalds	addal	%d0,%a1
37531da177e4SLinus Torvalds	addal	%d0,%a1
37541da177e4SLinus Torvalds	addal	%d1,%a1
37551da177e4SLinus Torvalds	andb	#1,%d2
37561da177e4SLinus Torvalds	jbne	L(white_16)
37571da177e4SLinus Torvalds	clrw	%a1@
37581da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37591da177e4SLinus TorvaldsL(white_16):
37601da177e4SLinus Torvalds	movew	#0x0fff,%a1@
37611da177e4SLinus Torvalds	jbra	L(console_plot_pixel_exit)
37621da177e4SLinus Torvalds
37631da177e4SLinus TorvaldsL(console_plot_pixel_exit):
37641da177e4SLinus Torvaldsfunc_return	console_plot_pixel
376597f3f68cSFinn Thain#endif /* CONSOLE_DEBUG */
37661da177e4SLinus Torvalds
37671da177e4SLinus Torvalds
37681da177e4SLinus Torvalds__INITDATA
37691da177e4SLinus Torvalds	.align	4
37701da177e4SLinus Torvalds
3771486df8bcSAndreas Schwabm68k_init_mapped_size:
3772486df8bcSAndreas Schwab	.long	0
3773486df8bcSAndreas Schwab
37741da177e4SLinus Torvalds#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \
37751da177e4SLinus Torvalds    defined(CONFIG_HP300) || defined(CONFIG_APOLLO)
37761da177e4SLinus TorvaldsL(custom):
37771da177e4SLinus TorvaldsL(iobase):
37781da177e4SLinus Torvalds	.long 0
37791da177e4SLinus Torvalds#endif
37801da177e4SLinus Torvalds
378197f3f68cSFinn Thain#ifdef CONSOLE_DEBUG
37821da177e4SLinus TorvaldsL(console_globals):
37831da177e4SLinus Torvalds	.long	0		/* cursor column */
37841da177e4SLinus Torvalds	.long	0		/* cursor row */
37851da177e4SLinus Torvalds	.long	0		/* max num columns */
37861da177e4SLinus Torvalds	.long	0		/* max num rows */
37871da177e4SLinus Torvalds	.long	0		/* left edge */
37881da177e4SLinus TorvaldsL(console_font):
37891da177e4SLinus Torvalds	.long	0		/* pointer to console font (struct font_desc) */
37901da177e4SLinus TorvaldsL(console_font_data):
37911da177e4SLinus Torvalds	.long	0		/* pointer to console font data */
379297f3f68cSFinn Thain#endif /* CONSOLE_DEBUG */
37931da177e4SLinus Torvalds
37941da177e4SLinus Torvalds#if defined(MMU_PRINT)
37951da177e4SLinus TorvaldsL(mmu_print_data):
37961da177e4SLinus Torvalds	.long	0		/* valid flag */
37971da177e4SLinus Torvalds	.long	0		/* start logical */
37981da177e4SLinus Torvalds	.long	0		/* next logical */
37991da177e4SLinus Torvalds	.long	0		/* start physical */
38001da177e4SLinus Torvalds	.long	0		/* next physical */
38011da177e4SLinus Torvalds#endif /* MMU_PRINT */
38021da177e4SLinus Torvalds
38031da177e4SLinus TorvaldsL(cputype):
38041da177e4SLinus Torvalds	.long	0
38051da177e4SLinus TorvaldsL(mmu_cached_pointer_tables):
38061da177e4SLinus Torvalds	.long	0
38071da177e4SLinus TorvaldsL(mmu_num_pointer_tables):
38081da177e4SLinus Torvalds	.long	0
38091da177e4SLinus TorvaldsL(phys_kernel_start):
38101da177e4SLinus Torvalds	.long	0
38111da177e4SLinus TorvaldsL(kernel_end):
38121da177e4SLinus Torvalds	.long	0
38131da177e4SLinus TorvaldsL(memory_start):
38141da177e4SLinus Torvalds	.long	0
38151da177e4SLinus TorvaldsL(kernel_pgdir_ptr):
38161da177e4SLinus Torvalds	.long	0
38171da177e4SLinus TorvaldsL(temp_mmap_mem):
38181da177e4SLinus Torvalds	.long	0
38191da177e4SLinus Torvalds
38201da177e4SLinus Torvalds#if defined (CONFIG_MVME147)
38211da177e4SLinus TorvaldsM147_SCC_CTRL_A = 0xfffe3002
38221da177e4SLinus TorvaldsM147_SCC_DATA_A = 0xfffe3003
38231da177e4SLinus Torvalds#endif
38241da177e4SLinus Torvalds
38251da177e4SLinus Torvalds#if defined (CONFIG_MVME16x)
38261da177e4SLinus TorvaldsM162_SCC_CTRL_A = 0xfff45005
38271da177e4SLinus TorvaldsM167_CYCAR = 0xfff450ee
38281da177e4SLinus TorvaldsM167_CYIER = 0xfff45011
38291da177e4SLinus TorvaldsM167_CYLICR = 0xfff45026
38301da177e4SLinus TorvaldsM167_CYTEOIR = 0xfff45085
38311da177e4SLinus TorvaldsM167_CYTDR = 0xfff450f8
3832c46f46d0SFinn ThainM167_PCSCCMICR = 0xfff4201d
38331da177e4SLinus TorvaldsM167_PCSCCTICR = 0xfff4201e
3834c46f46d0SFinn ThainM167_PCSCCRICR = 0xfff4201f
38351da177e4SLinus TorvaldsM167_PCTPIACKR = 0xfff42025
38361da177e4SLinus Torvalds#endif
38371da177e4SLinus Torvalds
38381da177e4SLinus Torvalds#if defined (CONFIG_BVME6000)
38391da177e4SLinus TorvaldsBVME_SCC_CTRL_A	= 0xffb0000b
38401da177e4SLinus TorvaldsBVME_SCC_DATA_A	= 0xffb0000f
38411da177e4SLinus Torvalds#endif
38421da177e4SLinus Torvalds
38431da177e4SLinus Torvalds#if defined(CONFIG_MAC)
38441da177e4SLinus TorvaldsL(mac_videobase):
38451da177e4SLinus Torvalds	.long	0
38461da177e4SLinus TorvaldsL(mac_videodepth):
38471da177e4SLinus Torvalds	.long	0
38481da177e4SLinus TorvaldsL(mac_dimensions):
38491da177e4SLinus Torvalds	.long	0
38501da177e4SLinus TorvaldsL(mac_rowbytes):
38511da177e4SLinus Torvalds	.long	0
38521da177e4SLinus TorvaldsL(mac_sccbase):
38531da177e4SLinus Torvalds	.long	0
385493edd023SFinn Thain#endif /* CONFIG_MAC */
38551da177e4SLinus Torvalds
38561da177e4SLinus Torvalds#if defined (CONFIG_APOLLO)
38571da177e4SLinus TorvaldsLSRB0        = 0x10412
38581da177e4SLinus TorvaldsLTHRB0       = 0x10416
38591da177e4SLinus TorvaldsLCPUCTRL     = 0x10100
38601da177e4SLinus Torvalds#endif
38611da177e4SLinus Torvalds
38621da177e4SLinus Torvalds#if defined(CONFIG_HP300)
38631da177e4SLinus TorvaldsDCADATA	     = 0x11
38641da177e4SLinus TorvaldsDCALSR	     = 0x1b
38651da177e4SLinus TorvaldsAPCIDATA     = 0x00
38661da177e4SLinus TorvaldsAPCILSR      = 0x14
38671da177e4SLinus TorvaldsL(uartbase):
38681da177e4SLinus Torvalds	.long	0
38691da177e4SLinus TorvaldsL(uart_scode):
38701da177e4SLinus Torvalds	.long	-1
38711da177e4SLinus Torvalds#endif
38721da177e4SLinus Torvalds
38731da177e4SLinus Torvalds__FINIT
38741da177e4SLinus Torvalds	.data
38751da177e4SLinus Torvalds	.align	4
38761da177e4SLinus Torvalds
38771da177e4SLinus Torvaldsavailmem:
38781da177e4SLinus Torvalds	.long	0
38791da177e4SLinus Torvaldsm68k_pgtable_cachemode:
38801da177e4SLinus Torvalds	.long	0
38811da177e4SLinus Torvaldsm68k_supervisor_cachemode:
38821da177e4SLinus Torvalds	.long	0
38831da177e4SLinus Torvalds#if defined(CONFIG_MVME16x)
38841da177e4SLinus Torvaldsmvme_bdid:
38851da177e4SLinus Torvalds	.long	0,0,0,0,0,0,0,0
38861da177e4SLinus Torvalds#endif
38871da177e4SLinus Torvalds#if defined(CONFIG_Q40)
38881da177e4SLinus Torvaldsq40_mem_cptr:
38891da177e4SLinus Torvalds	.long	0
38901da177e4SLinus TorvaldsL(q40_do_debug):
38911da177e4SLinus Torvalds	.long	0
38921da177e4SLinus Torvalds#endif
3893*05d51e42SLaurent Vivier
3894*05d51e42SLaurent Vivier#if defined(CONFIG_VIRT)
3895*05d51e42SLaurent VivierGF_PUT_CHAR = 0x00
3896*05d51e42SLaurent VivierL(virt_gf_tty_base):
3897*05d51e42SLaurent Vivier	.long 0
3898*05d51e42SLaurent Vivier#endif /* CONFIG_VIRT */
3899