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