root/arch/m68k/kernel/head.S

/* [previous][next][first][last][top][bottom][index][help] */
   1 /* -*- mode: asm -*-
   2 **
   3 ** head.S -- This file contains the initial boot code for the 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 **
  11 ** Atari support by Andreas Schwab, using ideas of Robert de Vries
  12 ** and Bjoern Brauel
  13 **
  14 ** 94/11/14 Andreas Schwab: put kernel at PAGESIZE
  15 ** 94/11/18 Andreas Schwab: remove identity mapping of STRAM for Atari 
  16 ** ++ Bjoern & Roman: ATARI-68040 support for the Medusa
  17 **
  18 ** This file is subject to the terms and conditions of the GNU General Public
  19 ** License.  See the file README.legal in the main directory of this archive
  20 ** for more details.
  21 **
  22 */
  23 
  24 /*
  25  * Linux startup code.
  26  *
  27  * At this point, the boot loader has:
  28  * Disabled interrupts
  29  * Disabled caches
  30  * Put us in supervisor state.
  31  *
  32  * The kernel setup code takes the following steps:
  33  *   Raise interrupt level
  34  *   Set up initial kernel memory mapping.
  35  *      This sets up a mapping of the 4M of memory the kernel
  36  *      is located in.  It also does a mapping of any initial
  37  *      machine specific areas.
  38  * Note that the kernel is located at virtual address 0x1000 == _start
  39  *   Enable cache memories
  40  *   Jump to kernel startup
  41  *
  42  * Register d6 contains the CPU flags and d4 the machine type
  43  * from the boot_info information for most of this file.
  44  * The upper word of d6 contains a bit for '040 or '060, since these two
  45  * are quite similar for initial mm setup. Another bit in d6 allows
  46  * distinction of the '060. The lower word of d6 contains the cache mode
  47  * that should be applied to pages containing descriptors. This mode is
  48  * non-cached/non-serialized for the '040 and cacheable/write-through for
  49  * the '060.
  50  */
  51 
  52 #include <linux/linkage.h>
  53 #include <asm/bootinfo.h>
  54 
  55 .text
  56 .globl SYMBOL_NAME(kernel_pg_dir), SYMBOL_NAME(kpt)
  57 .globl SYMBOL_NAME(availmem), SYMBOL_NAME(is_medusa)
  58 .globl SYMBOL_NAME(m68k_pgtable_cachemode)
  59 .globl SYMBOL_NAME(kernel_pmd_table), SYMBOL_NAME(swapper_pg_dir)
  60 
  61 PAGESIZE = 4096
  62 BI_CPU = 4
  63 BI_MACH = 0
  64 BI_AMIGA_ECLK = 1234
  65 LF   = 10
  66 CR   = 13
  67 BI_BIT040 = 2   /* CPU bits in bootinfo */
  68 BI_BIT060 = 3
  69 BIT0460   = 16  /* indicates '0[46]0 in d6 */
  70 BIT060    = 17  /* indicates '060 in d6 */
  71 D6VAL_040 = 0x00010000
  72 D6VAL_060 = 0x00030000
  73 /* BIT040 = 2 */
  74 
  75      /* Some definitions for the special registers of the 68040.
  76       * (MMU, caches)
  77       */
  78 
  79 /* Translation control register */
  80 TC_ENABLE = 0x8000
  81 TC_PAGE8K = 0x4000
  82 TC_PAGE4K = 0x0000
  83 
  84 /* Transparent translation registers */
  85 TTR_ENABLE = 0x8000
  86 
  87 /* Some bits used in the page and table descriptors as well as in the 
  88  * special registers.
  89  */
  90 
  91 CM_CACHE_WT     = 0x0000          /* cacheable, write-through */
  92 CM_CACHE_CB     = 0x0020          /* cacheable, copyback */
  93 CM_NONCACHE_SER = 0x0040          /* noncacheable, serialized */
  94 CM_NONCACHE     = 0x0060          /* noncacheable */
  95 CM_MASK         = 0xffffff9f      /* mask */
  96 
  97 MODIFIED        = 0x0010
  98 WRITE_PROT      = 0x0004
  99 USED            = 0x0008
 100 GLOBAL          = 0x0400
 101 SV_ONLY         = 0x0080
 102 PAGEDESC        = 0x0001
 103 TABLEDESC       = 0x0002
 104 INVALID         = 0x0000
 105 
 106 /* Cache enabling */
 107 I_HALF          = 0x00002000    /* half-cache mode for I-cache ('060) */
 108 I_FREEZE        = 0x00004000    /* freeze I-cache ('060) */
 109 I_ENABLE        = 0x00008000    /* enable I-cache */
 110 BC_CLRU         = 0x00200000    /* clear user entries in branch cache ('060) */
 111 BC_CLRA         = 0x00400000    /* clear all entries in branch cache ('060) */
 112 BC_ENABLE       = 0x00800000    /* enable branch cache ('060) */
 113 D_HALF          = 0x08000000    /* half-cache mode for D-cache ('060) */
 114 PUSH_DPI        = 0x10000000    /* disable CPUSH invalidation ('060) */
 115 SB_ENABLE       = 0x20000000    /* enable store buffer ('060) */
 116 D_FREEZE        = 0x40000000    /* freeze D-cache ('060) */
 117 D_ENABLE        = 0x80000000    /* enable D-cache */
 118 
 119 /* Miscellaneous definitions */
 120 PAGE_MASK       = (~(PAGESIZE-1))
 121 
 122 ROOT_TABLE_SIZE = 128
 123 PTR_TABLE_SIZE  = 128
 124 PAGE_TABLE_SIZE = 64
 125 ROOT_INDEX_SHIFT = 25
 126 PAGE_INDEX_SHIFT = 12
 127 
 128 ENTRY(_stext)
 129 ENTRY(_start)
 130         bras    1f /* Jump over bootinfo version numbers */
 131 /*
 132  * Version numbers of the bootinfo interface
 133  */
 134 
 135         .long   BOOTINFOV_MAGIC
 136         .long   MACH_AMIGA, AMIGA_BOOTI_VERSION
 137         .long   MACH_ATARI, ATARI_BOOTI_VERSION
 138         .long   0
 139 
 140 1:
 141 
 142 /*
 143  * raise interrupt level
 144  */
 145 
 146         movew   #0x2700,%sr
 147 
 148 /*
 149  * Copy bootinfo from position after BSS to final resting place
 150  */
 151         lea     %pc@(SYMBOL_NAME(_end)),%a0
 152         lea     %pc@(SYMBOL_NAME(boot_info)),%a1
 153         movel   %pc@(SYMBOL_NAME(bisize)),%d0
 154         subql   #1,%d0
 155 1:      moveb   %a0@+,%a1@+
 156         dbra    %d0,1b
 157 
 158 /*
 159  * Record the CPU and machine type.
 160  */
 161         lea     %pc@(SYMBOL_NAME(boot_info)),%a0
 162         movel   %a0@(BI_MACH),%d4
 163         movel   %a0@(BI_CPU),%d0
 164         movel   %a0@(BI_CPU),%d6      /* !!!!!!!!!!!!!!!! */
 165 
 166         btst    #BI_BIT060,%d0
 167         beq     1f
 168         /* '060: d6 := BIT0460|BIT060, cache mode 0x60 (no-cache/non-ser) */
 169         movel   #(D6VAL_060+CM_NONCACHE),%d6
 170         bra     2f
 171 1:      btst    #BI_BIT040,%d0
 172         beq     1f
 173         /* '040: d6 := BIT0460, cache mode 0x00 (write-through) */
 174         movel   #(D6VAL_040+CM_CACHE_WT),%d6
 175         bra     2f
 176 1:      /* '020 or '030: d6 := no CPU bit, cache mode unused */
 177         moveq   #0,%d6
 178 
 179 2:      lea     %pc@(SYMBOL_NAME(m68k_pgtable_cachemode)),%a0
 180         movel   %d6,%a0@                /* save cache mode for page tables */
 181         andl    #0x0000ffff,%a0@
 182 
 183 /*
 184  * Initialize serial port
 185  */
 186         jbsr Lserial_init
 187 
 188         moveq   #CR,%d7
 189         jbsr    Lserial_putc
 190         moveq   #LF,%d7
 191         jbsr    Lserial_putc
 192         moveq   #'A',%d7
 193         jbsr    Lserial_putc
 194 
 195 /*
 196  * Get address at end of kernel code/data/bss and
 197  * mask off at a page boundary.
 198  */
 199         lea     %pc@(SYMBOL_NAME(_end)),%a0
 200         movel   %a0,%d0
 201         addl    #(PAGESIZE-1),%d0
 202         andl    #PAGE_MASK,%d0
 203         movel   %d0,%a6
 204 
 205         moveq   #'B',%d7
 206         jbsr    Lserial_putc
 207 
 208 /*
 209  * initialize the kernel root table.
 210  */
 211         lea     %pc@(SYMBOL_NAME(kernel_pg_dir)),%a4
 212         movel   %a4,%a0
 213         moveq   #0,%d0
 214         moveq   #(ROOT_TABLE_SIZE-1),%d1
 215 1:      movel   %d0,%a0@+
 216         dbra    %d1,1b
 217 
 218         /*
 219          * Initialize root table descriptor pointing to the kernel pointer
 220          * table.
 221          */
 222         movel   %a6,%a5
 223         addw    #PAGESIZE,%a6
 224 
 225         movel   %a5,%a0
 226         addql   #TABLEDESC,%a0
 227         movel   %a0,%a4@
 228 
 229         moveq   #'C',%d7
 230         jbsr    Lserial_putc
 231 
 232 /*
 233  * Initialize the pointer tables referred to above.  They either point
 234  * to page tables in the case of the 680[46]0 or contain early
 235  * termination page descriptors in the case of the 68851 or 68030.
 236  *
 237  * Each pointer table entry points to a 64 entry page table.  16 of these
 238  * page tables are grouped to form a single 1024 entry page table which
 239  * fits in a single 4096 byte page.
 240  *
 241  * Some register usages:
 242  *    a0 -> pointer table descriptor address
 243  *    a1 -> pointer table descriptor
 244  *    d1 -> counter
 245  *    d2 -> pointer table descriptor increment (varies according to CPU)
 246  */
 247 
 248         /* clear the kernel pointer table */
 249         movel   %a5,%a0
 250         moveq   #0,%d0
 251         moveq   #(PTR_TABLE_SIZE-1),%d1
 252 1:      movel   %d0,%a0@+
 253         dbra    %d1,1b
 254 
 255         movel   %a5,%a0
 256         moveq   #15,%d1
 257 
 258         /*
 259          * base value of pointer table descriptor is either
 260          * the address of the first page table (680[46]0)
 261          * or the base address of physical memory (68030).
 262          */
 263         btst    #BIT0460,%d6
 264         bne     1f
 265 
 266         /* 680[23]0 */
 267         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a1  /* base address */
 268         addql   #PAGEDESC,%a1   /* descriptor type */
 269         movel   #0x40000,%d2    /* increment */
 270         bra     2f
 271 
 272 1:      /* 680[46]0 */
 273         movel   %a6,%a1         /* base address */
 274         addw    #PAGESIZE,%a6   /* allocate the page table */
 275         lea     %pc@(SYMBOL_NAME(kpt)),%a3
 276         movel   %a1,%a3@                /* save address of page table */
 277         addql   #TABLEDESC,%a1  /* descriptor type */
 278         movel   #256,%d2        /* increment */
 279 
 280 2:      movel   %a1,%a0@+
 281         addl    %d2,%a1
 282         dbra    %d1,2b
 283 
 284         moveq   #'D',%d7
 285         jbsr    Lserial_putc
 286 
 287 /*
 288  * If we are running on a 680[46]0, we have a kernel page table and
 289  * must initialize it.  Make the entries point to the first
 290  * 4M of physical memory (the memory we are residing in).
 291  * Set the cache mode bits to Cacheable, Copyback.  Set the Global bits
 292  * in the descriptors also.
 293  */
 294 
 295         btst    #BIT0460,%d6
 296         jeq     Lnot040
 297 
 298         moveq   #'F',%d7
 299         jbsr    Lserial_putc
 300 
 301         movel   %pc@(SYMBOL_NAME(kpt)),%a0
 302         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a1
 303 
 304         addw    #(GLOBAL+CM_CACHE_CB+PAGEDESC),%a1
 305         movew   #((PAGESIZE/4)-1),%d1
 306         movel   #PAGESIZE,%d2
 307 
 308 1:      movel   %a1,%a0@+
 309         addl    %d2,%a1
 310         dbra    %d1,1b
 311 
 312         /*
 313          * on the 68040, pages used to hold mmu tables should
 314          * be initialized as noncachable; the '060 allows write-through.
 315          * Do this for the root table page (which also contains
 316          * all pointer tables utilitized thus far) and the
 317          * kernel page table.
 318          */
 319         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a0
 320         movel   %a4,%d0         /* address of root table */
 321         subl    %a0,%d0         /* determine offset of root table page */
 322         moveq   #PAGE_INDEX_SHIFT,%d1   /* determine offset into kernel page table */
 323         lsrl    %d1,%d0         /* i.e. page number of the address offset */
 324         movel   %pc@(SYMBOL_NAME(kpt)),%a0
 325         lea     %a0@(%d0:l:4),%a0
 326         movel   %a0@,%d1
 327         andl    #CM_MASK,%d1
 328         orw     %d6,%d1
 329         movel   %d1,%a0@+
 330 
 331         movel   %a0@,%d1        /* do the same for the kernel page table */
 332         bclr    #5,%d1          /* the kernel page table resides in the  */
 333         bset    #6,%d1          /* page after the page containing the    */
 334         movel   %d1,%a0@        /* root table                            */
 335 
 336 Lnot040:
 337 /*
 338  * Do any machine specific page table initializations.
 339  */
 340         moveq   #MACH_AMIGA,%d0
 341         cmpl    %d4,%d0
 342         bne     Lnotami
 343 
 344 /*
 345  * On the Amiga:
 346  * Our current stack (in CHIP ram) may become invalid after the remapping
 347  * of the kernel virtual address space, so set it to point to PAGE_SIZE.
 348  * This will be in CHIP ram until after the remapping, and in the unused
 349  * first page (temporarily) after that.
 350  *
 351  * Setup a mapping of the first 16M of physical address space at virtual
 352  * address 0x80000000, using early termination page descriptors for the
 353  * 68030, and proper page tables for the 680[46]0.  Set this area as
 354  * non-cacheable.
 355  */
 356 
 357         moveq   #'H',%d7
 358         jbsr    Lserial_putc
 359 
 360         move.w  #PAGESIZE,%sp
 361 
 362         btst    #BIT0460,%d6
 363         bne     Lspami68040
 364 
 365 
 366         /*
 367          * for the 68030, just setup a translation to map in the first
 368          * 32M of physical address space at virtual address 0x80000000
 369          * using an early termination page descriptor.
 370          */
 371 
 372         moveq   #'I',%d7
 373         jbsr    Lserial_putc
 374 
 375         moveq   #0x41,%d0
 376         movel   %d0,%a4@(64*4)
 377 
 378         bra     Lmapphys
 379 
 380 Lspami68040:
 381 
 382         /*
 383          * for the 680[46]0, use another pointer table, and allocate 4 more
 384          * page tables.  Initialize the pointer table to point to the
 385          * page tables.  Then initialize the page tables to point to
 386          * the first 16M of memory, with no caching (noncachable/serialized).
 387          */
 388 
 389         /* clear the amiga pointer table */
 390         lea     %a5@(512),%a0
 391         moveq   #0,%d0
 392         moveq   #(PTR_TABLE_SIZE-1),%d1
 393 1:      movel   %d0,%a0@+
 394         dbra    %d1,1b
 395 
 396         /* allocate 4 page tables */
 397         movel   %a6,%a3
 398         addw    #(4*PAGESIZE),%a6
 399 
 400         /* initialize the pointer table */
 401         lea     %a5@(512),%a0
 402         movel   %a3,%a1
 403         addql   #TABLEDESC,%a1  /* base descriptor */
 404         movel   #256,%d2        /* increment */
 405         moveq   #(PAGE_TABLE_SIZE-1),%d1
 406 
 407 1:      movel   %a1,%a0@+
 408         addl    %d2,%a1
 409         dbra    %d1,1b
 410 
 411         /* ensure that the root table points to the pointer table */
 412         lea     %a5@(512),%a0
 413         addql   #TABLEDESC,%a0
 414         movel   %a0,%a4@(256)   /* 0x80000000>>(ROOT_INDEX_SHIFT-2) doesn't
 415                                    work */
 416 
 417         /*
 418          * initialize the page tables
 419          * descriptor bits include noncachable/serialized and global bits.
 420          */
 421         movel   %a3,%a0
 422         movew   #(GLOBAL+CM_NONCACHE_SER+PAGEDESC),%a1
 423         movel   #PAGESIZE,%d2
 424         movew   #PAGESIZE-1,%d1
 425 
 426 1:      movel   %a1,%a0@+
 427         addl    %d2,%a1
 428         dbra    %d1,1b
 429 
 430         /*
 431          * Finally, since we just allocated 4 page tables, make sure that
 432          * the virtual mapping of the 4 page tables indicates
 433          * noncachable/serialized.
 434          */
 435         movel   %a3,%d0         /* ami page table start address */
 436         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a0
 437         subl    %a0,%d0         /* determine offset of root table page */
 438         moveq   #PAGE_INDEX_SHIFT,%d1   /* determine offset into kernel page table */
 439         lsrl    %d1,%d0
 440         movel   %pc@(SYMBOL_NAME(kpt)),%a0
 441         movel   #3,%d2
 442 1:      lea     %a0@(%d0:l:4),%a1
 443         movel   %a1@,%d1
 444         bclr    #5,%d1
 445         bset    #6,%d1
 446         movel   %d1,%a1@
 447         addql   #1,%d0
 448         dbra    %d2,1b
 449 
 450         bra     Lmapphys
 451 
 452 
 453 Lnotami:        /* other machines specific mappings go here! */
 454 
 455         moveq   #MACH_ATARI,%d0
 456         cmpl    %d4,%d0
 457         bne     Lnotatari
 458 
 459         move.w  #PAGESIZE,%sp
 460 
 461 /* On the Atari, we map the I/O region (phys. 0x00ffxxxx) by mapping
 462    the last 16 MB of virtual address space to the first 16 MB (i.e.
 463    0xffxxxxxx -> 0x00xxxxxx). For this, an additional pointer table is
 464    needed. I/O ranges are marked non-cachable.
 465 
 466    For the Medusa it is better to map the I/O region transparently
 467    (i.e. 0xffxxxxxx -> 0xffxxxxxx), because some I/O registers are
 468    accessible only in the high area. The test whether it is a Medusa
 469    is done by writing to the byte at phys. 0x0. This should result
 470    in a bus error on all other machines.
 471 
 472    ...should, but doesn't. The Atferburner040 for the Falcon has the
 473    same behaviour (0x0..0x7 are no ROM shadow). So we have to do
 474    another test to distinuish Medusa and AB040. This is a
 475    read attempt for 0x00ff82fe phys. that should bus error on a Falcon
 476    (+AB040), but is in the range where the Medusa always asserts DTACK.
 477 */
 478 
 479         moveq   #0,%d3                  /* base addr for others: 0x00000000 */
 480         movec   %d3,%vbr
 481         lea         %pc@(Ltest_berr),%a0
 482         movel   %a0,0x8
 483         movel   %sp,%a0
 484         moveb   0x0,%d1
 485         clrb    0x0
 486         nop
 487         moveb   %d1,0x0
 488         nop
 489         tstb    0x00ff82fe
 490         nop
 491         movel   #0xff000000,%d3         /* Medusa base addr: 0xff000000 */
 492 Ltest_berr:
 493         movel   %a0,%sp
 494         lea     %pc@(SYMBOL_NAME(is_medusa)),%a0
 495         movel   %d3,%a0@
 496 
 497         /* Let the root table point to the new pointer table */
 498         lea     %a5@(512),%a0
 499         addl    #TABLEDESC,%a0
 500         movel   %a0,%a4@(508)           /* 0xFE000000 - 0xFFFFFFFF */
 501 
 502         /* clear lower half of the pointer table (0xfexxxxxx) */
 503         lea     %a5@(512),%a0
 504         movel   #0,%d0
 505         movel   #63,%d2
 506 1:      movel   %d0,%a0@+
 507         dbra    %d2,1b
 508 
 509         btst    #BIT0460,%d6
 510         bne     Lspata68040
 511 
 512 /* Mapping of the last 16M of virtual address space to the first 16M
 513    for efficient addressing of hardware registers */
 514         movel   #0x40000,%d1
 515         movel   #63,%d2
 516         movel   %d3,%d0
 517         addl    #PAGEDESC,%d0
 518 1:      movel   %d0,%a0@+
 519         addl    %d1,%d0
 520         dbra    %d2,1b
 521         moveq   #0x40,%d0       /* make non-cachable */
 522         addl    %d0,%a5@(1020)  /* 0xFFFC0000-0xFFFFFFFF (I/O space) */
 523 /* GK: 0xFFF00000-0xFFF3FFFF (IDE-bus) has to be non-cachable too */
 524         addl    %d0,%a5@(1008)
 525 
 526         bra     Lmapphys
 527 
 528 Lspata68040:
 529         /* allocate 4 page tables */
 530         movel   %a6,%a3
 531         addw    #(4*PAGESIZE),%a6
 532 
 533 /* Initialize the upper half of the pointer table (a0 is still valid) */
 534         movel   %a3,%a1
 535         addql   #TABLEDESC,%a1
 536         movel   #256,%d2
 537         moveq   #63,%d1
 538 1:      movel   %a1,%a0@+
 539         addl    %d2,%a1
 540         dbra    %d1,1b
 541 
 542         /* Initialize the page tables as noncacheable/serialized! */
 543         movel   %a3,%a0
 544         movel   %d3,%a1
 545         addw    #(GLOBAL+CM_NONCACHE_SER+PAGEDESC),%a1
 546         movel   #PAGESIZE,%d2
 547         movew   #(PAGESIZE-1),%d1
 548 1:      movel   %a1,%a0@+
 549         addl    %d2,%a1
 550         dbra    %d1,1b
 551 
 552         /*
 553          * Finally, since we just allocated 4 page tables, make sure that
 554          * the virtual mapping of the 4 page tables indicates
 555          * noncachable or write-through.
 556          */
 557         movel   %a3,%d0         /* page table start address */
 558         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a0
 559         subl    %a0,%d0         /* determine offset of root table page */
 560         moveq   #PAGE_INDEX_SHIFT,%d1 /* determine offset into 
 561                                          kernel page table */
 562         lsrl    %d1,%d0
 563         movel   %pc@(SYMBOL_NAME(kpt)),%a0
 564         moveq   #3,%d2
 565 1:      lea     %a0@(%d0:l:4),%a1
 566         movel   %a1@,%d1
 567         andl    #CM_MASK,%d1
 568         orw     %d6,%d1
 569         movel   %d1,%a1@
 570         addql   #1,%d0
 571         dbra    %d2,1b
 572 
 573 Lnotatari:
 574 
 575 /*
 576  * Setup a transparent mapping of the physical memory we are executing in.
 577  *
 578  * Only do this if the physical memory is not in the first 16M Meg, or not on
 579  * an Amiga since the first 16M is already identity mapped on the Amiga.
 580  */
 581 Lmapphys:
 582         moveq   #'J',%d7
 583         jbsr    Lserial_putc
 584 
 585         clrl    %d5             /* indicate that no cleanup is required */
 586 
 587         cmpl    #MACH_AMIGA,%d4
 588         bne     Lmapphysnotamiga        /* other machines will probably have
 589                                          * to put in code and jump to it here
 590                                          */
 591 
 592 /*
 593  * The virtual address of the start of the kernel is 0x1000.  On ALL
 594  * Amigas, there is CHIP RAM in this area.  Hence we will copy the MMU
 595  * enabling code to CHIP RAM (to the same physical address as the kernel
 596  * virtual address) and jump to it.  When the MMU is enabled, we will be
 597  * running from the code in the kernel virtual space, rather than the
 598  * physical space.
 599  */
 600 
 601 /*
 602  * Setup Supervisor Root Pointer register to point to page directory,
 603  * setup translation register contents and enable translation.
 604  */
 605         btst    #BIT0460,%d6
 606         bne     Lamimmu68040
 607 
 608         moveq   #'K',%d7
 609         jbsr    Lserial_putc
 610 
 611         lea     %pc@(mmu),%a0
 612         movel   #0x80000002,%a0@   /* no limit, 4byte descriptors */
 613         movel   %a4,%a0@(4)
 614         pmove   %a0@,%srp
 615         pmove   %a0@,%crp
 616         /*
 617          * enable,super root enable,4096 byte pages,7 bit root index,
 618          * 7 bit pointer index, 6 bit page table index.
 619          */
 620         movel   #0x82c07760,%a0@
 621 
 622         /* setup registers for jumping MMU enabling code */
 623         lea     %pc@(Ldoit030ami),%a2
 624         lea     Ldoit030ami,%a1
 625 
 626         moveq   #CR,%d7
 627         jbsr    Lserial_putc
 628         moveq   #LF,%d7
 629         jbsr    Lserial_putc
 630         movel   %a2,%d7
 631         jbsr    Lserial_putnum
 632         moveq   #' ',%d7
 633         jbsr    Lserial_putc
 634         movel   %a1,%d7
 635         jbsr    Lserial_putnum
 636 
 637         bra     LdoitAmiga
 638 
 639 #ifdef __ELF__
 640         .align  16
 641 #else
 642         .align  4
 643 #endif
 644 Ldoit030ami:
 645         pmove   %a0@,%tc        /* enable the MMU */
 646         jra     LdoneMMUenable  /* branch to continuation of startup */
 647 
 648 Lamimmu68040:
 649         moveq   #'L',%d7
 650         jbsr    Lserial_putc
 651         
 652         .word   0xf4d8          /* CINVA I/D */
 653         .word   0xf518          /* pflusha      */
 654         .long   0x4e7bc807      /* movec a5,srp */
 655         .long   0x4e7bc806      /* movec a5,urp */
 656         movel   #(TC_ENABLE+TC_PAGE4K),%d0
 657 
 658         /* setup registers for jumping MMU enabling code */
 659         lea     Ldoit040ami,%a1
 660         lea     %pc@(Ldoit040ami),%a2
 661         bra     LdoitAmiga
 662 
 663 #ifdef __ELF__
 664         .align  16
 665 #else
 666         .align  4
 667 #endif
 668 Ldoit040ami:
 669         .long   0x4e7b0003      /* movec d0,tc  (enable the MMU) */
 670         jra     LdoneMMUenable  /* branch to continuation of startup */
 671 
 672 LdoitAmiga:
 673         /* copy the appropriate code (two longwords) to chipmem */
 674         movel   %a2@,%a1@
 675         movel   %a2@(4),%a1@(4)
 676 
 677         /*
 678          * save physaddr of phys mem in register a3
 679          */
 680         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a3
 681 
 682         /* jump to the physical address in chipmem */
 683         jmp     %a1@
 684 
 685 Lmapphysnotamiga:
 686 
 687         cmpl    #MACH_ATARI,%d4
 688         bne     Lmapphysnotatari
 689 
 690         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE),%a0
 691         tstl    %a0
 692         jeq     Lnophys2
 693 
 694         /* The kernel physical address is different from its virtual
 695            address.  Temporarily set up an identity mapping of the
 696            16MB chunk where the kernel is executing. */
 697   
 698         /* 680[46]0? */
 699         btst    #BIT0460,%d6
 700         jeq     1f
 701 
 702         /*
 703          * For the 68040, we will use the transparent translation
 704          * registers to identity map the 16M chunk that contains
 705          * the physical memory.
 706          */
 707         movel   %a0,%d2
 708         andl    #0xff000000,%d2         /* logical address base */
 709         orw     #0xc040,%d2             /* add in magic bits */
 710         .long   0x4e7b2004              /* movec d2,ittr0 */
 711         .long   0x4e7b2006              /* movec d2,dttr0 */
 712 
 713         /* d5 is kept 0 to do no cleanup. This didn't work in head.S, I don't
 714          * know why... The transparent translation is turned off in
 715          * atari/config.c instead.
 716          */
 717         jra     Lnophys2
 718 
 719         /* Transparent translation for the 68030 via transparent translation
 720            register */
 721 
 722 1:
 723         /* cleanup is needed; note it */
 724         moveq   #1,%d5
 725 
 726         movel   %a0,%d2
 727         andl    #0xff000000,%d2         /* logical address base */
 728         orw     #0x8143,%d2             /* add in magic bits */
 729         lea     %pc@(mmu),%a0
 730         movel   %d2,%a0@
 731         pmove   %a0@,%tt0
 732 
 733 Lnophys2:
 734         /*
 735          * save physaddr of phys mem in register a3
 736          */
 737         lea     %pc@(SYMBOL_NAME(_stext)-PAGESIZE:w),%a3
 738 
 739         btst    #BIT0460,%d6
 740         jne     Latarimmu68040
 741 
 742         moveq   #'K',%d7
 743         jbsr    Lserial_putc
 744 
 745         lea     %pc@(mmu),%a0
 746         movel   #0x80000002,%a0@   /* no limit, 4byte descriptors */
 747         movel   %a4,%a0@(4)
 748         pmove   %a0@,%srp
 749         pmove   %a0@,%crp
 750         /*
 751          * enable,super root enable,4096 byte pages,7 bit root index,
 752          * 7 bit pointer index, 6 bit page table index.
 753          */
 754         movel   #0x82c07760,%a0@
 755         pmove   %a0@,%tc                /* enable the MMU */
 756 
 757         /* Jump to the virtual address of continuation of startup. */
 758         jmp     LdoneMMUenable
 759 
 760 Latarimmu68040:
 761         moveq   #'L',%d7
 762         jbsr    Lserial_putc
 763 
 764         .word   0xf4d8          /* CINVA I/D */
 765         .word   0xf518          /* pflusha      */
 766         .long   0x4e7bc807      /* movec a4,srp */
 767         .long   0x4e7bc806      /* movec a4,urp */
 768         movel   #(TC_ENABLE+TC_PAGE4K),%d0
 769         /* this value is also ok for the '060, we don't use the cache
 770          * mode/protection defaults */
 771         .long   0x4e7b0003      /* movec d0,tc  (enable the MMU) */
 772         jmp     LdoneMMUenable  /* jump to virtual address of
 773                                    continuation of startup */
 774 
 775 Lmapphysnotatari:
 776 
 777 
 778 LdoneMMUenable:
 779 
 780 /*
 781  * Fixup the addresses for the kernel pointer table and availmem.
 782  * Convert them from physical addresses to virtual addresses.
 783  */
 784 
 785         /*
 786          * fixup the Amiga custom register location before printing
 787          */
 788         addl    #0x80000000,Lcustom
 789 
 790         /* The same for the Atari */
 791         movel   #0xff000000,Liobase
 792 
 793         moveq   #'M',%d7
 794         jbsr    Lserial_putc
 795 
 796         /*
 797          * a3 contains physaddr of kernel start
 798          */
 799         movel   SYMBOL_NAME(kpt),%d1
 800         subl    %a3,%d1
 801         movel   %d1,SYMBOL_NAME(kpt)
 802 
 803         /*
 804          * do the same conversion on the first available memory
 805          * address (in a6).
 806          */
 807         subl    %a3,%a6
 808 
 809         /* Allocate a page to be used by get_kpointer_table.  */
 810         movel   %a6,SYMBOL_NAME(kernel_pmd_table)
 811         addl    #PAGESIZE,%a6
 812         movel   %a6,SYMBOL_NAME(availmem) /* first available memory address */
 813 
 814         moveq   #'N',%d7
 815         jbsr    Lserial_putc
 816 
 817         /*
 818          * Clean up the temporary physical mapping (if necessary)
 819          */
 820 
 821         tstl    %d5
 822         jeq     Lnoclean
 823 
 824         btst    #BIT0460,%d6
 825         jne     Loff040
 826 
 827         /* clean up physical identity mapping for 68020/68030 */
 828         /* Is this needed for the Amiga anymore? */
 829         /* it's not in 1.2.13pl6 - Jes */
 830         cmpl    #MACH_AMIGA,%d4
 831         jeq     Lclean030
 832         cmpl    #MACH_ATARI,%d4
 833         jne     Lnoclean
 834 
 835         /* clear transparent translation register */
 836         lea     %pc@(mmu),%a0
 837         clrl    %a0@
 838         pmove   %a0@,%tt0
 839         jra     Lnoclean
 840 
 841 Lclean030:
 842         movel   %a0,%d2         /* a0 contains physical start address */
 843         moveq   #25,%d3         /* find appropriate index in root table */
 844         lsrl    %d3,%d2
 845         moveq   #0,%d0
 846         movel   %d0,%a4@(%d2:l:4)  /* clear descriptor */
 847 
 848         jra     Lnoclean
 849 
 850 Loff040:
 851         /* turn off transparent translation registers for '0[46]0 */
 852         moveq   #0,%d0
 853         .long   0x4e7b0004      /* movec d0,ittr0 */
 854         .long   0x4e7b0006      /* movec d0,dttr0 */
 855 
 856 Lnoclean:
 857         moveq   #'O',%d7
 858         jbsr    Lserial_putc
 859 
 860 
 861 /*
 862  * Enable caches
 863  */
 864         btst    #BIT0460,%d6
 865         jne     Lcache680460
 866 
 867         movel   #0x00001919,%d0
 868         movec   %d0,%cacr
 869         jra     1f
 870 
 871 Lcache680460:
 872         btst    #BIT060,%d6
 873         jne     Lcache68060
 874 
 875         .word   0xf4d8       /* CINVA I/D */
 876         movel   #I_ENABLE+D_ENABLE,%d0
 877         /* MMU stuff works in copyback mode now, so enable the cache */
 878         movec   %d0,%cacr
 879         jra     1f
 880 
 881 Lcache68060:
 882         .word   0xf4d8       /* CINVA I/D */
 883         movel   #I_ENABLE+D_ENABLE+SB_ENABLE+PUSH_DPI+BC_ENABLE+BC_CLRA,%d0
 884         /* MMU stuff works in copyback mode now, so enable the cache */
 885         movec   %d0,%cacr
 886         /* enable superscalar dispatch in PCR */
 887         moveq   #1,%d0
 888         .long   0x4e7b0808      /* movec d0,pcr */
 889 
 890 1:
 891 
 892 /*
 893  * Setup initial stack pointer
 894  */
 895         lea     SYMBOL_NAME(init_user_stack)+PAGESIZE,%sp
 896 
 897 /* jump to the kernel start */
 898 
 899         jbsr    SYMBOL_NAME(start_kernel)
 900 
 901 #if 0
 902 tmp_fault_handler:
 903      lea       %pc@(tfh_1st_str),%a0
 904      jbsr       Lserial_puts
 905      move.l    %sp@(2),%d7                     /* PC */
 906      jbsr       Lserial_putnum
 907      move.w    %sp@(0xa),%d7
 908      swap      %d7
 909      move.w    %sp@(0x6),%d7
 910      jbsr       Lserial_putnum
 911      lea       %pc@(tfh_2nd_str),%a0
 912      jbsr       Lserial_puts
 913      move.l    %sp@(0x10),%d7                  /* Fault address */
 914      jbsr       Lserial_putnum
 915      moveq     #CR,%d7
 916      jbsr       Lserial_putc
 917      moveq     #LF,%d7
 918      jbsr       Lserial_putc
 919 1:   jra       1b
 920 
 921 tfh_1st_str:
 922      .byte     CR
 923      .byte     LF
 924      .ascii    "Access fault occurred. PC = "
 925      .byte     0
 926 
 927 tfh_2nd_str:
 928      .byte     CR
 929      .byte     LF
 930      .ascii    "FaultAddress = "
 931      .byte     0
 932 #endif
 933 
 934 /*
 935  * Serial port output support.
 936  */
 937 LSERPER      = 0xdff032
 938 LSERDAT      = 0xdff030
 939 LSERDATR     = 0xdff018
 940 LNTSC_PERIOD = 371
 941 LPAL_PERIOD  = 368/2        /* /2 for 19200 baud */
 942 LNTSC_ECLOCK = 7159090
 943 LSERIAL_CNTRL = 0xbfd000
 944 LSERIAL_DTR   = 7
 945 
 946 /*
 947  * Debug output support
 948  * Atarians have a choice between the parallel port, the serial port
 949  * from the MFP or a serial port of the SCC
 950  */
 951 
 952 /* #define USE_PRINTER */
 953 /* #define USE_SCC */
 954 #define USE_MFP
 955 
 956 #ifdef USE_PRINTER
 957 
 958 LPSG_SELECT     = 0xff8800
 959 LPSG_READ       = 0xff8800
 960 LPSG_WRITE      = 0xff8802
 961 LPSG_IO_A       = 14
 962 LPSG_IO_B       = 15
 963 LPSG_CONTROL    = 7
 964 LSTMFP_GPIP     = 0xfffa01
 965 LSTMFP_DDR      = 0xfffa05
 966 LSTMFP_IERB     = 0xfffa09
 967 
 968 #elif defined(USE_SCC)
 969  
 970 LSCC_CTRL_B     = 0xff8c85
 971 LSCC_DATA_B     = 0xff8c87
 972 
 973 /* Initialisation table for SCC */
 974 scc_initable:
 975         .byte   9,12            /* Reset */
 976         .byte   4,0x44          /* x16, 1 stopbit, no parity */
 977         .byte   3,0xc0          /* receiver: 8 bpc */
 978         .byte   5,0xe2          /* transmitter: 8 bpc, assert dtr/rts */
 979         .byte   9,0             /* no interrupts */
 980         .byte   10,0            /* NRZ */
 981         .byte   11,0x50         /* use baud rate generator */
 982         .byte   12,24,13,0      /* 9600 baud */
 983         .byte   14,2,14,3       /* use master clock for BRG, enable */
 984         .byte   3,0xc1          /* enable receiver */
 985         .byte   5,0xea          /* enable transmitter */
 986         .byte   -1
 987         .even
 988 
 989 #elif defined(USE_MFP)
 990 
 991 LMFP_UCR     = 0xfffa29
 992 LMFP_TDCDR   = 0xfffa1d
 993 LMFP_TDDR    = 0xfffa25
 994 LMFP_TSR     = 0xfffa2d
 995 LMFP_UDR     = 0xfffa2f
 996 
 997 #endif
 998 
 999 /*
1000  * Initialize serial port hardware for 9600/8/1
1001  * a0 thrashed
1002  * Atari d0 trashed (a1 in case of SCC)
1003  */
1004         .even
1005 Lserial_init:
1006         cmpil   #MACH_AMIGA,%d4
1007         jne     1f
1008         bclr    #LSERIAL_DTR,LSERIAL_CNTRL
1009         movew   #LNTSC_PERIOD,LSERPER
1010         cmpl    #LNTSC_ECLOCK,%a0@(BI_AMIGA_ECLK)
1011         jeq     9f
1012         movew   #LPAL_PERIOD,LSERPER
1013         jra     9f
1014 1:      cmpil   #MACH_ATARI,%d4
1015         jne     9f
1016 #ifdef USE_PRINTER
1017         bclr    #0,LSTMFP_IERB
1018         bclr    #0,LSTMFP_DDR
1019         moveb   #LPSG_CONTROL,LPSG_SELECT
1020         moveb   #0xff,LPSG_WRITE
1021         moveb   #LPSG_IO_B,LPSG_SELECT
1022         clrb    LPSG_WRITE
1023         moveb   #LPSG_IO_A,LPSG_SELECT
1024         moveb   LPSG_READ,%d0
1025         bset    #5,%d0
1026         moveb   %d0,LPSG_WRITE
1027 #elif defined(USE_SCC)
1028         lea     LSCC_CTRL_B,%a0
1029         lea     %pc@(scc_initable:w),%a1
1030 2:      moveb   %a1@+,%d0
1031         jmi     3f
1032         moveb   %d0,%a0@
1033         moveb   %a1@+,%a0@
1034         jra     2b
1035 3:      clrb    %a0@
1036 #elif defined(USE_MFP)
1037         bclr    #1,LMFP_TSR
1038         moveb   #0x88,LMFP_UCR
1039         andb    #0x70,LMFP_TDCDR
1040         moveb   #2,LMFP_TDDR
1041         orb     #1,LMFP_TDCDR
1042         bset    #1,LMFP_TSR
1043 #endif
1044 9:
1045         rts
1046 
1047 /*
1048  * Output character in d7 on serial port.
1049  * d7 thrashed.
1050  */
1051 Lserial_putc:
1052         moveml  %a0/%a1,%sp@-
1053         cmpil   #MACH_AMIGA,%d4
1054         jne     2f
1055         andw    #0x00ff,%d7
1056         oriw    #0x0100,%d7
1057         movel   %pc@(Lcustom),%a1
1058         movew   %d7,%a1@(LSERDAT)
1059 1:      movew   %a1@(LSERDATR),%d7
1060         andw    #0x2000,%d7
1061         jeq     1b
1062         jra     9f
1063 2:      cmpil   #MACH_ATARI,%d4
1064         jne     9f
1065         movel   %pc@(Liobase),%a1
1066 #ifdef USE_PRINTER
1067 3:      btst    #0,%a1@(LSTMFP_GPIP)
1068         jne     3b
1069         moveb   #LPSG_IO_B,%a1@(LPSG_SELECT)
1070         moveb   %d7,%a1@(LPSG_WRITE)
1071         moveb   #LPSG_IO_A,%a1@(LPSG_SELECT)
1072         moveb   %a1@(LPSG_READ),%d7
1073         bclr    #5,%d7
1074         moveb   %d7,%a1@(LPSG_WRITE)
1075         nop
1076         nop
1077         bset    #5,%d7
1078         moveb   %d7,%a1@(LPSG_WRITE)
1079 #elif defined(USE_SCC)
1080 3:      btst    #2,%a1@(LSCC_CTRL_B)
1081         jeq     3b
1082         moveb   %d7,%a1@(LSCC_DATA_B)
1083 #elif defined(USE_MFP)
1084 3:      btst    #7,%a1@(LMFP_TSR)
1085         jeq     3b
1086         moveb   %d7,%a1@(LMFP_UDR)
1087 #endif
1088 9:
1089         moveml  %sp@+,%a0/%a1
1090         rts
1091 
1092 /*
1093  * Output string pointed to by a0 to serial port.
1094  * a0 trashed.
1095  */
1096 Lserial_puts:
1097         movel   %d7,%sp@-
1098 1:      moveb   %a0@+,%d7
1099         jeq     2f
1100         jbsr    Lserial_putc
1101         jra     1b
1102 2:      movel   %sp@+,%d7
1103         rts
1104 
1105 /*
1106  * Output number in d7 in hex notation on serial port.
1107  * d0-d2 trashed.
1108  * d7 trashed.
1109  */
1110 
1111 Lserial_putnum:
1112         moveml  %d0-%d2/%d7,%sp@-
1113         movel   %d7,%d1
1114         moveq   #4,%d0
1115         moveq   #7,%d2
1116 L1:     roll    %d0,%d1
1117         moveb   %d1,%d7
1118         andb    #0x0f,%d7
1119         cmpb    #0x0a,%d7
1120         bccs    1f
1121         addb    #'0',%d7
1122         jra     2f
1123 1:      addb    #'A'-10,%d7
1124 2:      jbsr    Lserial_putc
1125         dbra    %d2,L1
1126         moveq   #32,%d7
1127         jbsr    Lserial_putc
1128         moveml  %sp@+,%d0-%d2/%d7
1129         rts
1130 #if 0
1131 .globl showtest
1132 showtest:
1133         moveml  %a1/%d7,%sp@-
1134         moveq   #'A',%d7
1135         jbsr    Lserial_putc
1136         moveq   #'=',%d7
1137         jbsr    Lserial_putc
1138         movel   %a0,%d7
1139         jbsr    Lserial_putnum
1140 
1141         ptestr  #5,%a0@,#7,%a1
1142 
1143         moveq   #'D',%d7
1144         jbsr    Lserial_putc
1145         moveq   #'A',%d7
1146         jbsr    Lserial_putc
1147         moveq   #'=',%d7
1148         jbsr    Lserial_putc
1149 
1150         movel   %a1,%d7
1151         jbsr    Lserial_putnum
1152 
1153         moveq   #'D',%d7
1154         jbsr    Lserial_putc
1155         moveq   #'=',%d7
1156         jbsr    Lserial_putc
1157         movel   %a1@,%d7
1158         jbsr    Lserial_putnum
1159 
1160         moveq   #'S',%d7
1161         jbsr    Lserial_putc
1162         moveq   #'=',%d7
1163         jbsr    Lserial_putc
1164 
1165         lea     %pc@(mmu),%a1
1166         pmove   %psr,%a1@
1167         clrl    %d7
1168         movew   %a1@,%d7
1169         jbsr    Lserial_putnum
1170 
1171         moveq   #CR,%d7
1172         jbsr    Lserial_putc
1173         moveq   #LF,%d7
1174         jbsr    Lserial_putc
1175 
1176         moveml  %sp@+,%a1/%d7
1177         rts
1178 #endif
1179 
1180         .align 512      /*
1181                          * MMU root-pointers need to be 512-byte
1182                          * aligned on the 680[46]0 - Jes
1183                          */
1184 
1185 SYMBOL_NAME_LABEL(swapper_pg_dir)
1186         .skip ROOT_TABLE_SIZE * 4
1187 SYMBOL_NAME_LABEL(kernel_pg_dir)
1188         .skip ROOT_TABLE_SIZE * 4
1189 
1190         .data
1191         .even
1192 Lcustom:
1193         .long 0
1194 Liobase:
1195         .long 0
1196 mmu:    .quad 0
1197 SYMBOL_NAME_LABEL(kernel_pmd_table)
1198         .long 0
1199 SYMBOL_NAME_LABEL(kpt)
1200         .long 0
1201 SYMBOL_NAME_LABEL(availmem)
1202         .long 0
1203 SYMBOL_NAME_LABEL(is_medusa)
1204         .long 0
1205 SYMBOL_NAME_LABEL(m68k_pgtable_cachemode)
1206         .long 0

/* [previous][next][first][last][top][bottom][index][help] */