OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [arch/] [m68k/] [kernel/] [head.S] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.