1 /* SPDX-License-Identifier: GPL-2.0-or-later << 2 ** -*- mode: asm -*- << 3 ** << 4 ** head.S -- This file contains the initial bo << 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 idea << 15 ** and Bjoern Brauel << 16 ** VME Support by Richard Hirst << 17 ** << 18 ** 94/11/14 Andreas Schwab: put kernel at PAGE << 19 ** 94/11/18 Andreas Schwab: remove identity ma << 20 ** ++ Bjoern & Roman: ATARI-68040 support for << 21 ** 95/11/18 Richard Hirst: Added MVME166 suppo << 22 ** 96/04/26 Guenther Kelleter: fixed identity << 23 ** Magnum- and FX-a << 24 ** 98/04/25 Phil Blundell: added HP300 support << 25 ** 1998/08/30 David Kilzer: Added support for << 26 ** for linux-2.1.115 << 27 ** 1999/02/11 Richard Zidlicky: added Q40 sup << 28 ** 2004/05/13 Kars de Jong: Finalised HP300 su << 29 */ << 30 << 31 /* 1 /* 32 * Linux startup code. !! 2 * linux/arch/i386/kernel/head.S -- the 32-bit startup code. 33 * << 34 * At this point, the boot loader has: << 35 * Disabled interrupts << 36 * Disabled caches << 37 * Put us in supervisor state. << 38 * << 39 * The kernel setup code takes the following s << 40 * . Raise interrupt level << 41 * . Set up initial kernel memory mapping. << 42 * . This sets up a mapping of the 4M of m << 43 * . It also does a mapping of any initial << 44 * . Enable the MMU << 45 * . Enable cache memories << 46 * . Jump to kernel startup << 47 * << 48 * Much of the file restructuring was to accom << 49 * 1) Remove register dependency through-out t << 50 * 2) Increase use of subroutines to perform f << 51 * 3) Increase readability of the code << 52 * << 53 * Of course, readability is a subjective issu << 54 * argued that that goal was accomplished. It << 55 * A key way to help make code more readable i << 56 * documentation. So, the first thing you wil << 57 * write-ups on the structure of the file, and << 58 * functional subroutines. << 59 * << 60 * General Structure: << 61 * ------------------ << 62 * Without a doubt the single largest chu << 63 * mapping the kernel and I/O physical space i << 64 * for the kernel. << 65 * There are new subroutines and data str << 66 * support cleaner and easier to understand. << 67 * First, you will find a routine call "m << 68 * a logical to a physical region for some len << 69 * type on behalf of the caller. This routine << 70 * actual per-machine specific code very simpl << 71 * A central part of the code, but not a << 72 * is the mmu_init code which is broken down i << 73 * (the same for all machines) and mapping mac << 74 * regions. << 75 * Also, there will be a description of e << 76 * caches. << 77 * You will notice that there is a chunk << 78 * can emit the entire MMU mapping of the mach << 79 * only in debug modes and can be very helpful << 80 * Further, there is a new console driver << 81 * also only engaged in debug mode. Currently << 82 * on the Macintosh class of machines. Howeve << 83 * others will plug-in support for specific ma << 84 * << 85 * ########################################### << 86 * << 87 * mmu_map << 88 * ------- << 89 * mmu_map was written for two key reason << 90 * that it was very difficult to read the prev << 91 * regions of memory. Second, the Macintosh r << 92 * memory allocations that it didn't make sens << 93 * existing code any further. << 94 * mmu_map requires some parameters: << 95 * << 96 * mmu_map (logical, physical, length, ca << 97 * << 98 * While this essentially describes the f << 99 * find more indepth description of other para << 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 r << 109 * a table, if necessary a new table is alloca << 110 * basically like pmd_alloc() and pte_alloc() << 111 * table needs of course only to be allocated << 112 * so that here also some mmu specific initial << 113 * at the start of the kernel (the first page << 114 * the kernel_pg_dir. It must be at a position << 115 * to initialize the init task struct) and sin << 116 * settings, it's the easiest to use this page << 117 * for further pointer tables. << 118 * mmu_get_page_table_entry allocates always a << 119 * means 1024 pages and so 4MB of memory can b << 120 * to manage page tables in smaller pieces as << 121 * size. << 122 * << 123 * ########################################### << 124 * << 125 * << 126 * ########################################### << 127 * << 128 * mmu_engage << 129 * ---------- << 130 * Thanks to a small helping routine enab << 131 * and there is only one way left. mmu_engage << 132 * that only includes the absolute necessary t << 133 * position and to restore the original mappin << 134 * As this code doesn't need a transparent tra << 135 * means all registers are free to be used by << 136 * other purposes. << 137 * << 138 * ########################################### << 139 * << 140 * mmu_print << 141 * --------- << 142 * This algorithm will print out the page << 143 * appropriate for an 030 or an 040. This is << 144 * and as such is enclosed in #ifdef MMU_PRINT << 145 * << 146 * ########################################### << 147 * << 148 * console_init << 149 * ------------ << 150 * The console is also able to be turned << 151 * is specifically for debugging and can be ve << 152 * #ifdef / #endif clauses so it doesn't have << 153 * kernels. It's basic algorithm is to determ << 154 * (in height/width and bit depth) and then us << 155 * displaying an 8x8 font or an 8x16 (widthxhe << 156 * debugging so I can see more good data. But << 157 * for both fonts, so I included it. << 158 * Also, the algorithm for plotting pixel << 159 * theory other platforms could add support fo << 160 * buffers. This could be very useful. << 161 * << 162 * console_put_penguin << 163 * ------------------- << 164 * An important part of any Linux bring u << 165 * nothing like getting the Penguin on the scr << 166 * on any machine for which there is a console << 167 * << 168 * console_scroll << 169 * -------------- << 170 * My hope is that the scroll algorithm d << 171 * various platforms, but it wouldn't be hard << 172 * and new code if it doesn't. << 173 * << 174 * console_putc << 175 * ------------- << 176 * << 177 * ########################################### << 178 * << 179 * Register usage has greatly simplified << 180 * saves and restores all registers that it mo << 181 * value in there of course). So the only regi << 182 * is the stack pointer. << 183 * All other init code and data is now placed << 184 * be automatically freed at the end of the ke << 185 * 3 * 186 * ########################################### !! 4 * Copyright (C) 1991, 1992 Linus Torvalds 187 * 5 * 188 * options !! 6 * Enhanced CPU detection and feature setting code by Mike Jagdis 189 * ------- !! 7 * and Martin Mares, November 1997. 190 * There are many options available in a << 191 * taken the time to describe them here to sav << 192 * for them and trying to understand what they << 193 * << 194 * CONFIG_xxx: These are the obvious machine << 195 * during configuration. These are defined in << 196 * << 197 * CONSOLE_DEBUG: Only supports a Mac frame b << 198 * extended to support other platforms. << 199 * << 200 * TEST_MMU: This is a test harness for run << 201 * getting an MMU dump for another class of ma << 202 * that can be tested are any of the makes (At << 203 * and any of the models (030, 040, 060, etc.) << 204 * << 205 * NOTE: TEST_MMU is NOT permanent! It << 206 * When head.S boots on Atari, Am << 207 * machines. At that point the u << 208 * believed to be solid enough to << 209 * can be dropped. Do note that << 210 * head.S code significantly as l << 211 * clauses can be removed. << 212 * << 213 * MMU_NOCACHE_KERNEL: On the Macintosh platf << 214 * determing why devices don't appear to work. << 215 * the cacheability of the kernel bits. << 216 * << 217 * MMU_PRINT: There is a routine built into << 218 * MMU data structures. It outputs its result << 219 * interface. So where ever that winds up dri << 220 * mmu struct will appear. << 221 * << 222 * SERIAL_DEBUG: There are a series of << 223 * scattered through out the code to give prog << 224 * person sitting at the console. This consta << 225 * are used. << 226 * << 227 * DEBUG: This is the standard DEBUG fla << 228 * the kernel. It has the effect << 229 * the code. << 230 * << 231 * FONT_6x11: << 232 * FONT_8x8: << 233 * FONT_8x16: << 234 * In theory these could be deter << 235 * over by the booter. But, let' << 236 * coded value. (But, you will n << 237 * flexible!) A pointer to the f << 238 * is kept locally in Lconsole_fo << 239 * font size information dynamica << 240 * << 241 * Atari constants: << 242 * USE_PRINTER: Use the printer port for seria << 243 * USE_SCC_B: Use the SCC port A (Serial2) f << 244 * USE_SCC_A: Use the SCC port B (Modem2) fo << 245 * USE_MFP: Use the ST-MFP port (Modem1) f << 246 * << 247 * Macintosh constants: << 248 * MAC_USE_SCC_A: Use SCC port A (modem) for s << 249 * MAC_USE_SCC_B: Use SCC port B (printer) for << 250 */ 8 */ 251 9 >> 10 .text >> 11 #include <linux/config.h> >> 12 #include <linux/threads.h> 252 #include <linux/linkage.h> 13 #include <linux/linkage.h> 253 #include <linux/init.h> !! 14 #include <asm/segment.h> 254 #include <linux/pgtable.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> << 265 #include <asm/page.h> 15 #include <asm/page.h> 266 #include <asm/asm-offsets.h> !! 16 #include <asm/pgtable.h> 267 #ifdef CONFIG_MAC !! 17 #include <asm/desc.h> 268 # include <asm/machw.h> << 269 #endif << 270 << 271 #ifdef CONFIG_EARLY_PRINTK << 272 # define SERIAL_DEBUG << 273 # if defined(CONFIG_MAC) && defined(CONFIG_FO << 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 sup << 284 * The 8x8 font is harder to read but fits mor << 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 << 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 tran << 314 TTR_ANYMODE = 0x4000 /* user and ke << 315 TTR_KERNELMODE = 0x2000 /* only kernel << 316 TTR_USERMODE = 0x0000 /* only user m << 317 TTR_CI = 0x0400 /* inhibit cac << 318 TTR_RW = 0x0200 /* read/write << 319 TTR_RWM = 0x0100 /* read/write << 320 TTR_FCB2 = 0x0040 /* function co << 321 TTR_FCB1 = 0x0020 /* function co << 322 TTR_FCB0 = 0x0010 /* function co << 323 TTR_FCM2 = 0x0004 /* function co << 324 TTR_FCM1 = 0x0002 /* function co << 325 TTR_FCM0 = 0x0001 /* function co << 326 << 327 /* Cache Control registers */ << 328 CC6_ENABLE_D = 0x80000000 /* enable data << 329 CC6_FREEZE_D = 0x40000000 /* freeze data << 330 CC6_ENABLE_SB = 0x20000000 /* enable stor << 331 CC6_PUSH_DPI = 0x10000000 /* disable CPU << 332 CC6_HALF_D = 0x08000000 /* half-cache << 333 CC6_ENABLE_B = 0x00800000 /* enable bran << 334 CC6_CLRA_B = 0x00400000 /* clear all e << 335 CC6_CLRU_B = 0x00200000 /* clear user << 336 CC6_ENABLE_I = 0x00008000 /* enable inst << 337 CC6_FREEZE_I = 0x00004000 /* freeze inst << 338 CC6_HALF_I = 0x00002000 /* half-cache << 339 CC3_ALLOC_WRITE = 0x00002000 /* write alloc << 340 CC3_ENABLE_DB = 0x00001000 /* enable data << 341 CC3_CLR_D = 0x00000800 /* clear data << 342 CC3_CLRE_D = 0x00000400 /* clear entry << 343 CC3_FREEZE_D = 0x00000200 /* freeze data << 344 CC3_ENABLE_D = 0x00000100 /* enable data << 345 CC3_ENABLE_IB = 0x00000010 /* enable inst << 346 CC3_CLR_I = 0x00000008 /* clear instr << 347 CC3_CLRE_I = 0x00000004 /* clear entry << 348 CC3_FREEZE_I = 0x00000002 /* freeze inst << 349 CC3_ENABLE_I = 0x00000001 /* enable inst << 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 label << 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 << 378 #ifndef __INITDATA << 379 #define __INITDATA .data << 380 #define __FINIT .previous << 381 #endif << 382 << 383 /* Several macros to make the writing of subro << 384 * - func_start marks the beginning of the rou << 385 * register and saves the registers, it also << 386 * to automatically restore the registers ag << 387 * - func_return marks the end of the routine << 388 * macro to restore registers and jump back << 389 * - func_define generates another macro to au << 390 * onto the stack call the subroutine and cl << 391 */ << 392 << 393 /* Within subroutines these macros can be used << 394 * on the stack. With STACK some allocated mem << 395 * accessed and ARG0 points to the return addr << 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, << 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, << 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_AP << 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_D << 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_D << 485 addql #4,%sp << 486 #endif << 487 .endm << 488 << 489 .macro dputc ch << 490 #ifdef DEBUG << 491 putc \ch << 492 #endif << 493 .endm << 494 << 495 func_define putn,1 << 496 << 497 .macro dputn nr << 498 #ifdef DEBUG << 499 putn \nr << 500 #endif << 501 .endm << 502 << 503 .macro puts string << 504 #if defined(CONSOLE_DEBUG) || defined(SERIAL_D << 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 << 514 << 515 .macro dputs string << 516 #ifdef DEBUG << 517 puts "\string" << 518 #endif << 519 .endm << 520 << 521 #define is_not_amiga(lab) cmpl &MACH_AMIGA,%pc << 522 #define is_not_atari(lab) cmpl &MACH_ATARI,%pc << 523 #define is_not_mac(lab) cmpl &MACH_MAC,%pc@(m6 << 524 #define is_not_mvme147(lab) cmpl &MACH_MVME147 << 525 #define is_not_mvme16x(lab) cmpl &MACH_MVME16x << 526 #define is_not_bvme6000(lab) cmpl &MACH_BVME60 << 527 #define is_mvme147(lab) cmpl &MACH_MVME147,%pc << 528 #define is_mvme16x(lab) cmpl &MACH_MVME16x,%pc << 529 #define is_bvme6000(lab) cmpl &MACH_BVME6000,% << 530 #define is_not_hp300(lab) cmpl &MACH_HP300,%pc << 531 #define is_not_apollo(lab) cmpl &MACH_APOLLO,% << 532 #define is_not_q40(lab) cmpl &MACH_Q40,%pc@(m6 << 533 #define is_not_sun3x(lab) cmpl &MACH_SUN3X,%pc << 534 #define is_not_virt(lab) cmpl &MACH_VIRT,%pc@( << 535 << 536 #define hasnt_leds(lab) cmpl &MACH_HP300,%pc@( << 537 jeq 42f; \ << 538 cmpl &MACH_APOLLO,%pc@ << 539 jne lab ;\ << 540 42:\ << 541 << 542 #define is_040_or_060(lab) btst &CPUTYPE_ << 543 #define is_not_040_or_060(lab) btst &CPUTYPE_ << 544 #define is_040(lab) btst &CPUTYPE_ << 545 #define is_060(lab) btst &CPUTYPE_ << 546 #define is_not_060(lab) btst &CPUTYPE_ << 547 #define is_020(lab) btst &CPUTYPE_ << 548 #define is_not_020(lab) btst &CPUTYPE_ << 549 << 550 /* On the HP300 we use the on-board LEDs for d << 551 the console is running. Writing a 1 bit tu << 552 _off_ - on the 340 bit 7 is towards the bac << 553 .macro leds mask << 554 #if defined(CONFIG_HP300) || defined(CONFIG_AP << 555 hasnt_leds(.Lled\@) << 556 pea \mask << 557 func_call set_leds << 558 addql #4,%sp << 559 .Lled\@: << 560 #endif << 561 .endm << 562 << 563 __HEAD << 564 ENTRY(_stext) << 565 /* << 566 * Version numbers of the bootinfo interface << 567 * The area from _stext to _start will later b << 568 */ << 569 bras 1f /* Jump over bootinfo << 570 << 571 .long BOOTINFOV_MAGIC << 572 .long MACH_AMIGA, AMIGA_BOOTI_VERSIO << 573 .long MACH_ATARI, ATARI_BOOTI_VERSIO << 574 .long MACH_MVME147, MVME147_BOOTI_VE << 575 .long MACH_MVME16x, MVME16x_BOOTI_VE << 576 .long MACH_BVME6000, BVME6000_BOOTI_ << 577 .long MACH_MAC, MAC_BOOTI_VERSION << 578 .long MACH_Q40, Q40_BOOTI_VERSION << 579 .long MACH_HP300, HP300_BOOTI_VERSIO << 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 << 595 << 596 /* << 597 * Record the CPU and machine type. << 598 */ << 599 get_bi_record BI_MACHTYPE << 600 lea %pc@(m68k_machtype),%a1 << 601 movel %a0@,%a1@ << 602 << 603 get_bi_record BI_FPUTYPE << 604 lea %pc@(m68k_fputype),%a1 << 605 movel %a0@,%a1@ << 606 << 607 get_bi_record BI_MMUTYPE << 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 dis << 620 * while debugging it). << 621 */ << 622 << 623 is_not_mac(L(test_notmac)) << 624 << 625 get_bi_record BI_MAC_VADDR << 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 */ << 656 << 657 /* << 658 * There are ultimately two pieces of informat << 659 * processors CpuType and CacheBits. The CPUT << 660 * and is converted here from a booter type de << 661 * number which allows for the standard is_0x0 << 662 */ << 663 movel %pc@(m68k_cputype),%d0 << 664 /* << 665 * Assume it's an 030 << 666 */ << 667 clrl %d1 << 668 << 669 /* << 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@ << 700 << 701 /* << 702 * NOTE: << 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 */ << 711 << 712 /* << 713 * Determine the cache mode for pages << 714 * and for supervisor mode, unused for << 715 */ << 716 clrl %d0 << 717 clrl %d1 << 718 << 719 is_not_040_or_060(L(save_cachetype)) << 720 << 721 /* << 722 * '040 or '060 << 723 * d1 := cacheable write-through << 724 * NOTE: The 68040 manual strongly rec << 725 * but we have been using write-throug << 726 * guess it is OK. << 727 */ << 728 #ifdef CONFIG_060_WRITETHROUGH << 729 /* << 730 * If this is a 68060 board using driv << 731 * problems, then supervisor memory ac << 732 * also; otherwise, we want copyback. << 733 */ << 734 << 735 is_not_060(1f) << 736 movel #_PAGE_CACHE040W,%d0 << 737 jra L(save_cachetype) << 738 #endif /* CONFIG_060_WRITETHROUGH */ << 739 1: << 740 movew #_PAGE_CACHE040,%d0 << 741 << 742 movel #_PAGE_CACHE040W,%d1 << 743 << 744 L(save_cachetype): << 745 /* Save cache mode for supervisor mode << 746 */ << 747 lea %pc@(m68k_supervisor_cachemode << 748 movel %d0,%a0@ << 749 lea %pc@(m68k_pgtable_cachemode),% << 750 movel %d1,%a0@ << 751 << 752 /* << 753 * raise interrupt level << 754 */ << 755 movew #0x2700,%sr << 756 << 757 /* << 758 If running on an Atari, determine the I/O b << 759 serial port and test if we are running on a << 760 This test is necessary here, because on the << 761 port is only accessible in the high I/O mem << 762 << 763 The test whether it is a Medusa is done by << 764 phys. 0x0. This should result in a bus erro << 765 << 766 ...should, but doesn't. The Afterburner040 << 767 same behaviour (0x0..0x7 are no ROM shadow) << 768 another test to distinguish Medusa and AB04 << 769 read attempt for 0x00ff82fe phys. that shou << 770 (+AB040), but is in the range where the Med << 771 << 772 The test for the Hades is done by reading a << 773 should give a bus error on the Medusa. << 774 */ << 775 << 776 #ifdef CONFIG_ATARI << 777 is_not_atari(L(notypetest)) << 778 << 779 /* get special machine type (Medusa/Ha << 780 moveq #0,%d3 /* default if tag doesn << 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 se << 789 * serial port. There are no I/O regs << 790 moveq #0,%d0 << 791 cmpl #ATARI_MACH_HADES,%d3 << 792 jbne 1f << 793 movel #0xff000000,%d0 /* Had << 794 1: lea %pc@(L(iobase)),%a0 << 795 movel %d0,%a0@ << 796 << 797 L(notypetest): << 798 #endif << 799 << 800 #ifdef CONFIG_VME << 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 << 806 * versions of VMELILO and TFTPLILO do << 807 * early so we know how to handle cons << 808 * doesn't exist then we use the Bug f << 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)) << 820 << 821 /* Need to get the BRD_ID info to diff << 822 * etc. This is available as a BI_VME << 823 * versions of VMELILO and TFTPLILO, o << 824 */ << 825 get_bi_record BI_VME_BRDINFO << 826 tstl %d0 << 827 jpl 1f << 828 << 829 /* Get pointer to board ID data from B << 830 movel %d2,%sp@- << 831 trap #15 << 832 .word 0x70 /* trap 0x70 - << 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 << 846 << 847 L(gvtdone): << 848 << 849 #endif << 850 << 851 #ifdef CONFIG_HP300 << 852 is_not_hp300(L(nothp)) << 853 << 854 /* Get the address of the UART for ser << 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): << 869 #endif << 870 << 871 /* << 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 necessa << 916 * of machines for execution of Linux. << 917 * First map the first 4, 8, or 16 MB of << 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),%a << 931 movel %d1,%a0@ << 932 mmu_map #PAGE_OFFSET,%pc@(L(phys_kerne << 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 << 944 */ << 945 << 946 putc 'D' << 947 << 948 is_not_040_or_060(1f) << 949 << 950 /* << 951 * 040: Map the 16Meg range physical 0 << 952 */ << 953 mmu_map #0x80000000,#0,#0x0100 << 954 /* << 955 * Map the Zorro III I/O space with tr << 956 * for frame buffer memory etc. << 957 */ << 958 mmu_map_tt #1,#0x40000000,#0x2000 << 959 << 960 jbra L(mmu_init_done) << 961 << 962 1: << 963 /* << 964 * 030: Map the 32Meg range physical 0 << 965 */ << 966 mmu_map #0x80000000,#0,#0x0200 << 967 mmu_map_tt #1,#0x40000000,#0x2000 << 968 << 969 jbra L(mmu_init_done) << 970 18 971 L(mmu_init_not_amiga): !! 19 #define OLD_CL_MAGIC_ADDR 0x90020 972 #endif !! 20 #define OLD_CL_MAGIC 0xA33F 973 !! 21 #define OLD_CL_BASE_ADDR 0x90000 974 #ifdef CONFIG_ATARI !! 22 #define OLD_CL_OFFSET 0x90022 975 !! 23 #define NEW_CL_POINTER 0x228 /* Relative to real mode data */ 976 L(mmu_init_atari): << 977 << 978 is_not_atari(L(mmu_init_not_atari)) << 979 << 980 putc 'E' << 981 << 982 /* On the Atari, we map the I/O region (phys. << 983 the last 16 MB of virtual address space to << 984 0xffxxxxxx -> 0x00xxxxxx). For this, an add << 985 needed. I/O ranges are marked non-cachable. << 986 << 987 For the Medusa it is better to map the I/O << 988 (i.e. 0xffxxxxxx -> 0xffxxxxxx), because so << 989 accessible only in the high area. << 990 << 991 On the Hades all I/O registers are only acc << 992 area. << 993 */ << 994 << 995 /* I/O base addr for non-Medusa, non-H << 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/Had << 1003 1: movel %d0,%d3 << 1004 << 1005 is_040_or_060(L(spata68040)) << 1006 << 1007 /* Map everything non-cacheable, thou << 1008 * need to disable caches (crucial on << 1009 * (standard I/O) and 0xf00000..0xf3f << 1010 * isn't really used, except for some << 1011 * ROMs (mirror at phys. 0x0), so cac << 1012 * this. */ << 1013 mmu_map #0xff000000,%d3,#0x01000000,# << 1014 << 1015 jbra L(mmu_init_done) << 1016 << 1017 L(spata68040): << 1018 << 1019 mmu_map #0xff000000,%d3,#0x01000000,# << 1020 << 1021 jbra L(mmu_init_done) << 1022 << 1023 L(mmu_init_not_atari): << 1024 #endif << 1025 << 1026 #ifdef CONFIG_Q40 << 1027 is_not_q40(L(notq40)) << 1028 /* << 1029 * add transparent mapping for 0xff00 << 1030 * non-cached serialized etc.. << 1031 * this includes master chip, DAC, RT << 1032 * 0xfe000000-0xfeffffff is for scree << 1033 */ << 1034 << 1035 putc 'Q' << 1036 << 1037 mmu_map_tt #0,#0xfe000000,#0x010 << 1038 mmu_map_tt #1,#0xff000000,#0x010 << 1039 << 1040 jbra L(mmu_init_done) << 1041 << 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, INTI << 1049 * by mapping 32MB (on 020/030) or 16 << 1050 * The ROM mapping is needed because << 1051 */ << 1052 << 1053 is_040(1f) << 1054 << 1055 /* << 1056 * 030: Map the 32Meg range physical << 1057 */ << 1058 mmu_map #0xf0000000,#0,#0x02000000,#_ << 1059 << 1060 jbra L(mmu_init_done) << 1061 << 1062 1: << 1063 /* << 1064 * 040: Map the 16Meg range physical << 1065 */ << 1066 mmu_map #0xf0000000,#0,#0x01000000,#_ << 1067 << 1068 jbra L(mmu_init_done) << 1069 << 1070 L(nothp300): << 1071 #endif /* CONFIG_HP300 */ << 1072 << 1073 #ifdef CONFIG_MVME147 << 1074 << 1075 is_not_mvme147(L(not147)) << 1076 << 1077 /* << 1078 * On MVME147 we have already created << 1079 * 4MB of RAM at address 0, so now ne << 1080 * mapping of the top of memory space << 1081 * so we can access on-board i/o area << 1082 */ << 1083 << 1084 mmu_map_tt #1,#0xe0000000,#0x200 << 1085 << 1086 jbra L(mmu_init_done) << 1087 << 1088 L(not147): << 1089 #endif /* CONFIG_MVME147 */ << 1090 << 1091 #ifdef CONFIG_MVME16x << 1092 << 1093 is_not_mvme16x(L(not16x)) << 1094 << 1095 /* << 1096 * On MVME16x we have already created << 1097 * 4MB of RAM at address 0, so now ne << 1098 * mapping of the top of memory space << 1099 * Supervisor only access, so transpa << 1100 * clash with User code virtual addre << 1101 * this covers IO devices, PROM and S << 1102 * mapping is needed to allow 167Bug << 1103 * IO is in the range 0xfff00000 to 0 << 1104 * PROM is 0xff800000->0xffbfffff and << 1105 * 0xffe00000->0xffe1ffff. << 1106 */ << 1107 << 1108 mmu_map_tt #1,#0xe0000000,#0x200 << 1109 << 1110 jbra L(mmu_init_done) << 1111 << 1112 L(not16x): << 1113 #endif /* CONFIG_MVME162 | CONFIG_MVME167 */ << 1114 << 1115 #ifdef CONFIG_BVME6000 << 1116 << 1117 is_not_bvme6000(L(not6000)) << 1118 << 1119 /* << 1120 * On BVME6000 we have already create << 1121 * 4MB of RAM at address 0, so now ne << 1122 * mapping of the top of memory space << 1123 * so we can access on-board i/o area << 1124 * Supervisor only access, so transpa << 1125 * clash with User code virtual addre << 1126 */ << 1127 << 1128 mmu_map_tt #1,#0xe0000000,#0x200 << 1129 << 1130 jbra L(mmu_init_done) << 1131 << 1132 L(not6000): << 1133 #endif /* CONFIG_BVME6000 */ << 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 << 1141 * Macintosh mappings will be done. However, << 1142 * the first author of this code I'm proposin << 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 pa << 1149 * as absolutely (this requirement mostly ste << 1150 * the fact that when the frame buffer is at << 1151 * 0x0000.0000 then we know there is valid RA << 1152 * above the screen that we don't want to was << 1153 * << 1154 * By the way, if the frame buffer is at 0x00 << 1155 * then the Macintosh is known as an RBV base << 1156 * << 1157 * By the way 2, the code currently maps in a << 1158 * regions. But I'd like to cut that out. ( << 1159 * of the mappings up into the kernel proper << 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: << 1178 /* << 1179 * Mac Note: screen address of logica << 1180 * we simply map the 4MB th << 1181 */ << 1182 << 1183 movel #VIDEOMEMMASK,%d0 << 1184 andl %pc@(L(mac_videobase)),%d0 << 1185 << 1186 mmu_map #VIDEOMEMBASE,%d0,#VI << 1187 /* ROM from 4000 0000 to 4200 0000 (o << 1188 mmu_map_eq #0x40000000,#0x020000 << 1189 /* IO devices (incl. serial port) fro << 1190 mmu_map_eq #0x50000000,#0x030000 << 1191 /* Nubus slot space (video at 0xF0000 << 1192 mmu_map_tt #1,#0xf8000000,#0x080 << 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 t << 1203 * starting the MMU, so we copy the m << 1204 * from 8k -> 4k pages as we go. << 1205 */ << 1206 << 1207 /* copy maps from 0xfee00000 to 0xff0 << 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,% << 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,% << 1224 << 1225 /* this is where the prom page table << 1226 movel 0xfefe00d4, %a1 << 1227 movel %a1@, %a1 << 1228 << 1229 movel #((0x200000 >> 13)-1), %d1 << 1230 << 1231 1: << 1232 movel %a1@+, %d3 << 1233 movel %d3,%a0@+ << 1234 addl #0x1000,%d3 << 1235 movel %d3,%a0@+ << 1236 << 1237 dbra %d1,1b << 1238 << 1239 /* setup tt1 for I/O */ << 1240 mmu_map_tt #1,#0x40000000,#0x400 << 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,#0x010 << 1249 jbra L(mmu_init_done) << 1250 L(novirt): << 1251 #endif << 1252 << 1253 #ifdef CONFIG_APOLLO << 1254 is_not_apollo(L(notapollo)) << 1255 << 1256 putc 'P' << 1257 mmu_map #0x80000000,#0,#0x020 << 1258 << 1259 L(notapollo): << 1260 jbra L(mmu_init_done) << 1261 #endif << 1262 << 1263 L(mmu_init_done): << 1264 << 1265 putc 'G' << 1266 leds 0x8 << 1267 << 1268 /* << 1269 * mmu_fixup << 1270 * << 1271 * On the 040 class machines, all pages that << 1272 * mmu have to be fixed up. According to Moto << 1273 * tables should be non-cacheable on a '040 a << 1274 * '060. But analysis of the reasons for this << 1275 * experience, showed that write-through also << 1276 * << 1277 * Allocated memory so far goes from kernel_e << 1278 * is used for all kind of tables, for that t << 1279 * are now fixed. << 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 << 1290 * contains also kernel_pg_dir. << 1291 */ << 1292 movel %pc@(L(phys_kernel_start)),%d << 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): << 1311 << 1312 #ifdef MMU_PRINT << 1313 mmu_print << 1314 #endif << 1315 << 1316 /* << 1317 * mmu_engage << 1318 * << 1319 * This chunk of code performs the gruesome t << 1320 * The reason it's gruesome is because when t << 1321 * maps logical addresses to physical address << 1322 * register is then passed through the MMU be << 1323 * is fetched (the instruction following the << 1324 * This may mean one of two things: << 1325 * 1. The Program Counter falls within the lo << 1326 * the kernel of which there are two sub-p << 1327 * A. The PC maps to the correct instructi << 1328 * code location), or << 1329 * B. The PC does not map through and the << 1330 * data (or instruction) which is not t << 1331 * As you can imagine, A is good and B is << 1332 * Alternatively, << 1333 * 2. The Program Counter does not map throug << 1334 * will take a Bus Error. << 1335 * Clearly, 2 is bad. << 1336 * It doesn't take a wiz kid to figure you wa << 1337 * This code creates that possibility. << 1338 * There are two possible 1.A. states (we now << 1339 * A. The kernel is located at physical memor << 1340 * the logical memory for the kernel, i.e. << 1341 * B. The kernel is located some where else. << 1342 * << 1343 * Under some conditions the Macintosh can << 1344 * [A friend and I once noted that Apple hard << 1345 * wacked twice each day: once when they show << 1346 * "This is for the screwy hardware we know y << 1347 * and also at the end of the day (as in, Wha << 1348 * you designed today, but I'm sure it wasn't << 1349 * << 1350 * This code works on the following premise: << 1351 * If the kernel start (%d5) is within the fi << 1352 * then create a mapping for the kernel at lo << 1353 * the physical location of the pc. And, cre << 1354 * translation register for the first 16 Meg. << 1355 * is engaged, the PC can be moved up into th << 1356 * and then the transparent translation can b << 1357 * the PC can jump to the correct logical loc << 1358 * home (finally). This is essentially the c << 1359 * to use. Now, it's generalized for all pro << 1360 * that a fresh (but temporary) mapping has t << 1361 * is made in page 0 (an as of yet unused loc << 1362 * stack!). This temporary mapping will only << 1363 * and a single page table (it can map 256K). << 1364 * << 1365 * OK, alternatively, imagine that the Progra << 1366 * the first 16 Meg. Then, just use Transpar << 1367 * to do the right thing. << 1368 * << 1369 * Last, if _start is already at 0x01000, the << 1370 * to do (in other words, in a degenerate cas << 1371 * do nothing). << 1372 * << 1373 * Let's do it. << 1374 * << 1375 * << 1376 */ << 1377 << 1378 putc 'H' << 1379 << 1380 mmu_engage << 1381 << 1382 /* << 1383 * After this point no new memory is allocate << 1384 * the start of available memory is stored in << 1385 * (The bootmem allocator requires now the ph << 1386 */ << 1387 << 1388 movel L(memory_start),availmem << 1389 << 1390 #ifdef CONFIG_AMIGA << 1391 is_not_amiga(1f) << 1392 /* fixup the Amiga custom register lo << 1393 clrl L(custom) << 1394 1: << 1395 #endif << 1396 << 1397 #ifdef CONFIG_ATARI << 1398 is_not_atari(1f) << 1399 /* fixup the Atari iobase register lo << 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)),%d << 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) << 1422 /* << 1423 * Fix up the iobase register to poin << 1424 */ << 1425 movel #0xf0000000,L(iobase) << 1426 << 1427 /* << 1428 * Energise the FPU and caches. << 1429 */ << 1430 is_040(1f) << 1431 movel #0x60,0xf05f400c << 1432 jbra 2f << 1433 << 1434 /* << 1435 * 040: slightly different, apparentl << 1436 */ << 1437 1: movew #0,0xf05f400e << 1438 movew #0x64,0xf05f400e << 1439 2: << 1440 #endif << 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) << 1452 << 1453 /* << 1454 * Fix up the iobase before printing << 1455 */ << 1456 movel #0x80000000,L(iobase) << 1457 1: << 1458 #endif << 1459 << 1460 putc 'I' << 1461 leds 0x10 << 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,%d << 1478 /* MMU stuff works in copyback mode n << 1479 movec %d0,%cacr << 1480 jra L(cache_done) << 1481 << 1482 L(cache68060): << 1483 movel #CC6_ENABLE_D+CC6_ENABLE_I+CC << 1484 /* MMU stuff works in copyback mode n << 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_ << 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 << 1509 << 1510 putc 'K' << 1511 << 1512 subl %a6,%a6 /* clear a6 f << 1513 << 1514 /* << 1515 * The new 64bit printf support requires an e << 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 structur << 1528 * The bootinfo structure is located right af << 1529 * Returns: d0: size (-1 if not found) << 1530 * a0: data pointer (end-of-records << 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 th << 1556 * is thus: << 1557 * Root Table << 1558 * Logical addresses are transla << 1559 * a hierarchical translation mechanism << 1560 * seven bits of the logical address (LA << 1561 * index into the "root table." Each en << 1562 * table has a bit which specifies if it << 1563 * pointer table. Each entry defines a << 1564 * If an entry is invalid then that logi << 1565 * invalid and references to that range << 1566 * is enabled) will fault. If the entry << 1567 * one of two things. On 040/060 class << 1568 * a pointer table which then describes << 1569 * within that 32M range. On 020/030 cl << 1570 * called "early terminating descriptors << 1571 * allows an entire 32Meg to be describe << 1572 * root table. Thus, this entry in the << 1573 * physical address of the memory or I/O << 1574 * which the entry represents and it als << 1575 * cache bits for this region. << 1576 * << 1577 * Pointer Tables << 1578 * Per the Root Table, there wil << 1579 * pointer tables. Each pointer table d << 1580 * Not all of the 32M range need be defi << 1581 * seven bits of the logical address are << 1582 * the pointer table to point to page ta << 1583 * is valid). There will undoubtedly be << 1584 * pointer table for the kernel because << 1585 * defines a range of only 32M. Valid p << 1586 * point to page tables, or are early te << 1587 * themselves. << 1588 * << 1589 * Page Tables << 1590 * Per the Pointer Tables, each << 1591 * to the physical page in memory that s << 1592 * address that translates to the partic << 1593 * << 1594 * In short, the Logical Address gets tr << 1595 * bits 31..26 - index into the << 1596 * bits 25..18 - index into the << 1597 * bits 17..12 - index into the << 1598 * bits 11..0 - offset into a p << 1599 * << 1600 * The algorithms which follow do one th << 1601 * the MMU hardware. For example, there << 1602 * cache settings that are relevant. Ei << 1603 * being mapped in which case it is eith << 1604 * the RamDisk) or it is MMU data. On t << 1605 * option also describes the kernel. Or << 1606 * in which case it has its own kind of << 1607 * are constants which abstract these no << 1608 * actually makes the call to map some r << 1609 * << 1610 * << 1611 * << 1612 */ << 1613 24 1614 #ifdef MMU_PRINT << 1615 /* 25 /* 1616 * mmu_print !! 26 * References to members of the boot_cpu_data structure. 1617 * << 1618 * This algorithm will print out the cur << 1619 * << 1620 * Input: << 1621 * %a5 points to the root table. << 1622 * from this. << 1623 */ 27 */ 1624 28 1625 #define mmu_next_valid 0 !! 29 #define CPU_PARAMS SYMBOL_NAME(boot_cpu_data) 1626 #define mmu_start_logical 4 !! 30 #define X86 CPU_PARAMS+0 1627 #define mmu_next_logical 8 !! 31 #define X86_VENDOR CPU_PARAMS+1 1628 #define mmu_start_physical 12 !! 32 #define X86_MODEL CPU_PARAMS+2 1629 #define mmu_next_physical 16 !! 33 #define X86_MASK CPU_PARAMS+3 1630 !! 34 #define X86_HARD_MATH CPU_PARAMS+6 1631 #define MMU_PRINT_INVALID -1 !! 35 #define X86_CPUID CPU_PARAMS+8 1632 #define MMU_PRINT_VALID 1 !! 36 #define X86_CAPABILITY CPU_PARAMS+12 1633 #define MMU_PRINT_UNINITED 0 !! 37 #define X86_VENDOR_ID CPU_PARAMS+36 /* tied to NCAPINTS in cpufeature.h */ 1634 << 1635 #define putZc(z,n) jbne 1f; putc << 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_ << 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 << 1651 /* << 1652 * The following #if/#endif block is << 1653 * MMU Map in gory detail. It really << 1654 * MMU Map algorithm appears to go aw << 1655 * entry per entry level. << 1656 */ << 1657 movel #ROOT_TABLE_SIZE,%d5 << 1658 #if 0 << 1659 movel %a5@+,%d7 | Bur << 1660 subql #1,%d5 | the << 1661 #endif << 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 an << 1714 << 1715 lea %pc@(kernel_pg_dir),%a5 << 1716 movel %a5,%a0 /* a0 << 1717 movel #0x00000000,%a4 /* lo << 1718 moveql #0,%d0 << 1719 40: << 1720 /* Increment the logical address and << 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 /* mo << 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 << 1780 jbeq 1f /* No << 1781 << 1782 movel %d0,%d1 << 1783 andil #0xff000000,%d1 /* Ge << 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 << 1794 jbeq 1f /* No << 1795 << 1796 movel %d0,%d1 << 1797 andil #0xff000000,%d1 /* Ge << 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 c << 1820 jbra 4f << 1821 3: << 1822 putc 'N' << 1823 btstl #5,%d6 << 1824 putZc('s',' ') /* serialized non-cac << 1825 4: << 1826 rts << 1827 << 1828 mmu_030_print_flags: << 1829 btstl #6,%d6 << 1830 putZc('C','I') /* write through or c << 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 /* lo << 1842 movel #0,%d0 << 1843 30: << 1844 movel %a4,%d5 << 1845 addil #PAGESIZE<<13,%d5 << 1846 movel %a0@+,%d6 << 1847 btst #1,%d6 /* is << 1848 jbne 31f /* ye << 1849 btst #0,%d6 /* is << 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 << 1865 jbne 33f /* ye << 1866 btst #0,%d6 /* is << 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 /* mo << 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_ex << 1924 << 1925 movel #MMU_PRINT_INVALID,%a0@(mmu_n << 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_nex << 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 38 2001 /* 39 /* 2002 * mmu_map_tt !! 40 * swapper_pg_dir is the main page directory, address 0x00101000 2003 * << 2004 * This is a specific function which works on << 2005 * On 030, 040 & 060 it will attempt to use T << 2006 * registers (tt1). << 2007 * On 020 it will call the standard mmu_map w << 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 << 2022 */ << 2023 bfffo ARG3{#0,#32},%d1 << 2024 cmpw #8,%d1 << 2025 jcc L(do_map) << 2026 << 2027 /* And get the mask << 2028 */ << 2029 moveq #-1,%d0 << 2030 lsrl %d1,%d0 << 2031 lsrl #1,%d0 << 2032 << 2033 /* Mask the address << 2034 */ << 2035 movel %d0,%d1 << 2036 notl %d1 << 2037 andl ARG2,%d1 << 2038 << 2039 /* Generate the upper 16bit of the tt << 2040 */ << 2041 lsrl #8,%d0 << 2042 orl %d0,%d1 << 2043 clrw %d1 << 2044 << 2045 is_040_or_060(L(mmu_map_tt_040)) << 2046 << 2047 /* set 030 specific bits (read/write << 2048 * (highest function code set, lower << 2049 */ << 2050 orw #TTR_ENABLE+TTR_RWM+TTR_FCB2+ << 2051 movel ARG4,%d0 << 2052 btst #6,%d0 << 2053 jeq 1f << 2054 orw #TTR_CI,%d1 << 2055 << 2056 1: lea STACK,%a0 << 2057 dputn %d1 << 2058 movel %d1,%a0@ << 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 << 2069 */ << 2070 L(mmu_map_tt_040): << 2071 orw #TTR_ENABLE+TTR_KERNELMODE,%d << 2072 orl ARG4,%d1 << 2073 dputn %d1 << 2074 << 2075 .chip 68040 << 2076 tstl ARG1 << 2077 jne 1f << 2078 movec %d1,%itt0 << 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 memo << 2098 * table and allocate the pages on the f << 2099 * The pointer table does not have to be << 2100 * the root table, this routine will do << 2101 * << 2102 * NOTE << 2103 * This routine will assert failure and << 2104 * routines in the case of a run-time er << 2105 * if the address is already mapped. << 2106 * << 2107 * NOTE-2 << 2108 * This routine will use early terminati << 2109 * where possible for the 68020+68851 an << 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 d << 2122 */ << 2123 movel ARG1,%d0 << 2124 andl #-(PAGESIZE*PAGE_TABLE_SIZE), << 2125 movel %d0,%a3 << 2126 << 2127 /* Get the end address << 2128 */ << 2129 movel ARG1,%a4 << 2130 addl ARG3,%a4 << 2131 subql #1,%a4 << 2132 << 2133 /* Get physical address and round it << 2134 */ << 2135 movel ARG2,%d0 << 2136 andl #-(PAGESIZE*PAGE_TABLE_SIZE), << 2137 movel %d0,%a2 << 2138 << 2139 /* Add page attributes to the physica << 2140 */ << 2141 movel ARG4,%d0 << 2142 orw #_PAGE_PRESENT+_PAGE_ACCESSED << 2143 addw %d0,%a2 << 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 << 2152 /* << 2153 * MMU 040 & 060 Support << 2154 * << 2155 * The MMU usage for the 040 and 060 is << 2156 * the 030 and 68851 that there is separ << 2157 * block describes the data structures a << 2158 * this code. << 2159 * << 2160 * The 040 does not support early termin << 2161 * the 030 does. Therefore, a third lev << 2162 * for the 040, and that would be the pa << 2163 * page tables are allocated directly fr << 2164 * kernel. << 2165 * 41 * >> 42 * On entry, %esi points to the real-mode code as a 32-bit pointer. 2166 */ 43 */ 2167 !! 44 startup_32: 2168 L(mmu_map_040): << 2169 /* Calculate the offset into the root << 2170 */ << 2171 movel %a3,%d0 << 2172 moveq #ROOT_INDEX_SHIFT,%d1 << 2173 lsrl %d1,%d0 << 2174 mmu_get_root_table_entry %d0 << 2175 << 2176 /* Calculate the offset into the poin << 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,% << 2183 << 2184 /* Calculate the offset into the page << 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,% << 2191 << 2192 /* The page table entry must not no b << 2193 */ << 2194 tstl %a0@ << 2195 jne L(mmu_map_error) << 2196 << 2197 /* Do the mapping and advance the poi << 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 << 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 alig << 2220 * so we can try to map it once << 2221 */ << 2222 movel %a3,%d0 << 2223 andl #(PTR_TABLE_SIZE*PAGE_TABLE_S << 2224 jne 1f << 2225 << 2226 /* Is there enough to map for 32MB at << 2227 */ << 2228 lea %a3@(PTR_TABLE_SIZE*PAGE_TABL << 2229 cmpl %a1,%a4 << 2230 jcs 1f << 2231 << 2232 addql #1,%a1 << 2233 << 2234 /* The root table entry must not no b << 2235 */ << 2236 tstl %a0@ << 2237 jne L(mmu_map_error) << 2238 << 2239 /* Do the mapping and advance the poi << 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_TABL << 2250 jra L(mmu_mapnext_030) << 2251 1: << 2252 /* Calculate the offset into the poin << 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,% << 2259 << 2260 /* The pointer table entry must not n << 2261 */ << 2262 tstl %a0@ << 2263 jne L(mmu_map_error) << 2264 << 2265 /* Do the mapping and advance the poi << 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): << 2285 << 2286 dputs "mmu_map error:" << 2287 dputn %a2 << 2288 dputn %a3 << 2289 dputc '\n' << 2290 << 2291 L(mmu_map_done): << 2292 << 2293 func_return mmu_map << 2294 << 2295 /* 45 /* 2296 * mmu_fixup !! 46 * Set segments to known values 2297 * << 2298 * On the 040 class machines, all pages << 2299 * mmu have to be fixed up. << 2300 */ 47 */ 2301 !! 48 cld 2302 func_start mmu_fixup_page_mmu_cache,%d0/ !! 49 movl $(__KERNEL_DS),%eax 2303 !! 50 movl %eax,%ds 2304 dputs "mmu_fixup_page_mmu_cache" !! 51 movl %eax,%es 2305 dputn ARG1 !! 52 movl %eax,%fs 2306 !! 53 movl %eax,%gs 2307 /* Calculate the offset into the root !! 54 #ifdef CONFIG_SMP 2308 */ !! 55 orw %bx,%bx 2309 movel ARG1,%d0 !! 56 jz 1f 2310 moveq #ROOT_INDEX_SHIFT,%d1 << 2311 lsrl %d1,%d0 << 2312 mmu_get_root_table_entry %d0 << 2313 << 2314 /* Calculate the offset into the poin << 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,% << 2321 << 2322 /* Calculate the offset into the page << 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,% << 2329 << 2330 movel %a0@,%d0 << 2331 andil #_CACHEMASK040,%d0 << 2332 orl %pc@(m68k_pgtable_cachemode), << 2333 movel %d0,%a0@ << 2334 << 2335 dputc '\n' << 2336 << 2337 func_return mmu_fixup_page_mmu_cache << 2338 57 2339 /* 58 /* 2340 * mmu_temp_map !! 59 * New page tables may be in 4Mbyte page mode and may >> 60 * be using the global pages. 2341 * 61 * 2342 * create a temporary mapping to enable !! 62 * NOTE! If we are on a 486 we may have no cr4 at all! 2343 * this we don't need any transparation !! 63 * So we do not try to touch it unless we really have 2344 */ !! 64 * some bits in it to set. This won't work if the BSP 2345 !! 65 * implements cr4 but this AP does not -- very unlikely 2346 func_start mmu_temp_map,%d0/%d1/%a0/%a1 !! 66 * but be warned! The same applies to the pse feature 2347 !! 67 * if not equally supported. --macro 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 t << 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 al << 2363 */ << 2364 movel %a0@,%d0 << 2365 cmpl %pc@(L(memory_start)),%d0 << 2366 jcc 1f << 2367 << 2368 /* Temporary allocate a ptr table and << 2369 */ << 2370 movel %a1@,%d0 << 2371 addl #PTR_TABLE_SIZE*4,%a1@ << 2372 orw #_PAGE_TABLE+_PAGE_ACCESSED,% << 2373 movel %d0,%a0@ << 2374 dputs " (new)" << 2375 1: << 2376 dputn %d0 << 2377 /* Mask the root table entry for the << 2378 */ << 2379 andw #-ROOT_TABLE_SIZE,%d0 << 2380 movel %d0,%a0 << 2381 << 2382 /* Calculate the offset into the poin << 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 << 2392 */ << 2393 movel %a0@,%d0 << 2394 jne 1f << 2395 << 2396 /* Temporary allocate a page table an << 2397 */ << 2398 movel %a1@,%d0 << 2399 /* The 512 should be PAGE_TABLE_SIZE* << 2400 alignment restriction for pointer << 2401 addl #512,%a1@ << 2402 orw #_PAGE_TABLE+_PAGE_ACCESSED,% << 2403 movel %d0,%a0@ << 2404 dputs " (new)" << 2405 1: << 2406 dputn %d0 << 2407 /* Mask the ptr table entry for the p << 2408 */ << 2409 andw #-PTR_TABLE_SIZE,%d0 << 2410 movel %d0,%a0 << 2411 << 2412 /* Calculate the offset into the page << 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 t << 2422 */ << 2423 movel ARG1,%d0 << 2424 andw #-PAGESIZE,%d0 << 2425 orw #_PAGE_PRESENT+_PAGE_ACCESSED << 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 t << 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)),%d << 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 << 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)), << 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 << 2506 * 7 bit pointer index, 6 bit page ta << 2507 */ << 2508 movel #0x82c07760,%a0@(8) << 2509 pmove %a0@(8),%tc /* enable the << 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/ << 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 << 2543 * as the bootinfo structure is locat << 2544 * we simply search for the last entr << 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 a << 2559 * in mm/init.c simply expects kernel << 2560 * page is used for further ptr table << 2561 */ << 2562 lea %pc@(_stext),%a0 << 2563 lea %pc@(L(mmu_cached_pointer_tab << 2564 movel %a0,%a1@ << 2565 addl #ROOT_TABLE_SIZE*4,%a1@ << 2566 << 2567 lea %pc@(L(mmu_num_pointer_tables << 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/% << 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 pointe << 2610 */ << 2611 dputs "\nmmu_get_new_ptr_table:" << 2612 lea %pc@(L(mmu_num_pointer_tables << 2613 movel %a0@,%d0 << 2614 addql #1,%a0@ << 2615 << 2616 /* See if there is a free pointer tab << 2617 */ << 2618 lea %pc@(L(mmu_cached_pointer_tab << 2619 andw #7,%d0 << 2620 jne 1f << 2621 << 2622 /* Get a new pointer table page from << 2623 */ << 2624 get_new_page << 2625 movel %a0,%a1@ << 2626 1: << 2627 /* There is an unused pointer table i << 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 << 2636 */ << 2637 movel ARG1,%a0 << 2638 orw #_PAGE_TABLE+_PAGE_ACCESSED,% << 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/ << 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 << 2668 << 2669 /* If the page table entry doesn't ex << 2670 * page and use it as one continuous << 2671 * 4MB of memory, nearly almost all m << 2672 */ << 2673 get_new_page << 2674 addw #_PAGE_TABLE+_PAGE_ACCESSED,% << 2675 << 2676 /* align pointer table entry for a pa << 2677 */ << 2678 movel ARG1,%d0 << 2679 andw #-(PAGESIZE/PAGE_TABLE_SIZE), << 2680 movel %d0,%a1 << 2681 << 2682 /* Insert the page tables into the po << 2683 */ << 2684 moveq #PAGESIZE/PAGE_TABLE_SIZE/4-1 << 2685 1: << 2686 movel %a0,%a1@+ << 2687 lea %a0@(PAGE_TABLE_SIZE*4),%a0 << 2688 dbra %d0,1b << 2689 << 2690 /* Now we can get the initialized poi << 2691 */ << 2692 movel ARG1,%a0 << 2693 movel %a0@,%d0 << 2694 2: << 2695 /* Extract the page table entry << 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' << 2705 #endif << 2706 << 2707 func_return mmu_get_page_table_entry << 2708 << 2709 /* << 2710 * get_new_page << 2711 * 68 * 2712 * Return a new page from the memory sta !! 69 * NOTE! We have to correct for the fact that we're >> 70 * not yet offset PAGE_OFFSET.. 2713 */ 71 */ 2714 func_start get_new_page,%d0/%a1 !! 72 #define cr4_bits mmu_cr4_features-__PAGE_OFFSET 2715 !! 73 cmpl $0,cr4_bits 2716 dputs "\nget_new_page:" !! 74 je 3f 2717 !! 75 movl %cr4,%eax # Turn on paging options (PSE,PAE,..) 2718 /* allocate the page and adjust memor !! 76 orl cr4_bits,%eax 2719 */ !! 77 movl %eax,%cr4 2720 lea %pc@(L(memory_start)),%a0 !! 78 jmp 3f 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: 79 1: 2729 clrl %a1@+ << 2730 dbra %d0,1b << 2731 << 2732 dputn %a0 << 2733 dputc '\n' << 2734 << 2735 func_return get_new_page << 2736 << 2737 << 2738 << 2739 /* << 2740 * Debug output support << 2741 * Atarians have a choice between the paralle << 2742 * from the MFP or a serial port of the SCC << 2743 */ << 2744 << 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 << 2751 /* Initialisation table for SCC with 3.6864 M << 2752 L(scc_initable_mac): << 2753 .byte 4,0x44 /* x16, 1 sto << 2754 .byte 3,0xc0 /* receiver: << 2755 .byte 5,0xe2 /* transmitte << 2756 .byte 10,0 /* NRZ */ << 2757 .byte 11,0x50 /* use baud r << 2758 .byte 12,1,13,0 /* 38400 baud << 2759 .byte 14,1 /* Baud rate << 2760 .byte 3,0xc1 /* enable rec << 2761 .byte 5,0xea /* enable tra << 2762 .byte -1 << 2763 .even << 2764 #endif << 2765 #endif /* CONFIG_MAC */ << 2766 << 2767 #ifdef CONFIG_ATARI << 2768 /* #define USE_PRINTER */ << 2769 /* #define USE_SCC_B */ << 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 M << 2775 /* PCLK == 8.0539 gives baud == 9680.1 */ << 2776 L(scc_initable_atari): << 2777 .byte 4,0x44 /* x16, 1 sto << 2778 .byte 3,0xc0 /* receiver: << 2779 .byte 5,0xe2 /* transmitte << 2780 .byte 10,0 /* NRZ */ << 2781 .byte 11,0x50 /* use baud r << 2782 .byte 12,24,13,0 /* 9600 baud << 2783 .byte 14,2,14,3 /* use master << 2784 .byte 3,0xc1 /* enable rec << 2785 .byte 5,0xea /* enable tra << 2786 .byte -1 << 2787 .even << 2788 #endif 80 #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 */ << 2822 << 2823 /* 81 /* 2824 * Serial port output support. !! 82 * Initialize page tables 2825 */ 83 */ >> 84 movl $pg0-__PAGE_OFFSET,%edi /* initialize page tables */ >> 85 movl $007,%eax /* "007" doesn't mean with right to kill, but >> 86 PRESENT+RW+USER */ >> 87 2: stosl >> 88 add $0x1000,%eax >> 89 cmp $empty_zero_page-__PAGE_OFFSET,%edi >> 90 jne 2b 2826 91 2827 /* 92 /* 2828 * Initialize serial port hardware !! 93 * Enable paging 2829 */ 94 */ 2830 func_start serial_init,%d0/%d1/%a0/%a1 << 2831 /* << 2832 * Some of the register usage th << 2833 * CONFIG_AMIGA << 2834 * a0 = pointer to boot << 2835 * d0 = boot info offset << 2836 * CONFIG_ATARI << 2837 * a0 = address of SCC << 2838 * a1 = Liobase address/ << 2839 * d0 = init data for se << 2840 * CONFIG_MAC << 2841 * a0 = address of SCC << 2842 * a1 = address of scc_i << 2843 * d0 = init data for se << 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-ZTWO << 2854 get_bi_record BI_AMIGA_SERPER << 2855 movew %a0@,CUSTOMBASE+C_SERPER-ZTWO << 2856 | movew #61,CUSTOMBASE+C_SERPER-ZTWOB << 2857 1: << 2858 #endif << 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_SELEC << 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 p << 2879 moveb #9,%a0@ << 2880 moveb #0xc0,%a0@ << 2881 /* Wait for 5 PCLK cycles, which is a << 2882 /* 5 / 7.9872 MHz = approx. 0.63 us = << 2883 movel #32,%d0 << 2884 2: << 2885 subq #1,%d0 << 2886 jne 2b << 2887 /* Initialize channel */ << 2888 lea %pc@(L(scc_initable_atari)),% << 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 << 2906 << 2907 #ifdef CONFIG_MAC << 2908 is_not_mac(L(serial_init_not_mac)) << 2909 #if defined(MAC_USE_SCC_A) || defined(MAC_USE << 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_offse << 2917 /* Reset SCC device: write register p << 2918 moveb #9,%a0@(mac_scc_cha_a_ctrl_of << 2919 moveb #0xc0,%a0@(mac_scc_cha_a_ctrl << 2920 /* Wait for 5 PCLK cycles, which is a << 2921 /* 5 / 3.6864 MHz = approx. 1.36 us = << 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_o << 2933 moveb %a1@+,%a0@(mac_scc_cha_a_ctrl << 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_o << 2943 moveb %a1@+,%a0@(mac_scc_cha_b_ctrl << 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 d << 2954 - check for '%LX$' signature in SRAM */ << 2955 lea %pc@(q40_mem_cptr),%a1 << 2956 move.l #0xff020010,%a1@ /* must be << 2957 move.l #0xff020000,%a1 << 2958 cmp.b #'%',%a1@ << 2959 bne 2f /*nodbg*/ << 2960 addq.w #4,%a1 << 2961 cmp.b #'L',%a1@ << 2962 bne 2f /*nodbg*/ << 2963 addq.w #4,%a1 << 2964 cmp.b #'X',%a1@ << 2965 bne 2f /*nodbg*/ << 2966 addq.w #4,%a1 << 2967 cmp.b #'$',%a1@ << 2968 bne 2f /*nodbg*/ << 2969 /* signature OK */ << 2970 lea %pc@(L(q40_do_debug)),%a1 << 2971 tas %a1@ << 2972 /*nodbg: q40_do_debug is 0 by default*/ << 2973 2: << 2974 #endif << 2975 << 2976 #ifdef CONFIG_MVME16x << 2977 is_not_mvme16x(L(serial_init_not_mvme << 2978 moveb #0x10,M167_PCSCCMICR << 2979 moveb #0x10,M167_PCSCCTICR << 2980 moveb #0x10,M167_PCSCCRICR << 2981 jra L(serial_init_done) << 2982 L(serial_init_not_mvme16x): << 2983 #endif << 2984 << 2985 #ifdef CONFIG_APOLLO << 2986 /* We count on the PROM initializing SIO1 */ << 2987 #endif << 2988 << 2989 #ifdef CONFIG_HP300 << 2990 /* We count on the boot loader initialising t << 2991 #endif << 2992 << 2993 L(serial_init_done): << 2994 func_return serial_init << 2995 << 2996 /* << 2997 * Output character on serial port. << 2998 */ << 2999 func_start serial_putc,%d0/%d1/%a0/%a1 << 3000 << 3001 movel ARG1,%d0 << 3002 cmpib #'\n',%d0 << 3003 jbne 1f << 3004 << 3005 /* A little safe recursion is good fo << 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),%d << 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 << 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_of << 3029 jeq 3b << 3030 moveb %d0,%a1@(mac_scc_cha_a_data_o << 3031 #endif /* MAC_USE_SCC_A */ << 3032 #ifdef MAC_USE_SCC_B << 3033 4: btst #2,%a1@(mac_scc_cha_b_ctrl_of << 3034 jeq 4b << 3035 moveb %d0,%a1@(mac_scc_cha_b_data_o << 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 << 3083 * select an appropriate output routi << 3084 * the Bug code. If we have to use t << 3085 * workspace has to be valid, which m << 3086 * the SRAM, which is non-standard. << 3087 */ << 3088 moveml %d0-%d7/%a2-%a6,%sp@- << 3089 movel vme_brdtype,%d1 << 3090 jeq 1f | No << 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: 95 3: 3130 moveml %sp@+,%d0-%d7/%a2-%a6 !! 96 movl $swapper_pg_dir-__PAGE_OFFSET,%eax 3131 jbra L(serial_putc_done) !! 97 movl %eax,%cr3 /* set the page table pointer.. */ 3132 2: !! 98 movl %cr0,%eax 3133 #endif /* CONFIG_MVME16x */ !! 99 orl $0x80000000,%eax 3134 !! 100 movl %eax,%cr0 /* ..and set paging (PG) bit */ 3135 #ifdef CONFIG_BVME6000 !! 101 jmp 1f /* flush the prefetch-queue */ 3136 is_not_bvme6000(2f) !! 102 1: 3137 /* !! 103 movl $1f,%eax 3138 * The BVME6000 machine has a serial !! 104 jmp *%eax /* make sure eip is relocated */ 3139 */ !! 105 1: 3140 1: btst #2,BVME_SCC_CTRL_A !! 106 /* Set up the stack pointer */ 3141 jeq 1b !! 107 lss stack_start,%esp 3142 moveb %d0,BVME_SCC_DATA_A !! 108 3143 jbra L(serial_putc_done) !! 109 #ifdef CONFIG_SMP 3144 2: !! 110 orw %bx,%bx 3145 #endif !! 111 jz 1f /* Initial CPU cleans BSS */ 3146 !! 112 pushl $0 3147 #ifdef CONFIG_SUN3X !! 113 popfl 3148 is_not_sun3x(2f) !! 114 jmp checkCPUtype 3149 movel %d0,-(%sp) !! 115 1: 3150 movel 0xFEFE0018,%a1 !! 116 #endif /* CONFIG_SMP */ 3151 jbsr (%a1) !! 117 3152 addq #4,%sp !! 118 /* 3153 jbra L(serial_putc_done) !! 119 * Clear BSS first so that there are no surprises... 3154 2: !! 120 * No need to cld as DF is already clear from cld above... 3155 #endif !! 121 */ 3156 !! 122 xorl %eax,%eax 3157 #ifdef CONFIG_Q40 !! 123 movl $ SYMBOL_NAME(__bss_start),%edi 3158 is_not_q40(2f) !! 124 movl $ SYMBOL_NAME(_end),%ecx 3159 tst.l %pc@(L(q40_do_debug)) /* on !! 125 subl %edi,%ecx 3160 beq 2f !! 126 rep 3161 lea %pc@(q40_mem_cptr),%a1 !! 127 stosb 3162 move.l %a1@,%a0 !! 128 3163 move.b %d0,%a0@ !! 129 /* 3164 addq.l #4,%a0 !! 130 * start system 32-bit setup. We need to re-do some of the things done 3165 move.l %a0,%a1@ !! 131 * in 16-bit mode for the "real" operations. 3166 jbra L(serial_putc_done) !! 132 */ 3167 2: !! 133 call setup_idt 3168 #endif !! 134 /* 3169 !! 135 * Initialize eflags. Some BIOS's leave bits like NT set. This would 3170 #ifdef CONFIG_APOLLO !! 136 * confuse the debugger if this code is traced. 3171 is_not_apollo(2f) !! 137 * XXX - best to initialize before switching to protected mode. 3172 movl %pc@(L(iobase)),%a1 !! 138 */ 3173 moveb %d0,%a1@(LTHRB0) !! 139 pushl $0 3174 1: moveb %a1@(LSRB0),%d0 !! 140 popfl 3175 andb #0x4,%d0 !! 141 /* 3176 beq 1b !! 142 * Copy bootup parameters out of the way. First 2kB of 3177 jbra L(serial_putc_done) !! 143 * _empty_zero_page is for boot parameters, second 2kB 3178 2: !! 144 * is for the command line. 3179 #endif !! 145 * 3180 !! 146 * Note: %esi still has the pointer to the real-mode data. 3181 #ifdef CONFIG_HP300 !! 147 */ 3182 is_not_hp300(3f) !! 148 movl $ SYMBOL_NAME(empty_zero_page),%edi 3183 movl %pc@(L(iobase)),%a1 !! 149 movl $512,%ecx 3184 addl %pc@(L(uartbase)),%a1 !! 150 cld 3185 movel %pc@(L(uart_scode)),%d1 /* Ch !! 151 rep 3186 jmi 3f /* Un !! 152 movsl 3187 cmpi #256,%d1 /* AP !! 153 xorl %eax,%eax 3188 jeq 2f !! 154 movl $512,%ecx 3189 1: moveb %a1@(DCALSR),%d1 /* Ou !! 155 rep 3190 andb #0x20,%d1 !! 156 stosl 3191 beq 1b !! 157 movl SYMBOL_NAME(empty_zero_page)+NEW_CL_POINTER,%esi 3192 moveb %d0,%a1@(DCADATA) !! 158 andl %esi,%esi 3193 jbra L(serial_putc_done) !! 159 jnz 2f # New command line protocol 3194 2: moveb %a1@(APCILSR),%d1 /* Ou !! 160 cmpw $(OLD_CL_MAGIC),OLD_CL_MAGIC_ADDR 3195 andb #0x20,%d1 !! 161 jne 1f 3196 beq 2b !! 162 movzwl OLD_CL_OFFSET,%esi 3197 moveb %d0,%a1@(APCIDATA) !! 163 addl $(OLD_CL_BASE_ADDR),%esi 3198 jbra L(serial_putc_done) !! 164 2: 3199 3: !! 165 movl $ SYMBOL_NAME(empty_zero_page)+2048,%edi 3200 #endif !! 166 movl $512,%ecx 3201 !! 167 rep 3202 #ifdef CONFIG_VIRT !! 168 movsl 3203 is_not_virt(1f) !! 169 1: 3204 !! 170 checkCPUtype: 3205 movel L(virt_gf_tty_base),%a1 !! 171 3206 movel %d0,%a1@(GF_PUT_CHAR) !! 172 movl $-1,X86_CPUID # -1 for no CPUID initially 3207 1: !! 173 3208 #endif !! 174 /* check if it is 486 or 386. */ 3209 !! 175 /* 3210 L(serial_putc_done): !! 176 * XXX - this does a lot of unnecessary setup. Alignment checks don't 3211 func_return serial_putc !! 177 * apply at our cpl of 0 and the stack ought to be aligned already, and 3212 !! 178 * we don't need to preserve eflags. 3213 /* !! 179 */ 3214 * Output a string. !! 180 3215 */ !! 181 movb $3,X86 # at least 386 3216 func_start puts,%d0/%a0 !! 182 pushfl # push EFLAGS 3217 !! 183 popl %eax # get EFLAGS 3218 movel ARG1,%a0 !! 184 movl %eax,%ecx # save original EFLAGS 3219 jra 2f !! 185 xorl $0x40000,%eax # flip AC bit in EFLAGS 3220 1: !! 186 pushl %eax # copy to EFLAGS 3221 #ifdef CONSOLE_DEBUG !! 187 popfl # set EFLAGS 3222 console_putc %d0 !! 188 pushfl # get new EFLAGS 3223 #endif !! 189 popl %eax # put it in eax 3224 #ifdef SERIAL_DEBUG !! 190 xorl %ecx,%eax # change in flags 3225 serial_putc %d0 !! 191 andl $0x40000,%eax # check if AC bit changed 3226 #endif !! 192 je is386 3227 2: moveb %a0@+,%d0 !! 193 3228 jne 1b !! 194 movb $4,X86 # at least 486 3229 !! 195 movl %ecx,%eax 3230 func_return puts !! 196 xorl $0x200000,%eax # check ID flag 3231 !! 197 pushl %eax 3232 /* !! 198 popfl # if we are on a straight 486DX, SX, or 3233 * Output number in hex notation. !! 199 pushfl # 487SX we can't change it 3234 */ !! 200 popl %eax 3235 !! 201 xorl %ecx,%eax 3236 func_start putn,%d0-%d2 !! 202 pushl %ecx # restore original EFLAGS 3237 !! 203 popfl 3238 putc ' ' !! 204 andl $0x200000,%eax 3239 !! 205 je is486 3240 movel ARG1,%d0 !! 206 3241 moveq #7,%d1 !! 207 /* get vendor info */ 3242 1: roll #4,%d0 !! 208 xorl %eax,%eax # call CPUID with 0 -> return vendor ID 3243 move %d0,%d2 !! 209 cpuid 3244 andb #0x0f,%d2 !! 210 movl %eax,X86_CPUID # save CPUID level 3245 addb #'0',%d2 !! 211 movl %ebx,X86_VENDOR_ID # lo 4 chars 3246 cmpb #'9',%d2 !! 212 movl %edx,X86_VENDOR_ID+4 # next 4 chars 3247 jls 2f !! 213 movl %ecx,X86_VENDOR_ID+8 # last 4 chars 3248 addb #'A'-('9'+1),%d2 !! 214 3249 2: !! 215 orl %eax,%eax # do we have processor info as well? 3250 #ifdef CONSOLE_DEBUG !! 216 je is486 3251 console_putc %d2 !! 217 3252 #endif !! 218 movl $1,%eax # Use the CPUID instruction to get CPU type 3253 #ifdef SERIAL_DEBUG !! 219 cpuid 3254 serial_putc %d2 !! 220 movb %al,%cl # save reg for future use >> 221 andb $0x0f,%ah # mask processor family >> 222 movb %ah,X86 >> 223 andb $0xf0,%al # mask model >> 224 shrb $4,%al >> 225 movb %al,X86_MODEL >> 226 andb $0x0f,%cl # mask mask revision >> 227 movb %cl,X86_MASK >> 228 movl %edx,X86_CAPABILITY >> 229 >> 230 is486: >> 231 movl %cr0,%eax # 486 or better >> 232 andl $0x80000011,%eax # Save PG,PE,ET >> 233 orl $0x50022,%eax # set AM, WP, NE and MP >> 234 jmp 2f >> 235 >> 236 is386: pushl %ecx # restore original EFLAGS >> 237 popfl >> 238 movl %cr0,%eax # 386 >> 239 andl $0x80000011,%eax # Save PG,PE,ET >> 240 orl $2,%eax # set MP >> 241 2: movl %eax,%cr0 >> 242 call check_x87 >> 243 incb ready >> 244 lgdt gdt_descr >> 245 lidt idt_descr >> 246 ljmp $(__KERNEL_CS),$1f >> 247 1: movl $(__KERNEL_DS),%eax # reload all the segment registers >> 248 movl %eax,%ds # after changing gdt. >> 249 movl %eax,%es >> 250 movl %eax,%fs >> 251 movl %eax,%gs >> 252 #ifdef CONFIG_SMP >> 253 movl $(__KERNEL_DS), %eax >> 254 movl %eax,%ss # Reload the stack pointer (segment only) >> 255 #else >> 256 lss stack_start,%esp # Load processor stack 3255 #endif 257 #endif 3256 dbra %d1,1b !! 258 xorl %eax,%eax >> 259 lldt %ax >> 260 cld # gcc2 wants the direction flag cleared at all times >> 261 #ifdef CONFIG_SMP >> 262 movb ready, %cl >> 263 cmpb $1,%cl >> 264 je 1f # the first CPU calls start_kernel >> 265 # all other CPUs call initialize_secondary >> 266 call SYMBOL_NAME(initialize_secondary) >> 267 jmp L6 >> 268 1: >> 269 #endif >> 270 call SYMBOL_NAME(start_kernel) >> 271 L6: >> 272 jmp L6 # main should never return here, but >> 273 # just in case, we know what happens. >> 274 >> 275 ready: .byte 0 >> 276 >> 277 /* >> 278 * We depend on ET to be correct. This checks for 287/387. >> 279 */ >> 280 check_x87: >> 281 movb $0,X86_HARD_MATH >> 282 clts >> 283 fninit >> 284 fstsw %ax >> 285 cmpb $0,%al >> 286 je 1f >> 287 movl %cr0,%eax /* no coprocessor: have to set bits */ >> 288 xorl $4,%eax /* set EM */ >> 289 movl %eax,%cr0 >> 290 ret >> 291 ALIGN >> 292 1: movb $1,X86_HARD_MATH >> 293 .byte 0xDB,0xE4 /* fsetpm for 287, ignored by 387 */ >> 294 ret >> 295 >> 296 /* >> 297 * setup_idt >> 298 * >> 299 * sets up a idt with 256 entries pointing to >> 300 * ignore_int, interrupt gates. It doesn't actually load >> 301 * idt - that can be done only after paging has been enabled >> 302 * and the kernel moved to PAGE_OFFSET. Interrupts >> 303 * are enabled elsewhere, when we can be relatively >> 304 * sure everything is ok. >> 305 */ >> 306 setup_idt: >> 307 lea ignore_int,%edx >> 308 movl $(__KERNEL_CS << 16),%eax >> 309 movw %dx,%ax /* selector = 0x0010 = cs */ >> 310 movw $0x8E00,%dx /* interrupt gate - dpl=0, present */ >> 311 >> 312 lea SYMBOL_NAME(idt_table),%edi >> 313 mov $256,%ecx >> 314 rp_sidt: >> 315 movl %eax,(%edi) >> 316 movl %edx,4(%edi) >> 317 addl $8,%edi >> 318 dec %ecx >> 319 jne rp_sidt >> 320 ret >> 321 >> 322 ENTRY(stack_start) >> 323 .long SYMBOL_NAME(init_task_union)+8192 >> 324 .long __KERNEL_DS >> 325 >> 326 /* This is the default interrupt "handler" :-) */ >> 327 int_msg: >> 328 .asciz "Unknown interrupt, stack: %p %p %p %p\n" >> 329 ALIGN >> 330 ignore_int: >> 331 cld >> 332 movl $(__KERNEL_DS),%eax >> 333 movl %eax,%ds >> 334 movl %eax,%es >> 335 pushl 12(%esp) >> 336 pushl 12(%esp) >> 337 pushl 12(%esp) >> 338 pushl 12(%esp) >> 339 pushl $int_msg >> 340 call SYMBOL_NAME(printk) >> 341 1: hlt >> 342 jmp 1b >> 343 >> 344 /* >> 345 * The interrupt descriptor table has room for 256 idt's, >> 346 * the global descriptor table is dependent on the number >> 347 * of tasks we can have.. >> 348 */ >> 349 #define IDT_ENTRIES 256 >> 350 #define GDT_ENTRIES (__TSS(NR_CPUS)) >> 351 >> 352 >> 353 .globl SYMBOL_NAME(idt) >> 354 .globl SYMBOL_NAME(gdt) >> 355 >> 356 ALIGN >> 357 .word 0 >> 358 idt_descr: >> 359 .word IDT_ENTRIES*8-1 # idt contains 256 entries >> 360 SYMBOL_NAME(idt): >> 361 .long SYMBOL_NAME(idt_table) >> 362 >> 363 .word 0 >> 364 gdt_descr: >> 365 .word GDT_ENTRIES*8-1 >> 366 SYMBOL_NAME(gdt): >> 367 .long SYMBOL_NAME(gdt_table) >> 368 >> 369 /* >> 370 * This is initialized to create an identity-mapping at 0-8M (for bootup >> 371 * purposes) and another mapping of the 0-8M area at virtual address >> 372 * PAGE_OFFSET. >> 373 */ >> 374 .org 0x1000 >> 375 ENTRY(swapper_pg_dir) >> 376 .long 0x00102007 >> 377 .long 0x00103007 >> 378 .fill BOOT_USER_PGD_PTRS-2,4,0 >> 379 /* default: 766 entries */ >> 380 .long 0x00102007 >> 381 .long 0x00103007 >> 382 /* default: 254 entries */ >> 383 .fill BOOT_KERNEL_PGD_PTRS-2,4,0 >> 384 >> 385 /* >> 386 * The page tables are initialized to only 8MB here - the final page >> 387 * tables are set up later depending on memory size. >> 388 */ >> 389 .org 0x2000 >> 390 ENTRY(pg0) >> 391 >> 392 .org 0x3000 >> 393 ENTRY(pg1) >> 394 >> 395 /* >> 396 * empty_zero_page must immediately follow the page tables ! (The >> 397 * initialization loop counts until empty_zero_page) >> 398 */ >> 399 >> 400 .org 0x4000 >> 401 ENTRY(empty_zero_page) 3257 402 3258 func_return putn !! 403 .org 0x5000 3259 404 3260 #ifdef CONFIG_EARLY_PRINTK << 3261 /* 405 /* 3262 * This routine takes its parameters on !! 406 * Real beginning of normal "text" segment 3263 * turns around and calls the internal r << 3264 * is used by the boot console. << 3265 * << 3266 * The calling parameters are: << 3267 * void debug_cons_nputs(const c << 3268 * << 3269 * This routine does NOT understand vari << 3270 * simple strings! << 3271 */ 407 */ 3272 ENTRY(debug_cons_nputs) !! 408 ENTRY(stext) 3273 moveml %d0/%d1/%a0,%sp@- !! 409 ENTRY(_stext) 3274 movew %sr,%sp@- << 3275 ori #0x0700,%sr << 3276 movel %sp@(18),%a0 /* fe << 3277 movel %sp@(22),%d1 /* fe << 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_A << 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 << 3315 410 3316 #ifdef CONSOLE_DEBUG << 3317 /* 411 /* 3318 * For continuity, see the data alignmen !! 412 * This starts the data section. Note that the above is all 3319 * to which this structure is tied. !! 413 * in the text section because it has alignment requirements 3320 */ !! 414 * that we cannot fulfill any other way. 3321 #define Lconsole_struct_cur_column 0 !! 415 */ 3322 #define Lconsole_struct_cur_row 4 !! 416 .data 3323 #define Lconsole_struct_num_columns 8 !! 417 3324 #define Lconsole_struct_num_rows 12 !! 418 ALIGN 3325 #define Lconsole_struct_left_edge 16 !! 419 /* 3326 !! 420 * This contains typically 140 quadwords, depending on NR_CPUS. 3327 func_start console_init,%a0-%a4/%d0-%d7 !! 421 * 3328 /* !! 422 * NOTE! Make sure the gdt descriptor in head.S matches this if you 3329 * Some of the register usage th !! 423 * change anything. 3330 * a0 = pointer to boot_ !! 424 */ 3331 * a1 = pointer to scree !! 425 ENTRY(gdt_table) 3332 * a2 = pointer to conso !! 426 .quad 0x0000000000000000 /* NULL descriptor */ 3333 * d3 = pixel width of s !! 427 .quad 0x0000000000000000 /* not used */ 3334 * d4 = pixel height of !! 428 .quad 0x00cf9a000000ffff /* 0x10 kernel 4GB code at 0x00000000 */ 3335 * (d3,d4) ~= (x,y) of a !! 429 .quad 0x00cf92000000ffff /* 0x18 kernel 4GB data at 0x00000000 */ 3336 * and to the ri !! 430 .quad 0x00cffa000000ffff /* 0x23 user 4GB code at 0x00000000 */ 3337 * NOT on the sc !! 431 .quad 0x00cff2000000ffff /* 0x2b user 4GB data at 0x00000000 */ 3338 * d5 = number of bytes !! 432 .quad 0x0000000000000000 /* not used */ 3339 * d6 = number of bytes !! 433 .quad 0x0000000000000000 /* not used */ 3340 */ !! 434 /* 3341 !! 435 * The APM segments have byte granularity and their bases 3342 lea %pc@(L(console_globals)),%a2 !! 436 * and limits are set at run time. 3343 movel %pc@(L(mac_videobase)),%a1 !! 437 */ 3344 movel %pc@(L(mac_rowbytes)),%d5 !! 438 .quad 0x0040920000000000 /* 0x40 APM set up for bad BIOS's */ 3345 movel %pc@(L(mac_dimensions)),%d3 !! 439 .quad 0x00409a0000000000 /* 0x48 APM CS code */ 3346 movel %d3,%d4 !! 440 .quad 0x00009a0000000000 /* 0x50 APM CS 16 code (16 bit) */ 3347 swap %d4 /* -> high by !! 441 .quad 0x0040920000000000 /* 0x58 APM DS data */ 3348 andl #0xffff,%d3 /* d3 = scree !! 442 .fill NR_CPUS*4,8,0 /* space for TSS's and LDT's */ 3349 andl #0xffff,%d4 /* d4 = scree << 3350 << 3351 movel %d5,%d6 << 3352 | subl #20,%d6 << 3353 mulul %d4,%d6 /* scan line << 3354 divul #8,%d6 /* we'll clea << 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_FON << 3366 lea %pc@(font_vga_8x8),%a0 << 3367 #elif defined(FONT_8x16) && defined(CONFIG_FO << 3368 lea %pc@(font_vga_8x16),%a0 << 3369 #elif defined(FONT_6x11) && defined(CONFIG_FO << 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 << 3376 << 3377 /* << 3378 * At this point we make a shift << 3379 * a1 = address of console_font << 3380 */ << 3381 lea %pc@(L(console_font)),%a1 << 3382 movel %a0,%a1@ /* store poin << 3383 tstl %a0 << 3384 jeq 1f << 3385 lea %pc@(L(console_font_data)),%a << 3386 movel %a0@(FONT_DESC_DATA),%d0 << 3387 subl #L(console_font),%a1 << 3388 addl %a1,%d0 << 3389 movel %d0,%a4@ << 3390 << 3391 /* << 3392 * Calculate global maxs << 3393 * Note - we can use either an << 3394 * 8 x 16 or 8 x 8 character fon << 3395 * 6 x 11 also supported << 3396 */ << 3397 /* ASSERT: a0 = contents of L << 3398 movel %d3,%d0 << 3399 divul %a0@(FONT_DESC_WIDTH),%d0 << 3400 << 3401 movel %d4,%d1 << 3402 divul %a0@(FONT_DESC_HEIGHT),%d1 << 3403 << 3404 movel %d0,%a2@(Lconsole_struct_num_ << 3405 movel %d1,%a2@(Lconsole_struct_num_ << 3406 << 3407 /* << 3408 * Clear the current row and col << 3409 */ << 3410 clrl %a2@(Lconsole_struct_cur_colu << 3411 clrl %a2@(Lconsole_struct_cur_row) << 3412 clrl %a2@(Lconsole_struct_left_edg << 3413 << 3414 /* << 3415 * Initialization is complete << 3416 */ << 3417 1: << 3418 func_return console_init << 3419 << 3420 #ifdef CONFIG_LOGO << 3421 func_start console_put_penguin,%a0-%a1/% << 3422 /* << 3423 * Get 'that_penguin' onto the s << 3424 * penguin is 64 x 74 pixels, al << 3425 */ << 3426 lea %pc@(L(mac_dimensions)),%a0 << 3427 movel %a0@,%d0 << 3428 andil #0xffff,%d0 << 3429 subil #64,%d0 /* snug up ag << 3430 clrl %d1 /* start at t << 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_p << 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" << 3454 #endif << 3455 << 3456 /* << 3457 * Calculate source and destination a << 3458 * output a1 = dest << 3459 * a2 = source << 3460 */ << 3461 << 3462 func_start console_scroll,%a0-%a4/%d0-%d << 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 << 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 = scree << 3482 andl #0xffff,%d4 /* d4 = scree << 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 << 3491 mulul %d4,%d6 /* scan line << 3492 divul #32,%d6 /* we'll move << 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 << 3510 divul #32,%d6 /* we << 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_lo << 3524 << 3525 1: << 3526 func_return console_scroll << 3527 << 3528 << 3529 func_start console_putc,%a0/%a1/%d0-%d7 << 3530 << 3531 is_not_mac(L(console_exit)) << 3532 tstl %pc@(L(console_font)) << 3533 jeq L(console_exit) << 3534 << 3535 /* Output character in d7 on console. << 3536 */ << 3537 movel ARG1,%d7 << 3538 cmpib #'\n',%d7 << 3539 jbne 1f << 3540 << 3541 /* A little safe recursion is good fo << 3542 console_putc #'\r' << 3543 1: << 3544 lea %pc@(L(console_globals)),%a0 << 3545 << 3546 cmpib #10,%d7 << 3547 jne L(console_not_lf) << 3548 movel %a0@(Lconsole_struct_cur_row) << 3549 addil #1,%d0 << 3550 movel %d0,%a0@(Lconsole_struct_cur_ << 3551 movel %a0@(Lconsole_struct_num_rows << 3552 cmpl %d1,%d0 << 3553 jcs 1f << 3554 subil #1,%d0 << 3555 movel %d0,%a0@(Lconsole_struct_cur_ << 3556 console_scroll << 3557 1: << 3558 jra L(console_exit) << 3559 << 3560 L(console_not_lf): << 3561 cmpib #13,%d7 << 3562 jne L(console_not_cr) << 3563 clrl %a0@(Lconsole_struct_cur_colu << 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_colu << 3571 jra L(console_exit) << 3572 << 3573 /* << 3574 * At this point we know that the %d7 ch << 3575 * rendered on the screen. Register usa << 3576 * a0 = pointer to console globa << 3577 * a1 = font data << 3578 * d0 = cursor column << 3579 * d1 = cursor row to draw the c << 3580 * d7 = character number << 3581 */ << 3582 L(console_not_home): << 3583 movel %a0@(Lconsole_struct_cur_colu << 3584 addql #1,%a0@(Lconsole_struct_cur_c << 3585 movel %a0@(Lconsole_struct_num_colu << 3586 cmpl %d1,%d0 << 3587 jcs 1f << 3588 console_putc #'\n' /* recursion << 3589 1: << 3590 movel %a0@(Lconsole_struct_cur_row) << 3591 << 3592 /* << 3593 * At this point we make a shift << 3594 * a0 = address of pointer to fo << 3595 */ << 3596 movel %pc@(L(console_font)),%a0 << 3597 movel %pc@(L(console_font_data)),%a << 3598 andl #0x000000ff,%d7 << 3599 /* ASSERT: a0 = contents of L << 3600 mulul %a0@(FONT_DESC_HEIGHT),%d7 << 3601 addl %d7,%a1 /* a1 << 3602 << 3603 /* << 3604 * At this point we make a shift << 3605 * d0 = pixel coordinate, x << 3606 * d1 = pixel coordinate, y << 3607 * d2 = (bit 0) 1/0 for white/bl << 3608 * d3 = font scan line data (8 p << 3609 * d6 = count down for the font' << 3610 * d7 = count down for the font' << 3611 */ << 3612 /* ASSERT: a0 = contents of L << 3613 mulul %a0@(FONT_DESC_WIDTH),%d0 << 3614 mulul %a0@(FONT_DESC_HEIGHT),%d1 << 3615 movel %a0@(FONT_DESC_HEIGHT),%d7 << 3616 subq #1,%d7 << 3617 L(console_read_char_scanline): << 3618 moveb %a1@+,%d3 << 3619 << 3620 /* ASSERT: a0 = contents of L << 3621 movel %a0@(FONT_DESC_WIDTH),%d6 << 3622 subql #1,%d6 << 3623 << 3624 L(console_do_font_scanline): << 3625 lslb #1,%d3 << 3626 scsb %d2 /* convert 1 << 3627 console_plot_pixel %d0,%d1,%d2 << 3628 addq #1,%d0 << 3629 dbra %d6,L(console_do_font_scanlin << 3630 << 3631 /* ASSERT: a0 = contents of L << 3632 subl %a0@(FONT_DESC_WIDTH),%d0 << 3633 addq #1,%d1 << 3634 dbra %d7,L(console_read_char_scanl << 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 << 3644 * All registers are preserved << 3645 */ << 3646 func_start console_plot_pixel,%a0-%a1/%d << 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 << 3658 * d1 = y coord << 3659 * d2 = black or white ( << 3660 * d3 = video depth << 3661 * d4 = temp of x (d0) f << 3662 */ << 3663 L(test_1bit): << 3664 cmpb #1,%d3 << 3665 jbne L(test_2bit) << 3666 movel %d0,%d4 /* we need th << 3667 divul #8,%d0 << 3668 addal %d0,%a1 << 3669 addal %d1,%a1 << 3670 andb #7,%d4 << 3671 eorb #7,%d4 /* reverse th << 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 th << 3684 divul #4,%d0 << 3685 addal %d0,%a1 << 3686 addal %d1,%a1 << 3687 andb #3,%d4 << 3688 eorb #3,%d4 /* reverse th << 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 th << 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_A << 3771 defined(CONFIG_HP300) || defined(CONFIG_A << 3772 L(custom): << 3773 L(iobase): << 3774 .long 0 << 3775 #endif << 3776 << 3777 #ifdef CONSOLE_DEBUG << 3778 L(console_globals): << 3779 .long 0 /* cursor col << 3780 .long 0 /* cursor row << 3781 .long 0 /* max num co << 3782 .long 0 /* max num ro << 3783 .long 0 /* left edge << 3784 L(console_font): << 3785 .long 0 /* pointer to << 3786 L(console_font_data): << 3787 .long 0 /* pointer to << 3788 #endif /* CONSOLE_DEBUG */ << 3789 << 3790 #if defined(MMU_PRINT) << 3791 L(mmu_print_data): << 3792 .long 0 /* valid flag << 3793 .long 0 /* start logi << 3794 .long 0 /* next logic << 3795 .long 0 /* start phys << 3796 .long 0 /* next physi << 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 << 3833 << 3834 #if defined (CONFIG_BVME6000) << 3835 BVME_SCC_CTRL_A = 0xffb0000b << 3836 BVME_SCC_DATA_A = 0xffb0000f << 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 << 3889 << 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.