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