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