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