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