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 4,0x44 /* x16, 1 stopbit, no parity */ 2756 .byte 3,0xc0 /* receiver: 8 bpc */ 2757 .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */ 2758 .byte 10,0 /* NRZ */ 2759 .byte 11,0x50 /* use baud rate generator */ 2760 .byte 12,1,13,0 /* 38400 baud */ 2761 .byte 14,1 /* Baud rate generator enable */ 2762 .byte 3,0xc1 /* enable receiver */ 2763 .byte 5,0xea /* enable transmitter */ 2764 .byte -1 2765 .even 2766#endif 2767 2768#ifdef CONFIG_ATARI 2769/* #define USE_PRINTER */ 2770/* #define USE_SCC_B */ 2771/* #define USE_SCC_A */ 2772#define USE_MFP 2773 2774#if defined(USE_SCC_A) || defined(USE_SCC_B) 2775#define USE_SCC 2776/* Initialisation table for SCC */ 2777L(scc_initable): 2778 .byte 9,12 /* Reset */ 2779 .byte 4,0x44 /* x16, 1 stopbit, no parity */ 2780 .byte 3,0xc0 /* receiver: 8 bpc */ 2781 .byte 5,0xe2 /* transmitter: 8 bpc, assert dtr/rts */ 2782 .byte 9,0 /* no interrupts */ 2783 .byte 10,0 /* NRZ */ 2784 .byte 11,0x50 /* use baud rate generator */ 2785 .byte 12,24,13,0 /* 9600 baud */ 2786 .byte 14,2,14,3 /* use master clock for BRG, enable */ 2787 .byte 3,0xc1 /* enable receiver */ 2788 .byte 5,0xea /* enable transmitter */ 2789 .byte -1 2790 .even 2791#endif 2792 2793#ifdef USE_PRINTER 2794 2795LPSG_SELECT = 0xff8800 2796LPSG_READ = 0xff8800 2797LPSG_WRITE = 0xff8802 2798LPSG_IO_A = 14 2799LPSG_IO_B = 15 2800LPSG_CONTROL = 7 2801LSTMFP_GPIP = 0xfffa01 2802LSTMFP_DDR = 0xfffa05 2803LSTMFP_IERB = 0xfffa09 2804 2805#elif defined(USE_SCC_B) 2806 2807LSCC_CTRL = 0xff8c85 2808LSCC_DATA = 0xff8c87 2809 2810#elif defined(USE_SCC_A) 2811 2812LSCC_CTRL = 0xff8c81 2813LSCC_DATA = 0xff8c83 2814 2815#elif defined(USE_MFP) 2816 2817LMFP_UCR = 0xfffa29 2818LMFP_TDCDR = 0xfffa1d 2819LMFP_TDDR = 0xfffa25 2820LMFP_TSR = 0xfffa2d 2821LMFP_UDR = 0xfffa2f 2822 2823#endif 2824#endif /* CONFIG_ATARI */ 2825 2826/* 2827 * Serial port output support. 2828 */ 2829 2830/* 2831 * Initialize serial port hardware for 9600/8/1 2832 */ 2833func_start serial_init,%d0/%d1/%a0/%a1 2834 /* 2835 * Some of the register usage that follows 2836 * CONFIG_AMIGA 2837 * a0 = pointer to boot info record 2838 * d0 = boot info offset 2839 * CONFIG_ATARI 2840 * a0 = address of SCC 2841 * a1 = Liobase address/address of scc_initable 2842 * d0 = init data for serial port 2843 * CONFIG_MAC 2844 * a0 = address of SCC 2845 * a1 = address of scc_initable_mac 2846 * d0 = init data for serial port 2847 */ 2848 2849#ifdef CONFIG_AMIGA 2850#define SERIAL_DTR 7 2851#define SERIAL_CNTRL CIABBASE+C_PRA 2852 2853 is_not_amiga(1f) 2854 lea %pc@(L(custom)),%a0 2855 movel #-ZTWOBASE,%a0@ 2856 bclr #SERIAL_DTR,SERIAL_CNTRL-ZTWOBASE 2857 get_bi_record BI_AMIGA_SERPER 2858 movew %a0@,CUSTOMBASE+C_SERPER-ZTWOBASE 2859| movew #61,CUSTOMBASE+C_SERPER-ZTWOBASE 28601: 2861#endif 2862#ifdef CONFIG_ATARI 2863 is_not_atari(4f) 2864 movel %pc@(L(iobase)),%a1 2865#if defined(USE_PRINTER) 2866 bclr #0,%a1@(LSTMFP_IERB) 2867 bclr #0,%a1@(LSTMFP_DDR) 2868 moveb #LPSG_CONTROL,%a1@(LPSG_SELECT) 2869 moveb #0xff,%a1@(LPSG_WRITE) 2870 moveb #LPSG_IO_B,%a1@(LPSG_SELECT) 2871 clrb %a1@(LPSG_WRITE) 2872 moveb #LPSG_IO_A,%a1@(LPSG_SELECT) 2873 moveb %a1@(LPSG_READ),%d0 2874 bset #5,%d0 2875 moveb %d0,%a1@(LPSG_WRITE) 2876#elif defined(USE_SCC) 2877 lea %a1@(LSCC_CTRL),%a0 2878 lea %pc@(L(scc_initable)),%a1 28792: moveb %a1@+,%d0 2880 jmi 3f 2881 moveb %d0,%a0@ 2882 moveb %a1@+,%a0@ 2883 jra 2b 28843: clrb %a0@ 2885#elif defined(USE_MFP) 2886 bclr #1,%a1@(LMFP_TSR) 2887 moveb #0x88,%a1@(LMFP_UCR) 2888 andb #0x70,%a1@(LMFP_TDCDR) 2889 moveb #2,%a1@(LMFP_TDDR) 2890 orb #1,%a1@(LMFP_TDCDR) 2891 bset #1,%a1@(LMFP_TSR) 2892#endif 2893 jra L(serial_init_done) 28944: 2895#endif 2896#ifdef CONFIG_MAC 2897 is_not_mac(L(serial_init_not_mac)) 2898 2899#ifdef SERIAL_DEBUG 2900 2901/* You may define either or both of these. */ 2902#define MAC_USE_SCC_A /* Modem port */ 2903#define MAC_USE_SCC_B /* Printer port */ 2904 2905#define mac_scc_cha_b_ctrl_offset 0x0 2906#define mac_scc_cha_a_ctrl_offset 0x2 2907#define mac_scc_cha_b_data_offset 0x4 2908#define mac_scc_cha_a_data_offset 0x6 2909 2910#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B) 2911 movel %pc@(L(mac_sccbase)),%a0 2912 /* Reset SCC device */ 2913 moveb #9,%a0@(mac_scc_cha_a_ctrl_offset) 2914 moveb #0xc0,%a0@(mac_scc_cha_a_ctrl_offset) 2915 /* Wait for 5 PCLK cycles, which is about 68 CPU cycles */ 2916 /* 5 / 3.6864 MHz = approx. 1.36 us = 68 / 50 MHz */ 2917 movel #35,%d0 29185: 2919 subq #1,%d0 2920 jne 5b 2921#endif 2922 2923#ifdef MAC_USE_SCC_A 2924 /* Initialize channel A */ 2925 lea %pc@(L(scc_initable_mac)),%a1 29265: moveb %a1@+,%d0 2927 jmi 6f 2928 moveb %d0,%a0@(mac_scc_cha_a_ctrl_offset) 2929 moveb %a1@+,%a0@(mac_scc_cha_a_ctrl_offset) 2930 jra 5b 29316: 2932#endif /* MAC_USE_SCC_A */ 2933 2934#ifdef MAC_USE_SCC_B 2935 /* Initialize channel B */ 2936 lea %pc@(L(scc_initable_mac)),%a1 29377: moveb %a1@+,%d0 2938 jmi 8f 2939 moveb %d0,%a0@(mac_scc_cha_b_ctrl_offset) 2940 moveb %a1@+,%a0@(mac_scc_cha_b_ctrl_offset) 2941 jra 7b 29428: 2943#endif /* MAC_USE_SCC_B */ 2944 2945#endif /* SERIAL_DEBUG */ 2946 2947 jra L(serial_init_done) 2948L(serial_init_not_mac): 2949#endif /* CONFIG_MAC */ 2950 2951#ifdef CONFIG_Q40 2952 is_not_q40(2f) 2953/* debug output goes into SRAM, so we don't do it unless requested 2954 - check for '%LX$' signature in SRAM */ 2955 lea %pc@(q40_mem_cptr),%a1 2956 move.l #0xff020010,%a1@ /* must be inited - also used by debug=mem */ 2957 move.l #0xff020000,%a1 2958 cmp.b #'%',%a1@ 2959 bne 2f /*nodbg*/ 2960 addq.w #4,%a1 2961 cmp.b #'L',%a1@ 2962 bne 2f /*nodbg*/ 2963 addq.w #4,%a1 2964 cmp.b #'X',%a1@ 2965 bne 2f /*nodbg*/ 2966 addq.w #4,%a1 2967 cmp.b #'$',%a1@ 2968 bne 2f /*nodbg*/ 2969 /* signature OK */ 2970 lea %pc@(L(q40_do_debug)),%a1 2971 tas %a1@ 2972/*nodbg: q40_do_debug is 0 by default*/ 29732: 2974#endif 2975 2976#ifdef CONFIG_APOLLO 2977/* We count on the PROM initializing SIO1 */ 2978#endif 2979 2980#ifdef CONFIG_HP300 2981/* We count on the boot loader initialising the UART */ 2982#endif 2983 2984L(serial_init_done): 2985func_return serial_init 2986 2987/* 2988 * Output character on serial port. 2989 */ 2990func_start serial_putc,%d0/%d1/%a0/%a1 2991 2992 movel ARG1,%d0 2993 cmpib #'\n',%d0 2994 jbne 1f 2995 2996 /* A little safe recursion is good for the soul */ 2997 serial_putc #'\r' 29981: 2999 3000#ifdef CONFIG_AMIGA 3001 is_not_amiga(2f) 3002 andw #0x00ff,%d0 3003 oriw #0x0100,%d0 3004 movel %pc@(L(custom)),%a0 3005 movew %d0,%a0@(CUSTOMBASE+C_SERDAT) 30061: movew %a0@(CUSTOMBASE+C_SERDATR),%d0 3007 andw #0x2000,%d0 3008 jeq 1b 3009 jra L(serial_putc_done) 30102: 3011#endif 3012 3013#ifdef CONFIG_MAC 3014 is_not_mac(5f) 3015 3016#ifdef SERIAL_DEBUG 3017 3018#if defined(MAC_USE_SCC_A) || defined(MAC_USE_SCC_B) 3019 movel %pc@(L(mac_sccbase)),%a1 3020#endif 3021 3022#ifdef MAC_USE_SCC_A 30233: btst #2,%a1@(mac_scc_cha_a_ctrl_offset) 3024 jeq 3b 3025 moveb %d0,%a1@(mac_scc_cha_a_data_offset) 3026#endif /* MAC_USE_SCC_A */ 3027 3028#ifdef MAC_USE_SCC_B 30294: btst #2,%a1@(mac_scc_cha_b_ctrl_offset) 3030 jeq 4b 3031 moveb %d0,%a1@(mac_scc_cha_b_data_offset) 3032#endif /* MAC_USE_SCC_B */ 3033 3034#endif /* SERIAL_DEBUG */ 3035 3036 jra L(serial_putc_done) 30375: 3038#endif /* CONFIG_MAC */ 3039 3040#ifdef CONFIG_ATARI 3041 is_not_atari(4f) 3042 movel %pc@(L(iobase)),%a1 3043#if defined(USE_PRINTER) 30443: btst #0,%a1@(LSTMFP_GPIP) 3045 jne 3b 3046 moveb #LPSG_IO_B,%a1@(LPSG_SELECT) 3047 moveb %d0,%a1@(LPSG_WRITE) 3048 moveb #LPSG_IO_A,%a1@(LPSG_SELECT) 3049 moveb %a1@(LPSG_READ),%d0 3050 bclr #5,%d0 3051 moveb %d0,%a1@(LPSG_WRITE) 3052 nop 3053 nop 3054 bset #5,%d0 3055 moveb %d0,%a1@(LPSG_WRITE) 3056#elif defined(USE_SCC) 30573: btst #2,%a1@(LSCC_CTRL) 3058 jeq 3b 3059 moveb %d0,%a1@(LSCC_DATA) 3060#elif defined(USE_MFP) 30613: btst #7,%a1@(LMFP_TSR) 3062 jeq 3b 3063 moveb %d0,%a1@(LMFP_UDR) 3064#endif 3065 jra L(serial_putc_done) 30664: 3067#endif /* CONFIG_ATARI */ 3068 3069#ifdef CONFIG_MVME147 3070 is_not_mvme147(2f) 30711: btst #2,M147_SCC_CTRL_A 3072 jeq 1b 3073 moveb %d0,M147_SCC_DATA_A 3074 jbra L(serial_putc_done) 30752: 3076#endif 3077 3078#ifdef CONFIG_MVME16x 3079 is_not_mvme16x(2f) 3080 /* 3081 * If the loader gave us a board type then we can use that to 3082 * select an appropriate output routine; otherwise we just use 3083 * the Bug code. If we have to use the Bug that means the Bug 3084 * workspace has to be valid, which means the Bug has to use 3085 * the SRAM, which is non-standard. 3086 */ 3087 moveml %d0-%d7/%a2-%a6,%sp@- 3088 movel vme_brdtype,%d1 3089 jeq 1f | No tag - use the Bug 3090 cmpi #VME_TYPE_MVME162,%d1 3091 jeq 6f 3092 cmpi #VME_TYPE_MVME172,%d1 3093 jne 5f 3094 /* 162/172; it's an SCC */ 30956: btst #2,M162_SCC_CTRL_A 3096 nop 3097 nop 3098 nop 3099 jeq 6b 3100 moveb #8,M162_SCC_CTRL_A 3101 nop 3102 nop 3103 nop 3104 moveb %d0,M162_SCC_CTRL_A 3105 jra 3f 31065: 3107 /* 166/167/177; it's a CD2401 */ 3108 moveb #0,M167_CYCAR 3109 moveb M167_CYIER,%d2 3110 moveb #0x02,M167_CYIER 31117: 3112 btst #5,M167_PCSCCTICR 3113 jeq 7b 3114 moveb M167_PCTPIACKR,%d1 3115 moveb M167_CYLICR,%d1 3116 jeq 8f 3117 moveb #0x08,M167_CYTEOIR 3118 jra 7b 31198: 3120 moveb %d0,M167_CYTDR 3121 moveb #0,M167_CYTEOIR 3122 moveb %d2,M167_CYIER 3123 jra 3f 31241: 3125 moveb %d0,%sp@- 3126 trap #15 3127 .word 0x0020 /* TRAP 0x020 */ 31283: 3129 moveml %sp@+,%d0-%d7/%a2-%a6 3130 jbra L(serial_putc_done) 31312: 3132#endif /* CONFIG_MVME16x */ 3133 3134#ifdef CONFIG_BVME6000 3135 is_not_bvme6000(2f) 3136 /* 3137 * The BVME6000 machine has a serial port ... 3138 */ 31391: btst #2,BVME_SCC_CTRL_A 3140 jeq 1b 3141 moveb %d0,BVME_SCC_DATA_A 3142 jbra L(serial_putc_done) 31432: 3144#endif 3145 3146#ifdef CONFIG_SUN3X 3147 is_not_sun3x(2f) 3148 movel %d0,-(%sp) 3149 movel 0xFEFE0018,%a1 3150 jbsr (%a1) 3151 addq #4,%sp 3152 jbra L(serial_putc_done) 31532: 3154#endif 3155 3156#ifdef CONFIG_Q40 3157 is_not_q40(2f) 3158 tst.l %pc@(L(q40_do_debug)) /* only debug if requested */ 3159 beq 2f 3160 lea %pc@(q40_mem_cptr),%a1 3161 move.l %a1@,%a0 3162 move.b %d0,%a0@ 3163 addq.l #4,%a0 3164 move.l %a0,%a1@ 3165 jbra L(serial_putc_done) 31662: 3167#endif 3168 3169#ifdef CONFIG_APOLLO 3170 is_not_apollo(2f) 3171 movl %pc@(L(iobase)),%a1 3172 moveb %d0,%a1@(LTHRB0) 31731: moveb %a1@(LSRB0),%d0 3174 andb #0x4,%d0 3175 beq 1b 3176 jbra L(serial_putc_done) 31772: 3178#endif 3179 3180#ifdef CONFIG_HP300 3181 is_not_hp300(3f) 3182 movl %pc@(L(iobase)),%a1 3183 addl %pc@(L(uartbase)),%a1 3184 movel %pc@(L(uart_scode)),%d1 /* Check the scode */ 3185 jmi 3f /* Unset? Exit */ 3186 cmpi #256,%d1 /* APCI scode? */ 3187 jeq 2f 31881: moveb %a1@(DCALSR),%d1 /* Output to DCA */ 3189 andb #0x20,%d1 3190 beq 1b 3191 moveb %d0,%a1@(DCADATA) 3192 jbra L(serial_putc_done) 31932: moveb %a1@(APCILSR),%d1 /* Output to APCI */ 3194 andb #0x20,%d1 3195 beq 2b 3196 moveb %d0,%a1@(APCIDATA) 3197 jbra L(serial_putc_done) 31983: 3199#endif 3200 3201L(serial_putc_done): 3202func_return serial_putc 3203 3204/* 3205 * Output a string. 3206 */ 3207func_start puts,%d0/%a0 3208 3209 movel ARG1,%a0 3210 jra 2f 32111: 3212#ifdef CONSOLE 3213 console_putc %d0 3214#endif 3215#ifdef SERIAL_DEBUG 3216 serial_putc %d0 3217#endif 32182: moveb %a0@+,%d0 3219 jne 1b 3220 3221func_return puts 3222 3223/* 3224 * Output number in hex notation. 3225 */ 3226 3227func_start putn,%d0-%d2 3228 3229 putc ' ' 3230 3231 movel ARG1,%d0 3232 moveq #7,%d1 32331: roll #4,%d0 3234 move %d0,%d2 3235 andb #0x0f,%d2 3236 addb #'0',%d2 3237 cmpb #'9',%d2 3238 jls 2f 3239 addb #'A'-('9'+1),%d2 32402: 3241#ifdef CONSOLE 3242 console_putc %d2 3243#endif 3244#ifdef SERIAL_DEBUG 3245 serial_putc %d2 3246#endif 3247 dbra %d1,1b 3248 3249func_return putn 3250 3251#ifdef CONFIG_MAC 3252/* 3253 * mac_early_print 3254 * 3255 * This routine takes its parameters on the stack. It then 3256 * turns around and calls the internal routines. This routine 3257 * is used by the boot console. 3258 * 3259 * The calling parameters are: 3260 * void mac_early_print(const char *str, unsigned length); 3261 * 3262 * This routine does NOT understand variable arguments only 3263 * simple strings! 3264 */ 3265ENTRY(mac_early_print) 3266 moveml %d0/%d1/%a0,%sp@- 3267 movew %sr,%sp@- 3268 ori #0x0700,%sr 3269 movel %sp@(18),%a0 /* fetch parameter */ 3270 movel %sp@(22),%d1 /* fetch parameter */ 3271 jra 2f 32721: 3273#ifdef CONSOLE 3274 console_putc %d0 3275#endif 3276#ifdef SERIAL_DEBUG 3277 serial_putc %d0 3278#endif 3279 subq #1,%d1 32802: jeq 3f 3281 moveb %a0@+,%d0 3282 jne 1b 32833: 3284 movew %sp@+,%sr 3285 moveml %sp@+,%d0/%d1/%a0 3286 rts 3287#endif /* CONFIG_MAC */ 3288 3289#if defined(CONFIG_HP300) || defined(CONFIG_APOLLO) 3290func_start set_leds,%d0/%a0 3291 movel ARG1,%d0 3292#ifdef CONFIG_HP300 3293 is_not_hp300(1f) 3294 movel %pc@(L(iobase)),%a0 3295 moveb %d0,%a0@(0x1ffff) 3296 jra 2f 3297#endif 32981: 3299#ifdef CONFIG_APOLLO 3300 movel %pc@(L(iobase)),%a0 3301 lsll #8,%d0 3302 eorw #0xff00,%d0 3303 moveb %d0,%a0@(LCPUCTRL) 3304#endif 33052: 3306func_return set_leds 3307#endif 3308 3309#ifdef CONSOLE 3310/* 3311 * For continuity, see the data alignment 3312 * to which this structure is tied. 3313 */ 3314#define Lconsole_struct_cur_column 0 3315#define Lconsole_struct_cur_row 4 3316#define Lconsole_struct_num_columns 8 3317#define Lconsole_struct_num_rows 12 3318#define Lconsole_struct_left_edge 16 3319#define Lconsole_struct_penguin_putc 20 3320 3321func_start console_init,%a0-%a4/%d0-%d7 3322 /* 3323 * Some of the register usage that follows 3324 * a0 = pointer to boot_info 3325 * a1 = pointer to screen 3326 * a2 = pointer to Lconsole_globals 3327 * d3 = pixel width of screen 3328 * d4 = pixel height of screen 3329 * (d3,d4) ~= (x,y) of a point just below 3330 * and to the right of the screen 3331 * NOT on the screen! 3332 * d5 = number of bytes per scan line 3333 * d6 = number of bytes on the entire screen 3334 */ 3335 3336 lea %pc@(L(console_globals)),%a2 3337 movel %pc@(L(mac_videobase)),%a1 3338 movel %pc@(L(mac_rowbytes)),%d5 3339 movel %pc@(L(mac_dimensions)),%d3 /* -> low byte */ 3340 movel %d3,%d4 3341 swap %d4 /* -> high byte */ 3342 andl #0xffff,%d3 /* d3 = screen width in pixels */ 3343 andl #0xffff,%d4 /* d4 = screen height in pixels */ 3344 3345 movel %d5,%d6 3346| subl #20,%d6 3347 mulul %d4,%d6 /* scan line bytes x num scan lines */ 3348 divul #8,%d6 /* we'll clear 8 bytes at a time */ 3349 moveq #-1,%d0 /* Mac_black */ 3350 subq #1,%d6 3351 3352L(console_clear_loop): 3353 movel %d0,%a1@+ 3354 movel %d0,%a1@+ 3355 dbra %d6,L(console_clear_loop) 3356 3357 /* Calculate font size */ 3358 3359#if defined(FONT_8x8) && defined(CONFIG_FONT_8x8) 3360 lea %pc@(font_vga_8x8),%a0 3361#elif defined(FONT_8x16) && defined(CONFIG_FONT_8x16) 3362 lea %pc@(font_vga_8x16),%a0 3363#elif defined(FONT_6x11) && defined(CONFIG_FONT_6x11) 3364 lea %pc@(font_vga_6x11),%a0 3365#elif defined(CONFIG_FONT_8x8) /* default */ 3366 lea %pc@(font_vga_8x8),%a0 3367#else /* no compiled-in font */ 3368 lea 0,%a0 3369#endif 3370 3371 /* 3372 * At this point we make a shift in register usage 3373 * a1 = address of console_font pointer 3374 */ 3375 lea %pc@(L(console_font)),%a1 3376 movel %a0,%a1@ /* store pointer to struct fbcon_font_desc in console_font */ 3377 tstl %a0 3378 jeq 1f 3379 lea %pc@(L(console_font_data)),%a4 3380 movel %a0@(FONT_DESC_DATA),%d0 3381 subl #L(console_font),%a1 3382 addl %a1,%d0 3383 movel %d0,%a4@ 3384 3385 /* 3386 * Calculate global maxs 3387 * Note - we can use either an 3388 * 8 x 16 or 8 x 8 character font 3389 * 6 x 11 also supported 3390 */ 3391 /* ASSERT: a0 = contents of Lconsole_font */ 3392 movel %d3,%d0 /* screen width in pixels */ 3393 divul %a0@(FONT_DESC_WIDTH),%d0 /* d0 = max num chars per row */ 3394 3395 movel %d4,%d1 /* screen height in pixels */ 3396 divul %a0@(FONT_DESC_HEIGHT),%d1 /* d1 = max num rows */ 3397 3398 movel %d0,%a2@(Lconsole_struct_num_columns) 3399 movel %d1,%a2@(Lconsole_struct_num_rows) 3400 3401 /* 3402 * Clear the current row and column 3403 */ 3404 clrl %a2@(Lconsole_struct_cur_column) 3405 clrl %a2@(Lconsole_struct_cur_row) 3406 clrl %a2@(Lconsole_struct_left_edge) 3407 3408 /* 3409 * Initialization is complete 3410 */ 34111: 3412func_return console_init 3413 3414func_start console_put_stats,%a0/%d7 3415 /* 3416 * Some of the register usage that follows 3417 * a0 = pointer to boot_info 3418 * d7 = value of boot_info fields 3419 */ 3420 puts "\nMacLinux\n" 3421 3422#ifdef SERIAL_DEBUG 3423 puts "\n vidaddr:" 3424 putn %pc@(L(mac_videobase)) /* video addr. */ 3425 3426 puts "\n _stext:" 3427 lea %pc@(_stext),%a0 3428 putn %a0 3429 3430 puts "\nbootinfo:" 3431 lea %pc@(_end),%a0 3432 putn %a0 3433 3434 puts "\n cpuid:" 3435 putn %pc@(L(cputype)) 3436 3437# ifdef CONFIG_MAC 3438 puts "\n sccbase:" 3439 putn %pc@(L(mac_sccbase)) 3440# endif 3441# ifdef MMU_PRINT 3442 putc '\n' 3443 jbsr mmu_print_machine_cpu_types 3444# endif 3445#endif /* SERIAL_DEBUG */ 3446 3447 putc '\n' 3448 3449func_return console_put_stats 3450 3451#ifdef CONSOLE_PENGUIN 3452func_start console_put_penguin,%a0-%a1/%d0-%d7 3453 /* 3454 * Get 'that_penguin' onto the screen in the upper right corner 3455 * penguin is 64 x 74 pixels, align against right edge of screen 3456 */ 3457 lea %pc@(L(mac_dimensions)),%a0 3458 movel %a0@,%d0 3459 andil #0xffff,%d0 3460 subil #64,%d0 /* snug up against the right edge */ 3461 clrl %d1 /* start at the top */ 3462 movel #73,%d7 3463 lea %pc@(L(that_penguin)),%a1 3464L(console_penguin_row): 3465 movel #31,%d6 3466L(console_penguin_pixel_pair): 3467 moveb %a1@,%d2 3468 lsrb #4,%d2 3469 console_plot_pixel %d0,%d1,%d2 3470 addq #1,%d0 3471 moveb %a1@+,%d2 3472 console_plot_pixel %d0,%d1,%d2 3473 addq #1,%d0 3474 dbra %d6,L(console_penguin_pixel_pair) 3475 3476 subil #64,%d0 3477 addq #1,%d1 3478 dbra %d7,L(console_penguin_row) 3479 3480func_return console_put_penguin 3481 3482/* include penguin bitmap */ 3483L(that_penguin): 3484#include "../mac/mac_penguin.S" 3485#endif 3486 3487 /* 3488 * Calculate source and destination addresses 3489 * output a1 = dest 3490 * a2 = source 3491 */ 3492 3493func_start console_scroll,%a0-%a4/%d0-%d7 3494 lea %pc@(L(mac_videobase)),%a0 3495 movel %a0@,%a1 3496 movel %a1,%a2 3497 lea %pc@(L(mac_rowbytes)),%a0 3498 movel %a0@,%d5 3499 movel %pc@(L(console_font)),%a0 3500 tstl %a0 3501 jeq 1f 3502 mulul %a0@(FONT_DESC_HEIGHT),%d5 /* account for # scan lines per character */ 3503 addal %d5,%a2 3504 3505 /* 3506 * Get dimensions 3507 */ 3508 lea %pc@(L(mac_dimensions)),%a0 3509 movel %a0@,%d3 3510 movel %d3,%d4 3511 swap %d4 3512 andl #0xffff,%d3 /* d3 = screen width in pixels */ 3513 andl #0xffff,%d4 /* d4 = screen height in pixels */ 3514 3515 /* 3516 * Calculate number of bytes to move 3517 */ 3518 lea %pc@(L(mac_rowbytes)),%a0 3519 movel %a0@,%d6 3520 movel %pc@(L(console_font)),%a0 3521 subl %a0@(FONT_DESC_HEIGHT),%d4 /* we're not scrolling the top row! */ 3522 mulul %d4,%d6 /* scan line bytes x num scan lines */ 3523 divul #32,%d6 /* we'll move 8 longs at a time */ 3524 subq #1,%d6 3525 3526L(console_scroll_loop): 3527 movel %a2@+,%a1@+ 3528 movel %a2@+,%a1@+ 3529 movel %a2@+,%a1@+ 3530 movel %a2@+,%a1@+ 3531 movel %a2@+,%a1@+ 3532 movel %a2@+,%a1@+ 3533 movel %a2@+,%a1@+ 3534 movel %a2@+,%a1@+ 3535 dbra %d6,L(console_scroll_loop) 3536 3537 lea %pc@(L(mac_rowbytes)),%a0 3538 movel %a0@,%d6 3539 movel %pc@(L(console_font)),%a0 3540 mulul %a0@(FONT_DESC_HEIGHT),%d6 /* scan line bytes x font height */ 3541 divul #32,%d6 /* we'll move 8 words at a time */ 3542 subq #1,%d6 3543 3544 moveq #-1,%d0 3545L(console_scroll_clear_loop): 3546 movel %d0,%a1@+ 3547 movel %d0,%a1@+ 3548 movel %d0,%a1@+ 3549 movel %d0,%a1@+ 3550 movel %d0,%a1@+ 3551 movel %d0,%a1@+ 3552 movel %d0,%a1@+ 3553 movel %d0,%a1@+ 3554 dbra %d6,L(console_scroll_clear_loop) 3555 35561: 3557func_return console_scroll 3558 3559 3560func_start console_putc,%a0/%a1/%d0-%d7 3561 3562 is_not_mac(L(console_exit)) 3563 tstl %pc@(L(console_font)) 3564 jeq L(console_exit) 3565 3566 /* Output character in d7 on console. 3567 */ 3568 movel ARG1,%d7 3569 cmpib #'\n',%d7 3570 jbne 1f 3571 3572 /* A little safe recursion is good for the soul */ 3573 console_putc #'\r' 35741: 3575 lea %pc@(L(console_globals)),%a0 3576 3577 cmpib #10,%d7 3578 jne L(console_not_lf) 3579 movel %a0@(Lconsole_struct_cur_row),%d0 3580 addil #1,%d0 3581 movel %d0,%a0@(Lconsole_struct_cur_row) 3582 movel %a0@(Lconsole_struct_num_rows),%d1 3583 cmpl %d1,%d0 3584 jcs 1f 3585 subil #1,%d0 3586 movel %d0,%a0@(Lconsole_struct_cur_row) 3587 console_scroll 35881: 3589 jra L(console_exit) 3590 3591L(console_not_lf): 3592 cmpib #13,%d7 3593 jne L(console_not_cr) 3594 clrl %a0@(Lconsole_struct_cur_column) 3595 jra L(console_exit) 3596 3597L(console_not_cr): 3598 cmpib #1,%d7 3599 jne L(console_not_home) 3600 clrl %a0@(Lconsole_struct_cur_row) 3601 clrl %a0@(Lconsole_struct_cur_column) 3602 jra L(console_exit) 3603 3604/* 3605 * At this point we know that the %d7 character is going to be 3606 * rendered on the screen. Register usage is - 3607 * a0 = pointer to console globals 3608 * a1 = font data 3609 * d0 = cursor column 3610 * d1 = cursor row to draw the character 3611 * d7 = character number 3612 */ 3613L(console_not_home): 3614 movel %a0@(Lconsole_struct_cur_column),%d0 3615 addql #1,%a0@(Lconsole_struct_cur_column) 3616 movel %a0@(Lconsole_struct_num_columns),%d1 3617 cmpl %d1,%d0 3618 jcs 1f 3619 console_putc #'\n' /* recursion is OK! */ 36201: 3621 movel %a0@(Lconsole_struct_cur_row),%d1 3622 3623 /* 3624 * At this point we make a shift in register usage 3625 * a0 = address of pointer to font data (fbcon_font_desc) 3626 */ 3627 movel %pc@(L(console_font)),%a0 3628 movel %pc@(L(console_font_data)),%a1 /* Load fbcon_font_desc.data into a1 */ 3629 andl #0x000000ff,%d7 3630 /* ASSERT: a0 = contents of Lconsole_font */ 3631 mulul %a0@(FONT_DESC_HEIGHT),%d7 /* d7 = index into font data */ 3632 addl %d7,%a1 /* a1 = points to char image */ 3633 3634 /* 3635 * At this point we make a shift in register usage 3636 * d0 = pixel coordinate, x 3637 * d1 = pixel coordinate, y 3638 * d2 = (bit 0) 1/0 for white/black (!) pixel on screen 3639 * d3 = font scan line data (8 pixels) 3640 * d6 = count down for the font's pixel width (8) 3641 * d7 = count down for the font's pixel count in height 3642 */ 3643 /* ASSERT: a0 = contents of Lconsole_font */ 3644 mulul %a0@(FONT_DESC_WIDTH),%d0 3645 mulul %a0@(FONT_DESC_HEIGHT),%d1 3646 movel %a0@(FONT_DESC_HEIGHT),%d7 /* Load fbcon_font_desc.height into d7 */ 3647 subq #1,%d7 3648L(console_read_char_scanline): 3649 moveb %a1@+,%d3 3650 3651 /* ASSERT: a0 = contents of Lconsole_font */ 3652 movel %a0@(FONT_DESC_WIDTH),%d6 /* Load fbcon_font_desc.width into d6 */ 3653 subql #1,%d6 3654 3655L(console_do_font_scanline): 3656 lslb #1,%d3 3657 scsb %d2 /* convert 1 bit into a byte */ 3658 console_plot_pixel %d0,%d1,%d2 3659 addq #1,%d0 3660 dbra %d6,L(console_do_font_scanline) 3661 3662 /* ASSERT: a0 = contents of Lconsole_font */ 3663 subl %a0@(FONT_DESC_WIDTH),%d0 3664 addq #1,%d1 3665 dbra %d7,L(console_read_char_scanline) 3666 3667L(console_exit): 3668func_return console_putc 3669 3670 /* 3671 * Input: 3672 * d0 = x coordinate 3673 * d1 = y coordinate 3674 * d2 = (bit 0) 1/0 for white/black (!) 3675 * All registers are preserved 3676 */ 3677func_start console_plot_pixel,%a0-%a1/%d0-%d4 3678 3679 movel %pc@(L(mac_videobase)),%a1 3680 movel %pc@(L(mac_videodepth)),%d3 3681 movel ARG1,%d0 3682 movel ARG2,%d1 3683 mulul %pc@(L(mac_rowbytes)),%d1 3684 movel ARG3,%d2 3685 3686 /* 3687 * Register usage: 3688 * d0 = x coord becomes byte offset into frame buffer 3689 * d1 = y coord 3690 * d2 = black or white (0/1) 3691 * d3 = video depth 3692 * d4 = temp of x (d0) for many bit depths 3693 */ 3694L(test_1bit): 3695 cmpb #1,%d3 3696 jbne L(test_2bit) 3697 movel %d0,%d4 /* we need the low order 3 bits! */ 3698 divul #8,%d0 3699 addal %d0,%a1 3700 addal %d1,%a1 3701 andb #7,%d4 3702 eorb #7,%d4 /* reverse the x-coordinate w/ screen-bit # */ 3703 andb #1,%d2 3704 jbne L(white_1) 3705 bsetb %d4,%a1@ 3706 jbra L(console_plot_pixel_exit) 3707L(white_1): 3708 bclrb %d4,%a1@ 3709 jbra L(console_plot_pixel_exit) 3710 3711L(test_2bit): 3712 cmpb #2,%d3 3713 jbne L(test_4bit) 3714 movel %d0,%d4 /* we need the low order 2 bits! */ 3715 divul #4,%d0 3716 addal %d0,%a1 3717 addal %d1,%a1 3718 andb #3,%d4 3719 eorb #3,%d4 /* reverse the x-coordinate w/ screen-bit # */ 3720 lsll #1,%d4 /* ! */ 3721 andb #1,%d2 3722 jbne L(white_2) 3723 bsetb %d4,%a1@ 3724 addq #1,%d4 3725 bsetb %d4,%a1@ 3726 jbra L(console_plot_pixel_exit) 3727L(white_2): 3728 bclrb %d4,%a1@ 3729 addq #1,%d4 3730 bclrb %d4,%a1@ 3731 jbra L(console_plot_pixel_exit) 3732 3733L(test_4bit): 3734 cmpb #4,%d3 3735 jbne L(test_8bit) 3736 movel %d0,%d4 /* we need the low order bit! */ 3737 divul #2,%d0 3738 addal %d0,%a1 3739 addal %d1,%a1 3740 andb #1,%d4 3741 eorb #1,%d4 3742 lsll #2,%d4 /* ! */ 3743 andb #1,%d2 3744 jbne L(white_4) 3745 bsetb %d4,%a1@ 3746 addq #1,%d4 3747 bsetb %d4,%a1@ 3748 addq #1,%d4 3749 bsetb %d4,%a1@ 3750 addq #1,%d4 3751 bsetb %d4,%a1@ 3752 jbra L(console_plot_pixel_exit) 3753L(white_4): 3754 bclrb %d4,%a1@ 3755 addq #1,%d4 3756 bclrb %d4,%a1@ 3757 addq #1,%d4 3758 bclrb %d4,%a1@ 3759 addq #1,%d4 3760 bclrb %d4,%a1@ 3761 jbra L(console_plot_pixel_exit) 3762 3763L(test_8bit): 3764 cmpb #8,%d3 3765 jbne L(test_16bit) 3766 addal %d0,%a1 3767 addal %d1,%a1 3768 andb #1,%d2 3769 jbne L(white_8) 3770 moveb #0xff,%a1@ 3771 jbra L(console_plot_pixel_exit) 3772L(white_8): 3773 clrb %a1@ 3774 jbra L(console_plot_pixel_exit) 3775 3776L(test_16bit): 3777 cmpb #16,%d3 3778 jbne L(console_plot_pixel_exit) 3779 addal %d0,%a1 3780 addal %d0,%a1 3781 addal %d1,%a1 3782 andb #1,%d2 3783 jbne L(white_16) 3784 clrw %a1@ 3785 jbra L(console_plot_pixel_exit) 3786L(white_16): 3787 movew #0x0fff,%a1@ 3788 jbra L(console_plot_pixel_exit) 3789 3790L(console_plot_pixel_exit): 3791func_return console_plot_pixel 3792#endif /* CONSOLE */ 3793 3794#if 0 3795/* 3796 * This is some old code lying around. I don't believe 3797 * it's used or important anymore. My guess is it contributed 3798 * to getting to this point, but it's done for now. 3799 * It was still in the 2.1.77 head.S, so it's still here. 3800 * (And still not used!) 3801 */ 3802L(showtest): 3803 moveml %a0/%d7,%sp@- 3804 puts "A=" 3805 putn %a1 3806 3807 .long 0xf0119f15 | ptestr #5,%a1@,#7,%a0 3808 3809 puts "DA=" 3810 putn %a0 3811 3812 puts "D=" 3813 putn %a0@ 3814 3815 puts "S=" 3816 lea %pc@(L(mmu)),%a0 3817 .long 0xf0106200 | pmove %psr,%a0@ 3818 clrl %d7 3819 movew %a0@,%d7 3820 putn %d7 3821 3822 putc '\n' 3823 moveml %sp@+,%a0/%d7 3824 rts 3825#endif /* 0 */ 3826 3827__INITDATA 3828 .align 4 3829 3830#if defined(CONFIG_ATARI) || defined(CONFIG_AMIGA) || \ 3831 defined(CONFIG_HP300) || defined(CONFIG_APOLLO) 3832L(custom): 3833L(iobase): 3834 .long 0 3835#endif 3836 3837#if defined(CONSOLE) 3838L(console_globals): 3839 .long 0 /* cursor column */ 3840 .long 0 /* cursor row */ 3841 .long 0 /* max num columns */ 3842 .long 0 /* max num rows */ 3843 .long 0 /* left edge */ 3844 .long 0 /* mac putc */ 3845L(console_font): 3846 .long 0 /* pointer to console font (struct font_desc) */ 3847L(console_font_data): 3848 .long 0 /* pointer to console font data */ 3849#endif /* CONSOLE */ 3850 3851#if defined(MMU_PRINT) 3852L(mmu_print_data): 3853 .long 0 /* valid flag */ 3854 .long 0 /* start logical */ 3855 .long 0 /* next logical */ 3856 .long 0 /* start physical */ 3857 .long 0 /* next physical */ 3858#endif /* MMU_PRINT */ 3859 3860L(cputype): 3861 .long 0 3862L(mmu_cached_pointer_tables): 3863 .long 0 3864L(mmu_num_pointer_tables): 3865 .long 0 3866L(phys_kernel_start): 3867 .long 0 3868L(kernel_end): 3869 .long 0 3870L(memory_start): 3871 .long 0 3872L(kernel_pgdir_ptr): 3873 .long 0 3874L(temp_mmap_mem): 3875 .long 0 3876 3877#if defined (CONFIG_MVME147) 3878M147_SCC_CTRL_A = 0xfffe3002 3879M147_SCC_DATA_A = 0xfffe3003 3880#endif 3881 3882#if defined (CONFIG_MVME16x) 3883M162_SCC_CTRL_A = 0xfff45005 3884M167_CYCAR = 0xfff450ee 3885M167_CYIER = 0xfff45011 3886M167_CYLICR = 0xfff45026 3887M167_CYTEOIR = 0xfff45085 3888M167_CYTDR = 0xfff450f8 3889M167_PCSCCTICR = 0xfff4201e 3890M167_PCTPIACKR = 0xfff42025 3891#endif 3892 3893#if defined (CONFIG_BVME6000) 3894BVME_SCC_CTRL_A = 0xffb0000b 3895BVME_SCC_DATA_A = 0xffb0000f 3896#endif 3897 3898#if defined(CONFIG_MAC) 3899L(mac_booter_data): 3900 .long 0 3901L(mac_videobase): 3902 .long 0 3903L(mac_videodepth): 3904 .long 0 3905L(mac_dimensions): 3906 .long 0 3907L(mac_rowbytes): 3908 .long 0 3909#ifdef SERIAL_DEBUG 3910L(mac_sccbase): 3911 .long 0 3912#endif 3913#endif /* CONFIG_MAC */ 3914 3915#if defined (CONFIG_APOLLO) 3916LSRB0 = 0x10412 3917LTHRB0 = 0x10416 3918LCPUCTRL = 0x10100 3919#endif 3920 3921#if defined(CONFIG_HP300) 3922DCADATA = 0x11 3923DCALSR = 0x1b 3924APCIDATA = 0x00 3925APCILSR = 0x14 3926L(uartbase): 3927 .long 0 3928L(uart_scode): 3929 .long -1 3930#endif 3931 3932__FINIT 3933 .data 3934 .align 4 3935 3936availmem: 3937 .long 0 3938m68k_pgtable_cachemode: 3939 .long 0 3940m68k_supervisor_cachemode: 3941 .long 0 3942#if defined(CONFIG_MVME16x) 3943mvme_bdid: 3944 .long 0,0,0,0,0,0,0,0 3945#endif 3946#if defined(CONFIG_Q40) 3947q40_mem_cptr: 3948 .long 0 3949L(q40_do_debug): 3950 .long 0 3951#endif 3952