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