xref: /linux/arch/m68k/atari/config.c (revision 5e8d780d745c1619aba81fe7166c5a4b5cad2b84)
1 /*
2  *  linux/arch/m68k/atari/config.c
3  *
4  *  Copyright (C) 1994 Bjoern Brauel
5  *
6  *  5/2/94 Roman Hodek:
7  *    Added setting of time_adj to get a better clock.
8  *
9  *  5/14/94 Roman Hodek:
10  *    gettod() for TT
11  *
12  *  5/15/94 Roman Hodek:
13  *    hard_reset_now() for Atari (and others?)
14  *
15  *  94/12/30 Andreas Schwab:
16  *    atari_sched_init fixed to get precise clock.
17  *
18  * This file is subject to the terms and conditions of the GNU General Public
19  * License.  See the file COPYING in the main directory of this archive
20  * for more details.
21  */
22 
23 /*
24  * Miscellaneous atari stuff
25  */
26 
27 #include <linux/config.h>
28 #include <linux/types.h>
29 #include <linux/mm.h>
30 #include <linux/console.h>
31 #include <linux/init.h>
32 #include <linux/delay.h>
33 #include <linux/ioport.h>
34 #include <linux/vt_kern.h>
35 
36 #include <asm/bootinfo.h>
37 #include <asm/setup.h>
38 #include <asm/atarihw.h>
39 #include <asm/atariints.h>
40 #include <asm/atari_stram.h>
41 #include <asm/system.h>
42 #include <asm/machdep.h>
43 #include <asm/hwtest.h>
44 #include <asm/io.h>
45 
46 u_long atari_mch_cookie;
47 u_long atari_mch_type;
48 struct atari_hw_present atari_hw_present;
49 u_long atari_switches;
50 int atari_dont_touch_floppy_select;
51 int atari_rtc_year_offset;
52 
53 /* local function prototypes */
54 static void atari_reset( void );
55 static void atari_get_model(char *model);
56 static int atari_get_hardware_list(char *buffer);
57 
58 /* atari specific irq functions */
59 extern void atari_init_IRQ (void);
60 extern void atari_mksound( unsigned int count, unsigned int ticks );
61 #ifdef CONFIG_HEARTBEAT
62 static void atari_heartbeat( int on );
63 #endif
64 
65 /* atari specific timer functions (in time.c) */
66 extern void atari_sched_init(irqreturn_t (*)(int, void *, struct pt_regs *));
67 extern unsigned long atari_gettimeoffset (void);
68 extern int atari_mste_hwclk (int, struct rtc_time *);
69 extern int atari_tt_hwclk (int, struct rtc_time *);
70 extern int atari_mste_set_clock_mmss (unsigned long);
71 extern int atari_tt_set_clock_mmss (unsigned long);
72 
73 /* atari specific debug functions (in debug.c) */
74 extern void atari_debug_init(void);
75 
76 
77 /* I've moved hwreg_present() and hwreg_present_bywrite() out into
78  * mm/hwtest.c, to avoid having multiple copies of the same routine
79  * in the kernel [I wanted them in hp300 and they were already used
80  * in the nubus code. NB: I don't have an Atari so this might (just
81  * conceivably) break something.
82  * I've preserved the #if 0 version of hwreg_present_bywrite() here
83  * for posterity.
84  *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk>, 05/1998
85  */
86 
87 #if 0
88 static int __init
89 hwreg_present_bywrite(volatile void *regp, unsigned char val)
90 {
91     int		ret;
92     long	save_sp, save_vbr;
93     static long tmp_vectors[3] = { [2] = (long)&&after_test };
94 
95     __asm__ __volatile__
96 	(	"movec	%/vbr,%2\n\t"	/* save vbr value            */
97                 "movec	%4,%/vbr\n\t"	/* set up temporary vectors  */
98 		"movel	%/sp,%1\n\t"	/* save sp                   */
99 		"moveq	#0,%0\n\t"	/* assume not present        */
100 		"moveb	%5,%3@\n\t"	/* write the hardware reg    */
101 		"cmpb	%3@,%5\n\t"	/* compare it                */
102 		"seq	%0"		/* comes here only if reg    */
103                                         /* is present                */
104 		: "=d&" (ret), "=r&" (save_sp), "=r&" (save_vbr)
105 		: "a" (regp), "r" (tmp_vectors), "d" (val)
106                 );
107   after_test:
108     __asm__ __volatile__
109       (	"movel	%0,%/sp\n\t"		/* restore sp                */
110         "movec	%1,%/vbr"			/* restore vbr               */
111         : : "r" (save_sp), "r" (save_vbr) : "sp"
112 	);
113 
114     return( ret );
115 }
116 #endif
117 
118 
119 /* ++roman: This is a more elaborate test for an SCC chip, since the plain
120  * Medusa board generates DTACK at the SCC's standard addresses, but a SCC
121  * board in the Medusa is possible. Also, the addresses where the ST_ESCC
122  * resides generate DTACK without the chip, too.
123  * The method is to write values into the interrupt vector register, that
124  * should be readable without trouble (from channel A!).
125  */
126 
127 static int __init scc_test( volatile char *ctla )
128 {
129 	if (!hwreg_present( ctla ))
130 		return( 0 );
131 	MFPDELAY();
132 
133 	*ctla = 2; MFPDELAY();
134 	*ctla = 0x40; MFPDELAY();
135 
136 	*ctla = 2; MFPDELAY();
137 	if (*ctla != 0x40) return( 0 );
138 	MFPDELAY();
139 
140 	*ctla = 2; MFPDELAY();
141 	*ctla = 0x60; MFPDELAY();
142 
143 	*ctla = 2; MFPDELAY();
144 	if (*ctla != 0x60) return( 0 );
145 
146 	return( 1 );
147 }
148 
149 
150     /*
151      *  Parse an Atari-specific record in the bootinfo
152      */
153 
154 int __init atari_parse_bootinfo(const struct bi_record *record)
155 {
156     int unknown = 0;
157     const u_long *data = record->data;
158 
159     switch (record->tag) {
160 	case BI_ATARI_MCH_COOKIE:
161 	    atari_mch_cookie = *data;
162 	    break;
163 	case BI_ATARI_MCH_TYPE:
164 	    atari_mch_type = *data;
165 	    break;
166 	default:
167 	    unknown = 1;
168     }
169     return(unknown);
170 }
171 
172 
173 /* Parse the Atari-specific switches= option. */
174 void __init atari_switches_setup( const char *str, unsigned len )
175 {
176     char switches[len+1];
177     char *p;
178     int ovsc_shift;
179     char *args = switches;
180 
181     /* copy string to local array, strsep works destructively... */
182     strlcpy( switches, str, sizeof(switches) );
183     atari_switches = 0;
184 
185     /* parse the options */
186     while ((p = strsep(&args, ",")) != NULL) {
187 	if (!*p) continue;
188 	ovsc_shift = 0;
189 	if (strncmp( p, "ov_", 3 ) == 0) {
190 	    p += 3;
191 	    ovsc_shift = ATARI_SWITCH_OVSC_SHIFT;
192 	}
193 
194 	if (strcmp( p, "ikbd" ) == 0) {
195 	    /* RTS line of IKBD ACIA */
196 	    atari_switches |= ATARI_SWITCH_IKBD << ovsc_shift;
197 	}
198 	else if (strcmp( p, "midi" ) == 0) {
199 	    /* RTS line of MIDI ACIA */
200 	    atari_switches |= ATARI_SWITCH_MIDI << ovsc_shift;
201 	}
202 	else if (strcmp( p, "snd6" ) == 0) {
203 	    atari_switches |= ATARI_SWITCH_SND6 << ovsc_shift;
204 	}
205 	else if (strcmp( p, "snd7" ) == 0) {
206 	    atari_switches |= ATARI_SWITCH_SND7 << ovsc_shift;
207 	}
208     }
209 }
210 
211 
212     /*
213      *  Setup the Atari configuration info
214      */
215 
216 void __init config_atari(void)
217 {
218     unsigned short tos_version;
219 
220     memset(&atari_hw_present, 0, sizeof(atari_hw_present));
221 
222     atari_debug_init();
223 
224     ioport_resource.end  = 0xFFFFFFFF;  /* Change size of I/O space from 64KB
225                                            to 4GB. */
226 
227     mach_sched_init      = atari_sched_init;
228     mach_init_IRQ        = atari_init_IRQ;
229     mach_get_model	 = atari_get_model;
230     mach_get_hardware_list = atari_get_hardware_list;
231     mach_gettimeoffset   = atari_gettimeoffset;
232     mach_reset           = atari_reset;
233     mach_max_dma_address = 0xffffff;
234 #if defined(CONFIG_INPUT_M68K_BEEP) || defined(CONFIG_INPUT_M68K_BEEP_MODULE)
235     mach_beep          = atari_mksound;
236 #endif
237 #ifdef CONFIG_HEARTBEAT
238     mach_heartbeat = atari_heartbeat;
239 #endif
240 
241     /* Set switches as requested by the user */
242     if (atari_switches & ATARI_SWITCH_IKBD)
243 	acia.key_ctrl = ACIA_DIV64 | ACIA_D8N1S | ACIA_RHTID;
244     if (atari_switches & ATARI_SWITCH_MIDI)
245 	acia.mid_ctrl = ACIA_DIV16 | ACIA_D8N1S | ACIA_RHTID;
246     if (atari_switches & (ATARI_SWITCH_SND6|ATARI_SWITCH_SND7)) {
247 	sound_ym.rd_data_reg_sel = 14;
248 	sound_ym.wd_data = sound_ym.rd_data_reg_sel |
249 			   ((atari_switches&ATARI_SWITCH_SND6) ? 0x40 : 0) |
250 			   ((atari_switches&ATARI_SWITCH_SND7) ? 0x80 : 0);
251     }
252 
253     /* ++bjoern:
254      * Determine hardware present
255      */
256 
257     printk( "Atari hardware found: " );
258     if (MACH_IS_MEDUSA || MACH_IS_HADES) {
259         /* There's no Atari video hardware on the Medusa, but all the
260          * addresses below generate a DTACK so no bus error occurs! */
261     }
262     else if (hwreg_present( f030_xreg )) {
263 	ATARIHW_SET(VIDEL_SHIFTER);
264         printk( "VIDEL " );
265         /* This is a temporary hack: If there is Falcon video
266          * hardware, we assume that the ST-DMA serves SCSI instead of
267          * ACSI. In the future, there should be a better method for
268          * this...
269          */
270 	ATARIHW_SET(ST_SCSI);
271         printk( "STDMA-SCSI " );
272     }
273     else if (hwreg_present( tt_palette )) {
274 	ATARIHW_SET(TT_SHIFTER);
275         printk( "TT_SHIFTER " );
276     }
277     else if (hwreg_present( &shifter.bas_hi )) {
278         if (hwreg_present( &shifter.bas_lo ) &&
279 	    (shifter.bas_lo = 0x0aau, shifter.bas_lo == 0x0aau)) {
280 	    ATARIHW_SET(EXTD_SHIFTER);
281             printk( "EXTD_SHIFTER " );
282         }
283         else {
284 	    ATARIHW_SET(STND_SHIFTER);
285             printk( "STND_SHIFTER " );
286         }
287     }
288     if (hwreg_present( &mfp.par_dt_reg )) {
289 	ATARIHW_SET(ST_MFP);
290         printk( "ST_MFP " );
291     }
292     if (hwreg_present( &tt_mfp.par_dt_reg )) {
293 	ATARIHW_SET(TT_MFP);
294         printk( "TT_MFP " );
295     }
296     if (hwreg_present( &tt_scsi_dma.dma_addr_hi )) {
297 	ATARIHW_SET(SCSI_DMA);
298         printk( "TT_SCSI_DMA " );
299     }
300     if (!MACH_IS_HADES && hwreg_present( &st_dma.dma_hi )) {
301 	ATARIHW_SET(STND_DMA);
302         printk( "STND_DMA " );
303     }
304     if (MACH_IS_MEDUSA || /* The ST-DMA address registers aren't readable
305 			   * on all Medusas, so the test below may fail */
306         (hwreg_present( &st_dma.dma_vhi ) &&
307          (st_dma.dma_vhi = 0x55) && (st_dma.dma_hi = 0xaa) &&
308          st_dma.dma_vhi == 0x55 && st_dma.dma_hi == 0xaa &&
309          (st_dma.dma_vhi = 0xaa) && (st_dma.dma_hi = 0x55) &&
310          st_dma.dma_vhi == 0xaa && st_dma.dma_hi == 0x55)) {
311 	ATARIHW_SET(EXTD_DMA);
312         printk( "EXTD_DMA " );
313     }
314     if (hwreg_present( &tt_scsi.scsi_data )) {
315 	ATARIHW_SET(TT_SCSI);
316         printk( "TT_SCSI " );
317     }
318     if (hwreg_present( &sound_ym.rd_data_reg_sel )) {
319 	ATARIHW_SET(YM_2149);
320         printk( "YM2149 " );
321     }
322     if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
323 	hwreg_present( &tt_dmasnd.ctrl )) {
324 	ATARIHW_SET(PCM_8BIT);
325         printk( "PCM " );
326     }
327     if (!MACH_IS_HADES && hwreg_present( &falcon_codec.unused5 )) {
328 	ATARIHW_SET(CODEC);
329         printk( "CODEC " );
330     }
331     if (hwreg_present( &dsp56k_host_interface.icr )) {
332 	ATARIHW_SET(DSP56K);
333         printk( "DSP56K " );
334     }
335     if (hwreg_present( &tt_scc_dma.dma_ctrl ) &&
336 #if 0
337 	/* This test sucks! Who knows some better? */
338 	(tt_scc_dma.dma_ctrl = 0x01, (tt_scc_dma.dma_ctrl & 1) == 1) &&
339 	(tt_scc_dma.dma_ctrl = 0x00, (tt_scc_dma.dma_ctrl & 1) == 0)
340 #else
341 	!MACH_IS_MEDUSA && !MACH_IS_HADES
342 #endif
343 	) {
344 	ATARIHW_SET(SCC_DMA);
345         printk( "SCC_DMA " );
346     }
347     if (scc_test( &scc.cha_a_ctrl )) {
348 	ATARIHW_SET(SCC);
349         printk( "SCC " );
350     }
351     if (scc_test( &st_escc.cha_b_ctrl )) {
352 	ATARIHW_SET( ST_ESCC );
353 	printk( "ST_ESCC " );
354     }
355     if (MACH_IS_HADES)
356     {
357         ATARIHW_SET( VME );
358         printk( "VME " );
359     }
360     else if (hwreg_present( &tt_scu.sys_mask )) {
361 	ATARIHW_SET(SCU);
362 	/* Assume a VME bus if there's a SCU */
363 	ATARIHW_SET( VME );
364         printk( "VME SCU " );
365     }
366     if (hwreg_present( (void *)(0xffff9210) )) {
367 	ATARIHW_SET(ANALOG_JOY);
368         printk( "ANALOG_JOY " );
369     }
370     if (!MACH_IS_HADES && hwreg_present( blitter.halftone )) {
371 	ATARIHW_SET(BLITTER);
372         printk( "BLITTER " );
373     }
374     if (hwreg_present((void *)0xfff00039)) {
375 	ATARIHW_SET(IDE);
376         printk( "IDE " );
377     }
378 #if 1 /* This maybe wrong */
379     if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
380 	hwreg_present( &tt_microwire.data ) &&
381 	hwreg_present( &tt_microwire.mask ) &&
382 	(tt_microwire.mask = 0x7ff,
383 	 udelay(1),
384 	 tt_microwire.data = MW_LM1992_PSG_HIGH | MW_LM1992_ADDR,
385 	 udelay(1),
386 	 tt_microwire.data != 0)) {
387 	ATARIHW_SET(MICROWIRE);
388 	while (tt_microwire.mask != 0x7ff) ;
389         printk( "MICROWIRE " );
390     }
391 #endif
392     if (hwreg_present( &tt_rtc.regsel )) {
393 	ATARIHW_SET(TT_CLK);
394         printk( "TT_CLK " );
395         mach_hwclk = atari_tt_hwclk;
396         mach_set_clock_mmss = atari_tt_set_clock_mmss;
397     }
398     if (!MACH_IS_HADES && hwreg_present( &mste_rtc.sec_ones)) {
399 	ATARIHW_SET(MSTE_CLK);
400         printk( "MSTE_CLK ");
401         mach_hwclk = atari_mste_hwclk;
402         mach_set_clock_mmss = atari_mste_set_clock_mmss;
403     }
404     if (!MACH_IS_MEDUSA && !MACH_IS_HADES &&
405 	hwreg_present( &dma_wd.fdc_speed ) &&
406 	hwreg_write( &dma_wd.fdc_speed, 0 )) {
407 	    ATARIHW_SET(FDCSPEED);
408 	    printk( "FDC_SPEED ");
409     }
410     if (!MACH_IS_HADES && !ATARIHW_PRESENT(ST_SCSI)) {
411 	ATARIHW_SET(ACSI);
412         printk( "ACSI " );
413     }
414     printk("\n");
415 
416     if (CPU_IS_040_OR_060)
417         /* Now it seems to be safe to turn of the tt0 transparent
418          * translation (the one that must not be turned off in
419          * head.S...)
420          */
421         __asm__ volatile ("moveq #0,%/d0\n\t"
422                           ".chip 68040\n\t"
423 			  "movec %%d0,%%itt0\n\t"
424 			  "movec %%d0,%%dtt0\n\t"
425 			  ".chip 68k"
426 						  : /* no outputs */
427 						  : /* no inputs */
428 						  : "d0");
429 
430     /* allocator for memory that must reside in st-ram */
431     atari_stram_init ();
432 
433     /* Set up a mapping for the VMEbus address region:
434      *
435      * VME is either at phys. 0xfexxxxxx (TT) or 0xa00000..0xdfffff
436      * (MegaSTE) In both cases, the whole 16 MB chunk is mapped at
437      * 0xfe000000 virt., because this can be done with a single
438      * transparent translation. On the 68040, lots of often unused
439      * page tables would be needed otherwise. On a MegaSTE or similar,
440      * the highest byte is stripped off by hardware due to the 24 bit
441      * design of the bus.
442      */
443 
444     if (CPU_IS_020_OR_030) {
445         unsigned long	tt1_val;
446         tt1_val = 0xfe008543;	/* Translate 0xfexxxxxx, enable, cache
447                                  * inhibit, read and write, FDC mask = 3,
448                                  * FDC val = 4 -> Supervisor only */
449         __asm__ __volatile__ ( ".chip 68030\n\t"
450 				"pmove	%0@,%/tt1\n\t"
451 				".chip 68k"
452 				: : "a" (&tt1_val) );
453     }
454     else {
455         __asm__ __volatile__
456             ( "movel %0,%/d0\n\t"
457 	      ".chip 68040\n\t"
458 	      "movec %%d0,%%itt1\n\t"
459 	      "movec %%d0,%%dtt1\n\t"
460 	      ".chip 68k"
461               :
462               : "g" (0xfe00a040)	/* Translate 0xfexxxxxx, enable,
463                                          * supervisor only, non-cacheable/
464                                          * serialized, writable */
465               : "d0" );
466 
467     }
468 
469     /* Fetch tos version at Physical 2 */
470     /* We my not be able to access this address if the kernel is
471        loaded to st ram, since the first page is unmapped.  On the
472        Medusa this is always the case and there is nothing we can do
473        about this, so we just assume the smaller offset.  For the TT
474        we use the fact that in head.S we have set up a mapping
475        0xFFxxxxxx -> 0x00xxxxxx, so that the first 16MB is accessible
476        in the last 16MB of the address space. */
477     tos_version = (MACH_IS_MEDUSA || MACH_IS_HADES) ?
478 		  0xfff : *(unsigned short *)0xff000002;
479     atari_rtc_year_offset = (tos_version < 0x306) ? 70 : 68;
480 }
481 
482 #ifdef CONFIG_HEARTBEAT
483 static void atari_heartbeat( int on )
484 {
485     unsigned char tmp;
486     unsigned long flags;
487 
488     if (atari_dont_touch_floppy_select)
489 	return;
490 
491     local_irq_save(flags);
492     sound_ym.rd_data_reg_sel = 14; /* Select PSG Port A */
493     tmp = sound_ym.rd_data_reg_sel;
494     sound_ym.wd_data = on ? (tmp & ~0x02) : (tmp | 0x02);
495     local_irq_restore(flags);
496 }
497 #endif
498 
499 /* ++roman:
500  *
501  * This function does a reset on machines that lack the ability to
502  * assert the processor's _RESET signal somehow via hardware. It is
503  * based on the fact that you can find the initial SP and PC values
504  * after a reset at physical addresses 0 and 4. This works pretty well
505  * for Atari machines, since the lowest 8 bytes of physical memory are
506  * really ROM (mapped by hardware). For other 680x0 machines: don't
507  * know if it works...
508  *
509  * To get the values at addresses 0 and 4, the MMU better is turned
510  * off first. After that, we have to jump into physical address space
511  * (the PC before the pmove statement points to the virtual address of
512  * the code). Getting that physical address is not hard, but the code
513  * becomes a bit complex since I've tried to ensure that the jump
514  * statement after the pmove is in the cache already (otherwise the
515  * processor can't fetch it!). For that, the code first jumps to the
516  * jump statement with the (virtual) address of the pmove section in
517  * an address register . The jump statement is surely in the cache
518  * now. After that, that physical address of the reset code is loaded
519  * into the same address register, pmove is done and the same jump
520  * statements goes to the reset code. Since there are not many
521  * statements between the two jumps, I hope it stays in the cache.
522  *
523  * The C code makes heavy use of the GCC features that you can get the
524  * address of a C label. No hope to compile this with another compiler
525  * than GCC!
526  */
527 
528 /* ++andreas: no need for complicated code, just depend on prefetch */
529 
530 static void atari_reset (void)
531 {
532     long tc_val = 0;
533     long reset_addr;
534 
535     /* On the Medusa, phys. 0x4 may contain garbage because it's no
536        ROM.  See above for explanation why we cannot use PTOV(4). */
537     reset_addr = MACH_IS_HADES ? 0x7fe00030 :
538                  MACH_IS_MEDUSA || MACH_IS_AB40 ? 0xe00030 :
539 		 *(unsigned long *) 0xff000004;
540 
541     /* reset ACIA for switch off OverScan, if it's active */
542     if (atari_switches & ATARI_SWITCH_OVSC_IKBD)
543 	acia.key_ctrl = ACIA_RESET;
544     if (atari_switches & ATARI_SWITCH_OVSC_MIDI)
545 	acia.mid_ctrl = ACIA_RESET;
546 
547     /* processor independent: turn off interrupts and reset the VBR;
548      * the caches must be left enabled, else prefetching the final jump
549      * instruction doesn't work. */
550     local_irq_disable();
551     __asm__ __volatile__
552 	("moveq	#0,%/d0\n\t"
553 	 "movec	%/d0,%/vbr"
554 	 : : : "d0" );
555 
556     if (CPU_IS_040_OR_060) {
557         unsigned long jmp_addr040 = virt_to_phys(&&jmp_addr_label040);
558 	if (CPU_IS_060) {
559 	    /* 68060: clear PCR to turn off superscalar operation */
560 	    __asm__ __volatile__
561 		("moveq	#0,%/d0\n\t"
562 		 ".chip 68060\n\t"
563 		 "movec %%d0,%%pcr\n\t"
564 		 ".chip 68k"
565 		 : : : "d0" );
566 	}
567 
568         __asm__ __volatile__
569             ("movel    %0,%/d0\n\t"
570              "andl     #0xff000000,%/d0\n\t"
571              "orw      #0xe020,%/d0\n\t"   /* map 16 MB, enable, cacheable */
572              ".chip 68040\n\t"
573 	     "movec    %%d0,%%itt0\n\t"
574              "movec    %%d0,%%dtt0\n\t"
575 	     ".chip 68k\n\t"
576              "jmp   %0@\n\t"
577              : /* no outputs */
578              : "a" (jmp_addr040)
579              : "d0" );
580       jmp_addr_label040:
581         __asm__ __volatile__
582           ("moveq #0,%/d0\n\t"
583 	   "nop\n\t"
584 	   ".chip 68040\n\t"
585 	   "cinva %%bc\n\t"
586 	   "nop\n\t"
587 	   "pflusha\n\t"
588 	   "nop\n\t"
589 	   "movec %%d0,%%tc\n\t"
590 	   "nop\n\t"
591 	   /* the following setup of transparent translations is needed on the
592 	    * Afterburner040 to successfully reboot. Other machines shouldn't
593 	    * care about a different tt regs setup, they also didn't care in
594 	    * the past that the regs weren't turned off. */
595 	   "movel #0xffc000,%%d0\n\t" /* whole insn space cacheable */
596 	   "movec %%d0,%%itt0\n\t"
597 	   "movec %%d0,%%itt1\n\t"
598 	   "orw   #0x40,%/d0\n\t" /* whole data space non-cacheable/ser. */
599 	   "movec %%d0,%%dtt0\n\t"
600 	   "movec %%d0,%%dtt1\n\t"
601 	   ".chip 68k\n\t"
602            "jmp %0@"
603            : /* no outputs */
604            : "a" (reset_addr)
605            : "d0");
606     }
607     else
608         __asm__ __volatile__
609             ("pmove %0@,%/tc\n\t"
610              "jmp %1@"
611              : /* no outputs */
612              : "a" (&tc_val), "a" (reset_addr));
613 }
614 
615 
616 static void atari_get_model(char *model)
617 {
618     strcpy(model, "Atari ");
619     switch (atari_mch_cookie >> 16) {
620 	case ATARI_MCH_ST:
621 	    if (ATARIHW_PRESENT(MSTE_CLK))
622 		strcat (model, "Mega ST");
623 	    else
624 		strcat (model, "ST");
625 	    break;
626 	case ATARI_MCH_STE:
627 	    if (MACH_IS_MSTE)
628 		strcat (model, "Mega STE");
629 	    else
630 		strcat (model, "STE");
631 	    break;
632 	case ATARI_MCH_TT:
633 	    if (MACH_IS_MEDUSA)
634 		/* Medusa has TT _MCH cookie */
635 		strcat (model, "Medusa");
636 	    else if (MACH_IS_HADES)
637 		strcat(model, "Hades");
638 	    else
639 		strcat (model, "TT");
640 	    break;
641 	case ATARI_MCH_FALCON:
642 	    strcat (model, "Falcon");
643 	    if (MACH_IS_AB40)
644 		strcat (model, " (with Afterburner040)");
645 	    break;
646 	default:
647 	    sprintf (model + strlen (model), "(unknown mach cookie 0x%lx)",
648 		     atari_mch_cookie);
649 	    break;
650     }
651 }
652 
653 
654 static int atari_get_hardware_list(char *buffer)
655 {
656     int len = 0, i;
657 
658     for (i = 0; i < m68k_num_memory; i++)
659 	len += sprintf (buffer+len, "\t%3ld MB at 0x%08lx (%s)\n",
660 			m68k_memory[i].size >> 20, m68k_memory[i].addr,
661 			(m68k_memory[i].addr & 0xff000000 ?
662 			 "alternate RAM" : "ST-RAM"));
663 
664 #define ATARIHW_ANNOUNCE(name,str)				\
665     if (ATARIHW_PRESENT(name))			\
666 	len += sprintf (buffer + len, "\t%s\n", str)
667 
668     len += sprintf (buffer + len, "Detected hardware:\n");
669     ATARIHW_ANNOUNCE(STND_SHIFTER, "ST Shifter");
670     ATARIHW_ANNOUNCE(EXTD_SHIFTER, "STe Shifter");
671     ATARIHW_ANNOUNCE(TT_SHIFTER, "TT Shifter");
672     ATARIHW_ANNOUNCE(VIDEL_SHIFTER, "Falcon Shifter");
673     ATARIHW_ANNOUNCE(YM_2149, "Programmable Sound Generator");
674     ATARIHW_ANNOUNCE(PCM_8BIT, "PCM 8 Bit Sound");
675     ATARIHW_ANNOUNCE(CODEC, "CODEC Sound");
676     ATARIHW_ANNOUNCE(TT_SCSI, "SCSI Controller NCR5380 (TT style)");
677     ATARIHW_ANNOUNCE(ST_SCSI, "SCSI Controller NCR5380 (Falcon style)");
678     ATARIHW_ANNOUNCE(ACSI, "ACSI Interface");
679     ATARIHW_ANNOUNCE(IDE, "IDE Interface");
680     ATARIHW_ANNOUNCE(FDCSPEED, "8/16 Mhz Switch for FDC");
681     ATARIHW_ANNOUNCE(ST_MFP, "Multi Function Peripheral MFP 68901");
682     ATARIHW_ANNOUNCE(TT_MFP, "Second Multi Function Peripheral MFP 68901");
683     ATARIHW_ANNOUNCE(SCC, "Serial Communications Controller SCC 8530");
684     ATARIHW_ANNOUNCE(ST_ESCC, "Extended Serial Communications Controller SCC 85230");
685     ATARIHW_ANNOUNCE(ANALOG_JOY, "Paddle Interface");
686     ATARIHW_ANNOUNCE(MICROWIRE, "MICROWIRE(tm) Interface");
687     ATARIHW_ANNOUNCE(STND_DMA, "DMA Controller (24 bit)");
688     ATARIHW_ANNOUNCE(EXTD_DMA, "DMA Controller (32 bit)");
689     ATARIHW_ANNOUNCE(SCSI_DMA, "DMA Controller for NCR5380");
690     ATARIHW_ANNOUNCE(SCC_DMA, "DMA Controller for SCC");
691     ATARIHW_ANNOUNCE(TT_CLK, "Clock Chip MC146818A");
692     ATARIHW_ANNOUNCE(MSTE_CLK, "Clock Chip RP5C15");
693     ATARIHW_ANNOUNCE(SCU, "System Control Unit");
694     ATARIHW_ANNOUNCE(BLITTER, "Blitter");
695     ATARIHW_ANNOUNCE(VME, "VME Bus");
696     ATARIHW_ANNOUNCE(DSP56K, "DSP56001 processor");
697 
698     return(len);
699 }
700 
701 /*
702  * Local variables:
703  *  c-indent-level: 4
704  *  tab-width: 8
705  * End:
706  */
707