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