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