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