root/arch/m68k/amiga/config.c

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

DEFINITIONS

This source file includes following definitions.
  1. config_amiga
  2. timer_wrapper
  3. amiga_sched_init
  4. amiga_gettimeoffset
  5. a3000_gettod
  6. a2000_gettod
  7. amiga_hwclk
  8. amiga_set_clock_mmss
  9. amiga_waitbut
  10. ami_serial_print
  11. amiga_debug_init
  12. dbprintf
  13. amiga_reset
  14. ami_savekmsg_init
  15. ami_mem_print
  16. amiga_get_model
  17. amiga_get_hardware_list

   1 /*
   2  *  linux/amiga/config.c
   3  *
   4  *  Copyright (C) 1993 Hamish Macdonald
   5  *
   6  * This file is subject to the terms and conditions of the GNU General Public
   7  * License.  See the file README.legal in the main directory of this archive
   8  * for more details.
   9  */
  10 
  11 /*
  12  * Miscellaneous Amiga stuff
  13  */
  14 
  15 #include <stdarg.h>
  16 #include <linux/config.h>
  17 #include <linux/types.h>
  18 #include <linux/kernel.h>
  19 #include <linux/mm.h>
  20 #include <linux/kd.h>
  21 #include <linux/tty.h>
  22 #include <linux/console.h>
  23 #include <linux/linkage.h>
  24 
  25 #include <asm/system.h>
  26 #include <asm/pgtable.h>
  27 #include <asm/bootinfo.h>
  28 #include <asm/amigahw.h>
  29 #include <asm/amigaints.h>
  30 #include <asm/irq.h>
  31 #include <asm/machdep.h>
  32 
  33 u_long amiga_masterclock;
  34 u_long amiga_colorclock;
  35 
  36 extern char m68k_debug_device[];
  37 
  38 extern void amiga_sched_init(isrfunc handler);
  39 extern int amiga_keyb_init(void);
  40 extern int amiga_kbdrate (struct kbd_repeat *);
  41 extern void amiga_init_INTS (void);
  42 extern int amiga_add_isr (unsigned long, isrfunc, int, void *, char *);
  43 extern int amiga_remove_isr (unsigned long, isrfunc);
  44 extern int amiga_get_irq_list (char *, int);
  45 extern void amiga_enable_irq(unsigned int);
  46 extern void amiga_disable_irq(unsigned int);
  47 extern unsigned long amiga_gettimeoffset (void);
  48 extern void a3000_gettod (int *, int *, int *, int *, int *, int *);
  49 extern void a2000_gettod (int *, int *, int *, int *, int *, int *);
  50 extern int amiga_hwclk (int, struct hwclk_time *);
  51 extern int amiga_set_clock_mmss (unsigned long);
  52 extern void amiga_mksound( unsigned int count, unsigned int ticks );
  53 #ifdef CONFIG_BLK_DEV_FD
  54 extern int amiga_floppy_init (void);
  55 extern void amiga_floppy_setup(char *, int *);
  56 #endif
  57 extern void amiga_reset (void);
  58 extern void amiga_waitbut(void);
  59 extern struct consw fb_con;
  60 extern struct fb_info *amiga_fb_init(long *);
  61 extern void zorro_init(void);
  62 static void ami_savekmsg_init(void);
  63 static void ami_mem_print(const char *b);
  64 extern void amiga_debug_init(void);
  65 extern void amiga_video_setup(char *, int *);
  66 
  67 extern void (*kd_mksound)(unsigned int, unsigned int);
  68 
  69 void config_amiga(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  70 {
  71   char *type = NULL;
  72 
  73   switch(boot_info.bi_amiga.model) {
  74   case AMI_500:
  75     type = "A500";
  76     break;
  77   case AMI_500PLUS:
  78     type = "A500+";
  79     break;
  80   case AMI_600:
  81     type = "A600";
  82     break;
  83   case AMI_1000:
  84     type = "A1000";
  85     break;
  86   case AMI_1200:
  87     type = "A1200";
  88     break;
  89   case AMI_2000:
  90     type = "A2000";
  91     break;
  92   case AMI_2500:
  93     type = "A2500";
  94     break;
  95   case AMI_3000:
  96     type = "A3000";
  97     break;
  98   case AMI_3000T:
  99     type = "A3000T";
 100     break;
 101   case AMI_3000PLUS:
 102     type = "A3000+";
 103     break;
 104   case AMI_4000:
 105     type = "A4000";
 106     break;
 107   case AMI_4000T:
 108     type = "A4000T";
 109     break;
 110   case AMI_CDTV:
 111     type = "CDTV";
 112     break;
 113   case AMI_CD32:
 114     type = "CD32";
 115     break;
 116   case AMI_DRACO:
 117     type = "Draco";
 118     break;
 119   }
 120   printk("Amiga hardware found: ");
 121   if (type)
 122     printk("[%s] ", type);
 123   switch(boot_info.bi_amiga.model) {
 124   case AMI_UNKNOWN:
 125     goto Generic;
 126 
 127   case AMI_500:
 128   case AMI_500PLUS:
 129   case AMI_1000:
 130     AMIGAHW_SET(A2000_CLK);             /* Is this correct? */
 131     printk("A2000_CLK ");
 132     goto Generic;
 133 
 134   case AMI_600:
 135   case AMI_1200:
 136     AMIGAHW_SET(A1200_IDE);
 137     printk("A1200_IDE ");
 138     AMIGAHW_SET(A2000_CLK);             /* Is this correct? */
 139     printk("A2000_CLK ");
 140     goto Generic;
 141 
 142   case AMI_2000:
 143   case AMI_2500:
 144     AMIGAHW_SET(A2000_CLK);
 145     printk("A2000_CLK ");
 146     goto Generic;
 147 
 148   case AMI_3000:
 149   case AMI_3000T:
 150     AMIGAHW_SET(AMBER_FF);
 151     printk("AMBER_FF ");
 152     AMIGAHW_SET(MAGIC_REKICK);
 153     printk("MAGIC_REKICK ");
 154     /* fall through */
 155   case AMI_3000PLUS:
 156     AMIGAHW_SET(A3000_SCSI);
 157     printk("A3000_SCSI ");
 158     AMIGAHW_SET(A3000_CLK);
 159     printk("A3000_CLK ");
 160     goto Generic;
 161 
 162   case AMI_4000T:
 163     AMIGAHW_SET(A4000_SCSI);
 164     printk("A4000_SCSI ");
 165     /* fall through */
 166   case AMI_4000:
 167     AMIGAHW_SET(A4000_IDE);
 168     printk("A4000_IDE ");
 169     AMIGAHW_SET(A3000_CLK);
 170     printk("A3000_CLK ");
 171     goto Generic;
 172 
 173   case AMI_CDTV:
 174   case AMI_CD32:
 175     AMIGAHW_SET(CD_ROM);
 176     printk("CD_ROM ");
 177     AMIGAHW_SET(A2000_CLK);             /* Is this correct? */
 178     printk("A2000_CLK ");
 179     goto Generic;
 180 
 181   Generic:
 182     AMIGAHW_SET(AMI_VIDEO);
 183     AMIGAHW_SET(AMI_BLITTER);
 184     AMIGAHW_SET(AMI_AUDIO);
 185     AMIGAHW_SET(AMI_FLOPPY);
 186     AMIGAHW_SET(AMI_KEYBOARD);
 187     AMIGAHW_SET(AMI_MOUSE);
 188     AMIGAHW_SET(AMI_SERIAL);
 189     AMIGAHW_SET(AMI_PARALLEL);
 190     AMIGAHW_SET(CHIP_RAM);
 191     AMIGAHW_SET(PAULA);
 192     printk("VIDEO BLITTER AUDIO FLOPPY KEYBOARD MOUSE SERIAL PARALLEL "
 193            "CHIP_RAM PAULA ");
 194 
 195     switch(boot_info.bi_amiga.chipset) {
 196     case CS_OCS:
 197     case CS_ECS:
 198     case CS_AGA:
 199       switch (custom.deniseid & 0xf) {
 200       case 0x0c:
 201         AMIGAHW_SET(DENISE_HR);
 202         printk("DENISE_HR");
 203         break;
 204       case 0x08:
 205         AMIGAHW_SET(LISA);
 206         printk("LISA ");
 207         break;
 208       }
 209       break;
 210     default:
 211       AMIGAHW_SET(DENISE);
 212       printk("DENISE ");
 213       break;
 214     }
 215     switch ((custom.vposr>>8) & 0x7f) {
 216     case 0x00:
 217       AMIGAHW_SET(AGNUS_PAL);
 218       printk("AGNUS_PAL ");
 219       break;
 220     case 0x10:
 221       AMIGAHW_SET(AGNUS_NTSC);
 222       printk("AGNUS_NTSC ");
 223       break;
 224     case 0x20:
 225     case 0x21:
 226       AMIGAHW_SET(AGNUS_HR_PAL);
 227       printk("AGNUS_HR_PAL ");
 228       break;
 229     case 0x30:
 230     case 0x31:
 231       AMIGAHW_SET(AGNUS_HR_NTSC);
 232       printk("AGNUS_HR_NTSC ");
 233       break;
 234     case 0x22:
 235     case 0x23:
 236       AMIGAHW_SET(ALICE_PAL);
 237       printk("ALICE_PAL ");
 238       break;
 239     case 0x32:
 240     case 0x33:
 241       AMIGAHW_SET(ALICE_NTSC);
 242       printk("ALICE_NTSC ");
 243       break;
 244     }
 245     AMIGAHW_SET(ZORRO);
 246     printk("ZORRO ");
 247     break;
 248 
 249   case AMI_DRACO:
 250     panic("No support for Draco yet");
 251  
 252   default:
 253     panic("Unknown Amiga Model");
 254   }
 255   printk("\n");
 256  
 257   mach_sched_init      = amiga_sched_init;
 258   mach_keyb_init       = amiga_keyb_init;
 259   mach_kbdrate         = amiga_kbdrate;
 260   mach_init_INTS       = amiga_init_INTS;
 261   mach_add_isr         = amiga_add_isr;
 262 #if 0 /* ++1.3++ */
 263   mach_remove_isr      = amiga_remove_isr;
 264   mach_enable_irq      = amiga_enable_irq;
 265   mach_disable_irq     = amiga_disable_irq;
 266 #endif
 267   mach_get_irq_list    = amiga_get_irq_list;
 268   mach_gettimeoffset   = amiga_gettimeoffset;
 269   if (AMIGAHW_PRESENT(A3000_CLK)){
 270     mach_gettod  = a3000_gettod;
 271     mach_max_dma_address = 0xffffffff; /*
 272                                         * default MAX_DMA 0xffffffff
 273                                         * on Z3 machines - we should
 274                                         * consider adding something
 275                                         * like a dma_mask in kmalloc
 276                                         * later on, so people using Z2
 277                                         * boards in Z3 machines won't
 278                                         * get into trouble - Jes
 279                                         */
 280   }
 281   else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
 282     mach_gettod  = a2000_gettod;
 283     mach_max_dma_address = 0x00ffffff; /*
 284                                         * default MAX_DMA 0x00ffffff
 285                                         * on Z2 machines.
 286                                         */
 287   }
 288   mach_hwclk           = amiga_hwclk;
 289   mach_set_clock_mmss  = amiga_set_clock_mmss;
 290   mach_mksound         = amiga_mksound;
 291 #ifdef CONFIG_BLK_DEV_FD
 292   mach_floppy_init     = amiga_floppy_init;
 293   mach_floppy_setup    = amiga_floppy_setup;
 294 #endif
 295   mach_reset           = amiga_reset;
 296   waitbut              = amiga_waitbut;
 297   conswitchp           = &fb_con;
 298   mach_fb_init         = amiga_fb_init;
 299   mach_debug_init      = amiga_debug_init;
 300   mach_video_setup     = amiga_video_setup;
 301   kd_mksound           = amiga_mksound;
 302 
 303   /* Fill in the clock values (based on the 700 kHz E-Clock) */
 304   amiga_masterclock = 40*amiga_eclock;  /* 28 MHz */
 305   amiga_colorclock = 5*amiga_eclock;            /* 3.5 MHz */
 306 
 307   /* clear all DMA bits */
 308   custom.dmacon = DMAF_ALL;
 309   /* ensure that the DMA master bit is set */
 310   custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
 311 
 312   /* initialize chipram allocator */
 313   amiga_chip_init ();
 314 
 315   /* initialize only once here, not every time the debug level is raised */
 316   if (!strcmp( m68k_debug_device, "mem" ))
 317     ami_savekmsg_init();
 318 
 319   /*
 320    * if it is an A3000, set the magic bit that forces
 321    * a hard rekick
 322    */
 323   if (AMIGAHW_PRESENT(MAGIC_REKICK))
 324     *(u_char *)ZTWO_VADDR(0xde0002) |= 0x80;
 325 
 326   zorro_init();
 327 #ifdef CONFIG_ZORRO
 328   /*
 329    * Identify all known AutoConfig Expansion Devices
 330    */
 331   zorro_identify();
 332 #endif /* CONFIG_ZORRO */
 333 }
 334 
 335 extern long time_finetune;      /* from kernel/sched.c */
 336 
 337 static unsigned short jiffy_ticks;
 338 
 339 #if 1 /* ++1.3++ */
 340 static void timer_wrapper( int irq, struct pt_regs *fp, void *otimerf )
     /* [previous][next][first][last][top][bottom][index][help] */
 341  {
 342    unsigned short flags, old_flags;
 343 
 344    ciab.icr = 0x01;
 345 
 346    save_flags(flags);
 347    old_flags = (flags & ~0x0700) | (fp->sr & 0x0700);
 348    
 349    restore_flags(old_flags);
 350 
 351    (*(isrfunc)otimerf)( irq, fp, NULL );
 352 
 353    restore_flags(flags);
 354    ciab.icr = 0x81;
 355 }
 356 #endif
 357 
 358 void amiga_sched_init (isrfunc timer_routine)
     /* [previous][next][first][last][top][bottom][index][help] */
 359 {
 360 
 361 #if 0 /* XXX */ /* I think finetune was removed by the 1.3.29 patch */
 362     double finetune;
 363 #endif
 364 
 365     jiffy_ticks = (amiga_eclock+50)/100;
 366 #if 0 /* XXX */
 367     finetune = (jiffy_ticks-amiga_eclock/HZ)/amiga_eclock*1000000*(1<<24);
 368     time_finetune = finetune+0.5;
 369 #endif
 370 
 371     ciab.cra &= 0xC0;    /* turn off timer A, continuous mode, from Eclk */
 372     ciab.talo = jiffy_ticks % 256;
 373     ciab.tahi = jiffy_ticks / 256;
 374     /* CIA interrupts when counter underflows, so adjust ticks by 1 */
 375     jiffy_ticks -= 1;
 376 
 377     /* install interrupt service routine for CIAB Timer A */
 378     /*
 379      * Please don't change this to use ciaa, as it interferes with the
 380      * SCSI code. We'll have to take a look at this later
 381      */
 382 #if 0
 383     add_isr (IRQ_AMIGA_CIAB_TA, timer_routine, 0, NULL, "timer");
 384 #else
 385     add_isr (IRQ_AMIGA_CIAB_TA, timer_wrapper, 0, timer_routine, "timer");
 386 #endif
 387     /* start timer */
 388     ciab.cra |= 0x01;
 389 }
 390 
 391 #define TICK_SIZE 10000
 392 
 393 /* This is always executed with interrupts disabled.  */
 394 unsigned long amiga_gettimeoffset (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 395 {
 396     unsigned short hi, lo, hi2;
 397     unsigned long ticks, offset = 0;
 398 
 399     /* read CIA A timer A current value */
 400     hi  = ciab.tahi;
 401     lo  = ciab.talo;
 402     hi2 = ciab.tahi;
 403 
 404     if (hi != hi2) {
 405         lo = ciab.talo;
 406         hi = hi2;
 407     }
 408 
 409     ticks = hi << 8 | lo;
 410 
 411 #if 0 /* XXX */
 412 /* reading the ICR clears all interrupts.  bad idea! */
 413       if (ticks > jiffy_ticks - jiffy_ticks / 100)
 414         /* check for pending interrupt */
 415         if (ciab.icr & CIA_ICR_TA)
 416           offset = 10000;
 417 #endif
 418 
 419     ticks = (jiffy_ticks-1) - ticks;
 420     ticks = (10000 * ticks) / jiffy_ticks;
 421 
 422     return ticks + offset;
 423 }
 424 
 425 void a3000_gettod (int *yearp, int *monp, int *dayp,
     /* [previous][next][first][last][top][bottom][index][help] */
 426                    int *hourp, int *minp, int *secp)
 427 {
 428         volatile struct tod3000 *tod = TOD_3000;
 429 
 430         tod->cntrl1 = TOD3000_CNTRL1_HOLD;
 431 
 432         *secp  = tod->second1 * 10 + tod->second2;
 433         *minp  = tod->minute1 * 10 + tod->minute2;
 434         *hourp = tod->hour1   * 10 + tod->hour2;
 435         *dayp  = tod->day1    * 10 + tod->day2;
 436         *monp  = tod->month1  * 10 + tod->month2;
 437         *yearp = tod->year1   * 10 + tod->year2;
 438 
 439         tod->cntrl1 = TOD3000_CNTRL1_FREE;
 440 }
 441 
 442 void a2000_gettod (int *yearp, int *monp, int *dayp,
     /* [previous][next][first][last][top][bottom][index][help] */
 443                    int *hourp, int *minp, int *secp)
 444 {
 445         volatile struct tod2000 *tod = TOD_2000;
 446 
 447         tod->cntrl1 = TOD2000_CNTRL1_HOLD;
 448 
 449         while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
 450                 ;
 451 
 452         *secp  = tod->second1     * 10 + tod->second2;
 453         *minp  = tod->minute1     * 10 + tod->minute2;
 454         *hourp = (tod->hour1 & 3) * 10 + tod->hour2;
 455         *dayp  = tod->day1        * 10 + tod->day2;
 456         *monp  = tod->month1      * 10 + tod->month2;
 457         *yearp = tod->year1       * 10 + tod->year2;
 458 
 459         if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
 460                 if ((!tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
 461                         *hourp = 0;
 462                 else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12)
 463                         *hourp += 12;
 464 
 465         tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
 466 }
 467 
 468 int amiga_hwclk(int op, struct hwclk_time *t)
     /* [previous][next][first][last][top][bottom][index][help] */
 469 {
 470         if (AMIGAHW_PRESENT(A3000_CLK)) {
 471                 volatile struct tod3000 *tod = TOD_3000;
 472 
 473                 tod->cntrl1 = TOD3000_CNTRL1_HOLD;
 474 
 475                 if (!op) { /* read */
 476                         t->sec  = tod->second1 * 10 + tod->second2;
 477                         t->min  = tod->minute1 * 10 + tod->minute2;
 478                         t->hour = tod->hour1   * 10 + tod->hour2;
 479                         t->day  = tod->day1    * 10 + tod->day2;
 480                         t->wday = tod->weekday;
 481                         t->mon  = tod->month1  * 10 + tod->month2 - 1;
 482                         t->year = tod->year1   * 10 + tod->year2;
 483                 } else {
 484                         tod->second1 = t->sec / 10;
 485                         tod->second2 = t->sec % 10;
 486                         tod->minute1 = t->min / 10;
 487                         tod->minute2 = t->min % 10;
 488                         tod->hour1   = t->hour / 10;
 489                         tod->hour2   = t->hour % 10;
 490                         tod->day1    = t->day / 10;
 491                         tod->day2    = t->day % 10;
 492                         if (t->wday != -1)
 493                                 tod->weekday = t->wday;
 494                         tod->month1  = (t->mon + 1) / 10;
 495                         tod->month2  = (t->mon + 1) % 10;
 496                         tod->year1   = t->year / 10;
 497                         tod->year2   = t->year % 10;
 498                 }
 499 
 500                 tod->cntrl1 = TOD3000_CNTRL1_FREE;
 501         } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
 502                 volatile struct tod2000 *tod = TOD_2000;
 503 
 504                 tod->cntrl1 = TOD2000_CNTRL1_HOLD;
 505             
 506                 while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
 507                         ;
 508 
 509                 if (!op) { /* read */
 510                         t->sec  = tod->second1     * 10 + tod->second2;
 511                         t->min  = tod->minute1     * 10 + tod->minute2;
 512                         t->hour = (tod->hour1 & 3) * 10 + tod->hour2;
 513                         t->day  = tod->day1        * 10 + tod->day2;
 514                         t->wday = tod->weekday;
 515                         t->mon  = tod->month1      * 10 + tod->month2 - 1;
 516                         t->year = tod->year1       * 10 + tod->year2;
 517 
 518                         if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
 519                                 if ((!tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
 520                                         t->hour = 0;
 521                                 else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
 522                                         t->hour += 12;
 523                 } else {
 524                         tod->second1 = t->sec / 10;
 525                         tod->second2 = t->sec % 10;
 526                         tod->minute1 = t->min / 10;
 527                         tod->minute2 = t->min % 10;
 528                         if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE)
 529                                 tod->hour1 = t->hour / 10;
 530                         else if (t->hour >= 12)
 531                                 tod->hour1 = TOD2000_HOUR1_PM +
 532                                         (t->hour - 12) / 10;
 533                         else
 534                                 tod->hour1 = t->hour / 10;
 535                         tod->hour2   = t->hour % 10;
 536                         tod->day1    = t->day / 10;
 537                         tod->day2    = t->day % 10;
 538                         if (t->wday != -1)
 539                                 tod->weekday = t->wday;
 540                         tod->month1  = (t->mon + 1) / 10;
 541                         tod->month2  = (t->mon + 1) % 10;
 542                         tod->year1   = t->year / 10;
 543                         tod->year2   = t->year % 10;
 544                 }
 545 
 546                 tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
 547         }
 548 
 549         return 0;
 550 }
 551 
 552 int amiga_set_clock_mmss (unsigned long nowtime)
     /* [previous][next][first][last][top][bottom][index][help] */
 553 {
 554         short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
 555 
 556         if (AMIGAHW_PRESENT(A3000_CLK)) {
 557                 volatile struct tod3000 *tod = TOD_3000;
 558 
 559                 tod->cntrl1 = TOD3000_CNTRL1_HOLD;
 560 
 561                 tod->second1 = real_seconds / 10;
 562                 tod->second2 = real_seconds % 10;
 563                 tod->minute1 = real_minutes / 10;
 564                 tod->minute2 = real_minutes % 10;
 565                 
 566                 tod->cntrl1 = TOD3000_CNTRL1_FREE;
 567         } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
 568                 volatile struct tod2000 *tod = TOD_2000;
 569 
 570                 tod->cntrl1 = TOD2000_CNTRL1_HOLD;
 571             
 572                 while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
 573                         ;
 574 
 575                 tod->second1 = real_seconds / 10;
 576                 tod->second2 = real_seconds % 10;
 577                 tod->minute1 = real_minutes / 10;
 578                 tod->minute2 = real_minutes % 10;
 579 
 580                 tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
 581         }
 582 
 583         return 0;
 584 }
 585 
 586 void amiga_waitbut (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 587 {
 588     int i;
 589 
 590     while (1) {
 591         while (ciaa.pra & 0x40);
 592 
 593         /* debounce */
 594         for (i = 0; i < 1000; i++);
 595 
 596         if (!(ciaa.pra & 0x40))
 597             break;
 598     }
 599 
 600     /* wait for button up */
 601     while (1) {
 602         while (!(ciaa.pra & 0x40));
 603 
 604         /* debounce */
 605         for (i = 0; i < 1000; i++);
 606 
 607         if (ciaa.pra & 0x40)
 608             break;
 609     }
 610 }
 611 
 612 void ami_serial_print (const char *str)
     /* [previous][next][first][last][top][bottom][index][help] */
 613 {
 614     while (*str) {
 615         if (*str == '\n') {
 616             custom.serdat = (unsigned char)'\r' | 0x100;
 617             while (!(custom.serdatr & 0x2000))
 618                 ;
 619         }
 620         custom.serdat = (unsigned char)*str++ | 0x100;
 621         while (!(custom.serdatr & 0x2000))
 622             ;
 623     }
 624 }
 625 
 626 void amiga_debug_init (void)
     /* [previous][next][first][last][top][bottom][index][help] */
 627 {
 628     extern void (*debug_print_proc)(const char *);
 629 
 630     if (!strcmp( m68k_debug_device, "ser" )) {
 631         /* no initialization required (?) */
 632         debug_print_proc = ami_serial_print;
 633     } else if (!strcmp( m68k_debug_device, "mem" )) {
 634         /* already initialized by config_amiga() (needed only once) */
 635         debug_print_proc = ami_mem_print;
 636     }
 637 }
 638 
 639 void dbprintf(const char *fmt , ...)
     /* [previous][next][first][last][top][bottom][index][help] */
 640 {
 641         static char buf[1024];
 642         va_list args;
 643         extern void console_print (const char *str);
 644         extern int vsprintf(char * buf, const char * fmt, va_list args);
 645 
 646         va_start(args, fmt);
 647         vsprintf(buf, fmt, args);
 648         va_end(args);
 649 
 650         console_print (buf);
 651 }
 652 
 653 NORET_TYPE void amiga_reset( void )
     /* [previous][next][first][last][top][bottom][index][help] */
 654     ATTRIB_NORET;
 655 
 656 void amiga_reset (void)
 657 {
 658   unsigned long jmp_addr040 = VTOP(&&jmp_addr_label040);
 659   unsigned long jmp_addr = VTOP(&&jmp_addr_label);
 660 
 661   cli();
 662   if (m68k_is040or060)
 663     /* Setup transparent translation registers for mapping
 664      * of 16 MB kernel segment before disabling translation
 665      */
 666     __asm__ __volatile__
 667       ("movel    %0,%/d0\n\t"
 668        "andl     #0xff000000,%/d0\n\t"
 669        "orw      #0xe020,%/d0\n\t"   /* map 16 MB, enable, cacheable */
 670        ".long    0x4e7b0004\n\t"   /* movec d0,itt0 */
 671        ".long    0x4e7b0006\n\t"   /* movec d0,dtt0 */
 672        "jmp      %0@\n\t"
 673        : /* no outputs */
 674        : "a" (jmp_addr040));
 675   else
 676     /* for 680[23]0, just disable translation and jump to the physical
 677      * address of the label
 678      */
 679     __asm__ __volatile__
 680       ("pmove  %/tc,%@\n\t"
 681        "bclr   #7,%@\n\t"
 682        "pmove  %@,%/tc\n\t"
 683        "jmp    %0@\n\t"
 684        : /* no outputs */
 685        : "a" (jmp_addr));
 686  jmp_addr_label040:
 687   /* disable translation on '040 now */
 688   __asm__ __volatile__    
 689     ("moveq #0,%/d0\n\t"
 690      ".long 0x4e7b0003\n\t"         /* movec d0,tc; disable MMU */
 691      : /* no outputs */
 692      : /* no inputs */
 693      : "d0");
 694 
 695  jmp_addr_label:
 696   /* pickup reset address from AmigaOS ROM, reset devices and jump
 697    * to reset address
 698    */
 699   __asm__ __volatile__
 700     ("movew #0x2700,%/sr\n\t"
 701      "leal  0x01000000,%/a0\n\t"
 702      "subl  %/a0@(-0x14),%/a0\n\t"
 703      "movel %/a0@(4),%/a0\n\t"
 704      "subql #2,%/a0\n\t"
 705      "bra   1f\n\t"
 706      /* align on a longword boundary */
 707      __ALIGN_STR "\n"
 708      "1:\n\t"
 709      "reset\n\t"
 710      "jmp   %/a0@" : /* Just that gcc scans it for % escapes */ );
 711   
 712   for (;;);
 713 
 714 }
 715 
 716 extern void *amiga_chip_alloc(long size);
 717 
 718 
 719 #define SAVEKMSG_MAXMEM         128*1024
 720 
 721 
 722 #define SAVEKMSG_MAGIC1         0x53415645      /* 'SAVE' */
 723 #define SAVEKMSG_MAGIC2         0x4B4D5347      /* 'KMSG' */
 724 
 725 struct savekmsg {
 726     u_long magic1;              /* SAVEKMSG_MAGIC1 */
 727     u_long magic2;              /* SAVEKMSG_MAGIC2 */
 728     u_long magicptr;            /* address of magic1 */
 729     u_long size;
 730     char data[0];
 731 };
 732 
 733 static struct savekmsg *savekmsg = NULL;
 734 
 735 
 736 static void ami_savekmsg_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 737 {
 738     savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM);
 739     savekmsg->magic1 = SAVEKMSG_MAGIC1;
 740     savekmsg->magic2 = SAVEKMSG_MAGIC2;
 741     savekmsg->magicptr = VTOP(savekmsg);
 742     savekmsg->size = 0;
 743 }
 744 
 745 
 746 static void ami_mem_print(const char *b)
     /* [previous][next][first][last][top][bottom][index][help] */
 747 {
 748     int len;
 749 
 750     for (len = 0; b[len]; len++);
 751     if (savekmsg->size+len <= SAVEKMSG_MAXMEM) {
 752         memcpy(savekmsg->data+savekmsg->size, b, len);
 753         savekmsg->size += len;
 754     }
 755 }
 756 
 757 
 758 void amiga_get_model(char *model)
     /* [previous][next][first][last][top][bottom][index][help] */
 759 {
 760     strcpy(model, "Amiga ");
 761     switch (boot_info.bi_amiga.model) {
 762         case AMI_500:
 763             strcat(model, "500");
 764             break;
 765         case AMI_500PLUS:
 766             strcat(model, "500+");
 767             break;
 768         case AMI_600:
 769             strcat(model, "600");
 770             break;
 771         case AMI_1000:
 772             strcat(model, "1000");
 773             break;
 774         case AMI_1200:
 775             strcat(model, "1200");
 776             break;
 777         case AMI_2000:
 778             strcat(model, "2000");
 779             break;
 780         case AMI_2500:
 781             strcat(model, "2500");
 782             break;
 783         case AMI_3000:
 784             strcat(model, "3000");
 785             break;
 786         case AMI_3000T:
 787             strcat(model, "3000T");
 788             break;
 789         case AMI_3000PLUS:
 790             strcat(model, "3000+");
 791             break;
 792         case AMI_4000:
 793             strcat(model, "4000");
 794             break;
 795         case AMI_4000T:
 796             strcat(model, "4000T");
 797             break;
 798         case AMI_CDTV:
 799             strcat(model, "CDTV");
 800             break;
 801         case AMI_CD32:
 802             strcat(model, "CD32");
 803             break;
 804         case AMI_DRACO:
 805             strcpy(model, "DRACO");
 806             break;
 807     }
 808 }
 809 
 810 
 811 int amiga_get_hardware_list(char *buffer)
     /* [previous][next][first][last][top][bottom][index][help] */
 812 {
 813     int len = 0;
 814 
 815     if (AMIGAHW_PRESENT(CHIP_RAM))
 816         len += sprintf(buffer+len, "Chip RAM:\t%ldK\n",
 817                        boot_info.bi_amiga.chip_size>>10);
 818     len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
 819                    boot_info.bi_amiga.psfreq, amiga_eclock);
 820     if (AMIGAHW_PRESENT(AMI_VIDEO)) {
 821         char *type;
 822         switch(boot_info.bi_amiga.chipset) {
 823             case CS_OCS:
 824                 type = "OCS";
 825                 break;
 826             case CS_ECS:
 827                 type = "ECS";
 828                 break;
 829             case CS_AGA:
 830                 type = "AGA";
 831                 break;
 832             default:
 833                 type = "Old or Unknown";
 834                 break;
 835         }
 836         len += sprintf(buffer+len, "Graphics:\t%s\n", type);
 837     }
 838 
 839 #define AMIGAHW_ANNOUNCE(name, str)                             \
 840     if (AMIGAHW_PRESENT(name))                          \
 841         len += sprintf (buffer+len, "\t%s\n", str)
 842 
 843     len += sprintf (buffer + len, "Detected hardware:\n");
 844 
 845     AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");
 846     AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");
 847     AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer");
 848     AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio");
 849     AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller");
 850     AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)");
 851     AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)");
 852     AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)");
 853     AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)");
 854     AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive");
 855     AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard");
 856     AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port");
 857     AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port");
 858     AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port");
 859     AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)");
 860     AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)");
 861     AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM");
 862     AMIGAHW_ANNOUNCE(PAULA, "Paula 8364");
 863     AMIGAHW_ANNOUNCE(DENISE, "Denise 8362");
 864     AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373");
 865     AMIGAHW_ANNOUNCE(LISA, "Lisa 8375");
 866     AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371");
 867     AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370");
 868     AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372");
 869     AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372");
 870     AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374");
 871     AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374");
 872     AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
 873     if (AMIGAHW_PRESENT(ZORRO))
 874         len += sprintf(buffer+len, "\tZorro AutoConfig: %d Expansion Device%s\n",
 875                        boot_info.bi_amiga.num_autocon,
 876                        boot_info.bi_amiga.num_autocon == 1 ? "" : "s");
 877 
 878     return(len);
 879 }

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