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