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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [arch/] [m68k/] [amiga/] [config.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1623 jcastillo
/*
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 COPYING 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, void *);
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)
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
  mach_remove_isr      = amiga_remove_isr;
263
  mach_enable_irq      = amiga_enable_irq;
264
  mach_disable_irq     = amiga_disable_irq;
265
  mach_get_irq_list    = amiga_get_irq_list;
266
  mach_gettimeoffset   = amiga_gettimeoffset;
267
  if (AMIGAHW_PRESENT(A3000_CLK)){
268
    mach_gettod  = a3000_gettod;
269
    mach_max_dma_address = 0xffffffff; /*
270
                                        * default MAX_DMA 0xffffffff
271
                                        * on Z3 machines - we should
272
                                        * consider adding something
273
                                        * like a dma_mask in kmalloc
274
                                        * later on, so people using Z2
275
                                        * boards in Z3 machines won't
276
                                        * get into trouble - Jes
277
                                        */
278
  }
279
  else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */
280
    mach_gettod  = a2000_gettod;
281
    mach_max_dma_address = 0x00ffffff; /*
282
                                        * default MAX_DMA 0x00ffffff
283
                                        * on Z2 machines.
284
                                        */
285
  }
286
  mach_hwclk           = amiga_hwclk;
287
  mach_set_clock_mmss  = amiga_set_clock_mmss;
288
  mach_mksound         = amiga_mksound;
289
#ifdef CONFIG_BLK_DEV_FD
290
  mach_floppy_init     = amiga_floppy_init;
291
  mach_floppy_setup    = amiga_floppy_setup;
292
#endif
293
  mach_reset           = amiga_reset;
294
  waitbut              = amiga_waitbut;
295
  conswitchp           = &fb_con;
296
  mach_fb_init         = amiga_fb_init;
297
  mach_debug_init      = amiga_debug_init;
298
  mach_video_setup     = amiga_video_setup;
299
  kd_mksound           = amiga_mksound;
300
 
301
  /* Fill in the clock values (based on the 700 kHz E-Clock) */
302
  amiga_masterclock = 40*amiga_eclock;  /* 28 MHz */
303
  amiga_colorclock = 5*amiga_eclock;            /* 3.5 MHz */
304
 
305
  /* clear all DMA bits */
306
  custom.dmacon = DMAF_ALL;
307
  /* ensure that the DMA master bit is set */
308
  custom.dmacon = DMAF_SETCLR | DMAF_MASTER;
309
 
310
  /* initialize chipram allocator */
311
  amiga_chip_init ();
312
 
313
  /* initialize only once here, not every time the debug level is raised */
314
  if (!strcmp( m68k_debug_device, "mem" ))
315
    ami_savekmsg_init();
316
 
317
  /*
318
   * if it is an A3000, set the magic bit that forces
319
   * a hard rekick
320
   */
321
  if (AMIGAHW_PRESENT(MAGIC_REKICK))
322
    *(u_char *)ZTWO_VADDR(0xde0002) |= 0x80;
323
 
324
  zorro_init();
325
#ifdef CONFIG_ZORRO
326
  /*
327
   * Identify all known AutoConfig Expansion Devices
328
   */
329
  zorro_identify();
330
#endif /* CONFIG_ZORRO */
331
}
332
 
333
extern long time_finetune;      /* from kernel/sched.c */
334
 
335
static unsigned short jiffy_ticks;
336
 
337
#if 1 /* ++1.3++ */
338
static void timer_wrapper( int irq, struct pt_regs *fp, void *otimerf )
339
 {
340
   unsigned short flags, old_flags;
341
 
342
   ciab.icr = 0x01;
343
 
344
   save_flags(flags);
345
   old_flags = (flags & ~0x0700) | (fp->sr & 0x0700);
346
 
347
   restore_flags(old_flags);
348
 
349
   (*(isrfunc)otimerf)( irq, fp, NULL );
350
 
351
   restore_flags(flags);
352
   ciab.icr = 0x81;
353
}
354
#endif
355
 
356
void amiga_sched_init (isrfunc timer_routine)
357
{
358
 
359
#if 0 /* XXX */ /* I think finetune was removed by the 1.3.29 patch */
360
    double finetune;
361
#endif
362
 
363
    jiffy_ticks = (amiga_eclock+50)/100;
364
#if 0 /* XXX */
365
    finetune = (jiffy_ticks-amiga_eclock/HZ)/amiga_eclock*1000000*(1<<24);
366
    time_finetune = finetune+0.5;
367
#endif
368
 
369
    ciab.cra &= 0xC0;    /* turn off timer A, continuous mode, from Eclk */
370
    ciab.talo = jiffy_ticks % 256;
371
    ciab.tahi = jiffy_ticks / 256;
372
    /* CIA interrupts when counter underflows, so adjust ticks by 1 */
373
    jiffy_ticks -= 1;
374
 
375
    /* install interrupt service routine for CIAB Timer A */
376
    /*
377
     * Please don't change this to use ciaa, as it interferes with the
378
     * SCSI code. We'll have to take a look at this later
379
     */
380
#if 0
381
    add_isr (IRQ_AMIGA_CIAB_TA, timer_routine, 0, NULL, "timer");
382
#else
383
    add_isr (IRQ_AMIGA_CIAB_TA, timer_wrapper, 0, timer_routine, "timer");
384
#endif
385
    /* start timer */
386
    ciab.cra |= 0x01;
387
}
388
 
389
#define TICK_SIZE 10000
390
 
391
/* This is always executed with interrupts disabled.  */
392
unsigned long amiga_gettimeoffset (void)
393
{
394
    unsigned short hi, lo, hi2;
395
    unsigned long ticks, offset = 0;
396
 
397
    /* read CIA A timer A current value */
398
    hi  = ciab.tahi;
399
    lo  = ciab.talo;
400
    hi2 = ciab.tahi;
401
 
402
    if (hi != hi2) {
403
        lo = ciab.talo;
404
        hi = hi2;
405
    }
406
 
407
    ticks = hi << 8 | lo;
408
 
409
#if 0 /* XXX */
410
/* reading the ICR clears all interrupts.  bad idea! */
411
      if (ticks > jiffy_ticks - jiffy_ticks / 100)
412
        /* check for pending interrupt */
413
        if (ciab.icr & CIA_ICR_TA)
414
          offset = 10000;
415
#endif
416
 
417
    ticks = (jiffy_ticks-1) - ticks;
418
    ticks = (10000 * ticks) / jiffy_ticks;
419
 
420
    return ticks + offset;
421
}
422
 
423
void a3000_gettod (int *yearp, int *monp, int *dayp,
424
                   int *hourp, int *minp, int *secp)
425
{
426
        volatile struct tod3000 *tod = TOD_3000;
427
 
428
        tod->cntrl1 = TOD3000_CNTRL1_HOLD;
429
 
430
        *secp  = tod->second1 * 10 + tod->second2;
431
        *minp  = tod->minute1 * 10 + tod->minute2;
432
        *hourp = tod->hour1   * 10 + tod->hour2;
433
        *dayp  = tod->day1    * 10 + tod->day2;
434
        *monp  = tod->month1  * 10 + tod->month2;
435
        *yearp = tod->year1   * 10 + tod->year2;
436
 
437
        tod->cntrl1 = TOD3000_CNTRL1_FREE;
438
}
439
 
440
void a2000_gettod (int *yearp, int *monp, int *dayp,
441
                   int *hourp, int *minp, int *secp)
442
{
443
        volatile struct tod2000 *tod = TOD_2000;
444
 
445
        tod->cntrl1 = TOD2000_CNTRL1_HOLD;
446
 
447
        while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
448
                ;
449
 
450
        *secp  = tod->second1     * 10 + tod->second2;
451
        *minp  = tod->minute1     * 10 + tod->minute2;
452
        *hourp = (tod->hour1 & 3) * 10 + tod->hour2;
453
        *dayp  = tod->day1        * 10 + tod->day2;
454
        *monp  = tod->month1      * 10 + tod->month2;
455
        *yearp = tod->year1       * 10 + tod->year2;
456
 
457
        if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
458
                if ((!tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12)
459
                        *hourp = 0;
460
                else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12)
461
                        *hourp += 12;
462
 
463
        tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
464
}
465
 
466
int amiga_hwclk(int op, struct hwclk_time *t)
467
{
468
        if (AMIGAHW_PRESENT(A3000_CLK)) {
469
                volatile struct tod3000 *tod = TOD_3000;
470
 
471
                tod->cntrl1 = TOD3000_CNTRL1_HOLD;
472
 
473
                if (!op) { /* read */
474
                        t->sec  = tod->second1 * 10 + tod->second2;
475
                        t->min  = tod->minute1 * 10 + tod->minute2;
476
                        t->hour = tod->hour1   * 10 + tod->hour2;
477
                        t->day  = tod->day1    * 10 + tod->day2;
478
                        t->wday = tod->weekday;
479
                        t->mon  = tod->month1  * 10 + tod->month2 - 1;
480
                        t->year = tod->year1   * 10 + tod->year2;
481
                } else {
482
                        tod->second1 = t->sec / 10;
483
                        tod->second2 = t->sec % 10;
484
                        tod->minute1 = t->min / 10;
485
                        tod->minute2 = t->min % 10;
486
                        tod->hour1   = t->hour / 10;
487
                        tod->hour2   = t->hour % 10;
488
                        tod->day1    = t->day / 10;
489
                        tod->day2    = t->day % 10;
490
                        if (t->wday != -1)
491
                                tod->weekday = t->wday;
492
                        tod->month1  = (t->mon + 1) / 10;
493
                        tod->month2  = (t->mon + 1) % 10;
494
                        tod->year1   = t->year / 10;
495
                        tod->year2   = t->year % 10;
496
                }
497
 
498
                tod->cntrl1 = TOD3000_CNTRL1_FREE;
499
        } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
500
                volatile struct tod2000 *tod = TOD_2000;
501
 
502
                tod->cntrl1 = TOD2000_CNTRL1_HOLD;
503
 
504
                while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
505
                        ;
506
 
507
                if (!op) { /* read */
508
                        t->sec  = tod->second1     * 10 + tod->second2;
509
                        t->min  = tod->minute1     * 10 + tod->minute2;
510
                        t->hour = (tod->hour1 & 3) * 10 + tod->hour2;
511
                        t->day  = tod->day1        * 10 + tod->day2;
512
                        t->wday = tod->weekday;
513
                        t->mon  = tod->month1      * 10 + tod->month2 - 1;
514
                        t->year = tod->year1       * 10 + tod->year2;
515
 
516
                        if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE))
517
                                if ((!tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12)
518
                                        t->hour = 0;
519
                                else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12)
520
                                        t->hour += 12;
521
                } else {
522
                        tod->second1 = t->sec / 10;
523
                        tod->second2 = t->sec % 10;
524
                        tod->minute1 = t->min / 10;
525
                        tod->minute2 = t->min % 10;
526
                        if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE)
527
                                tod->hour1 = t->hour / 10;
528
                        else if (t->hour >= 12)
529
                                tod->hour1 = TOD2000_HOUR1_PM +
530
                                        (t->hour - 12) / 10;
531
                        else
532
                                tod->hour1 = t->hour / 10;
533
                        tod->hour2   = t->hour % 10;
534
                        tod->day1    = t->day / 10;
535
                        tod->day2    = t->day % 10;
536
                        if (t->wday != -1)
537
                                tod->weekday = t->wday;
538
                        tod->month1  = (t->mon + 1) / 10;
539
                        tod->month2  = (t->mon + 1) % 10;
540
                        tod->year1   = t->year / 10;
541
                        tod->year2   = t->year % 10;
542
                }
543
 
544
                tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
545
        }
546
 
547
        return 0;
548
}
549
 
550
int amiga_set_clock_mmss (unsigned long nowtime)
551
{
552
        short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
553
 
554
        if (AMIGAHW_PRESENT(A3000_CLK)) {
555
                volatile struct tod3000 *tod = TOD_3000;
556
 
557
                tod->cntrl1 = TOD3000_CNTRL1_HOLD;
558
 
559
                tod->second1 = real_seconds / 10;
560
                tod->second2 = real_seconds % 10;
561
                tod->minute1 = real_minutes / 10;
562
                tod->minute2 = real_minutes % 10;
563
 
564
                tod->cntrl1 = TOD3000_CNTRL1_FREE;
565
        } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ {
566
                volatile struct tod2000 *tod = TOD_2000;
567
 
568
                tod->cntrl1 = TOD2000_CNTRL1_HOLD;
569
 
570
                while (tod->cntrl1 & TOD2000_CNTRL1_BUSY)
571
                        ;
572
 
573
                tod->second1 = real_seconds / 10;
574
                tod->second2 = real_seconds % 10;
575
                tod->minute1 = real_minutes / 10;
576
                tod->minute2 = real_minutes % 10;
577
 
578
                tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD;
579
        }
580
 
581
        return 0;
582
}
583
 
584
void amiga_waitbut (void)
585
{
586
    int i;
587
 
588
    while (1) {
589
        while (ciaa.pra & 0x40);
590
 
591
        /* debounce */
592
        for (i = 0; i < 1000; i++);
593
 
594
        if (!(ciaa.pra & 0x40))
595
            break;
596
    }
597
 
598
    /* wait for button up */
599
    while (1) {
600
        while (!(ciaa.pra & 0x40));
601
 
602
        /* debounce */
603
        for (i = 0; i < 1000; i++);
604
 
605
        if (ciaa.pra & 0x40)
606
            break;
607
    }
608
}
609
 
610
void ami_serial_print (const char *str)
611
{
612
    while (*str) {
613
        if (*str == '\n') {
614
            custom.serdat = (unsigned char)'\r' | 0x100;
615
            while (!(custom.serdatr & 0x2000))
616
                ;
617
        }
618
        custom.serdat = (unsigned char)*str++ | 0x100;
619
        while (!(custom.serdatr & 0x2000))
620
            ;
621
    }
622
}
623
 
624
void amiga_debug_init (void)
625
{
626
    extern void (*debug_print_proc)(const char *);
627
 
628
    if (!strcmp( m68k_debug_device, "ser" )) {
629
        /* no initialization required (?) */
630
        debug_print_proc = ami_serial_print;
631
    } else if (!strcmp( m68k_debug_device, "mem" )) {
632
        /* already initialized by config_amiga() (needed only once) */
633
        debug_print_proc = ami_mem_print;
634
    }
635
}
636
 
637
void dbprintf(const char *fmt , ...)
638
{
639
        static char buf[1024];
640
        va_list args;
641
        extern void console_print (const char *str);
642
        extern int vsprintf(char * buf, const char * fmt, va_list args);
643
 
644
        va_start(args, fmt);
645
        vsprintf(buf, fmt, args);
646
        va_end(args);
647
 
648
        console_print (buf);
649
}
650
 
651
NORET_TYPE void amiga_reset( void )
652
    ATTRIB_NORET;
653
 
654
void amiga_reset (void)
655
{
656
  unsigned long jmp_addr040 = VTOP(&&jmp_addr_label040);
657
  unsigned long jmp_addr = VTOP(&&jmp_addr_label);
658
 
659
  cli();
660
  if (m68k_is040or060)
661
    /* Setup transparent translation registers for mapping
662
     * of 16 MB kernel segment before disabling translation
663
     */
664
    __asm__ __volatile__
665
      ("movel    %0,%/d0\n\t"
666
       "andl     #0xff000000,%/d0\n\t"
667
       "orw      #0xe020,%/d0\n\t"   /* map 16 MB, enable, cacheable */
668
       ".long    0x4e7b0004\n\t"   /* movec d0,itt0 */
669
       ".long    0x4e7b0006\n\t"   /* movec d0,dtt0 */
670
       "jmp      %0@\n\t"
671
       : /* no outputs */
672
       : "a" (jmp_addr040));
673
  else
674
    /* for 680[23]0, just disable translation and jump to the physical
675
     * address of the label
676
     */
677
    __asm__ __volatile__
678
      ("pmove  %/tc,%@\n\t"
679
       "bclr   #7,%@\n\t"
680
       "pmove  %@,%/tc\n\t"
681
       "jmp    %0@\n\t"
682
       : /* no outputs */
683
       : "a" (jmp_addr));
684
 jmp_addr_label040:
685
  /* disable translation on '040 now */
686
  __asm__ __volatile__
687
    ("moveq #0,%/d0\n\t"
688
     ".long 0x4e7b0003\n\t"         /* movec d0,tc; disable MMU */
689
     : /* no outputs */
690
     : /* no inputs */
691
     : "d0");
692
 
693
 jmp_addr_label:
694
  /* pickup reset address from AmigaOS ROM, reset devices and jump
695
   * to reset address
696
   */
697
  __asm__ __volatile__
698
    ("movew #0x2700,%/sr\n\t"
699
     "leal  0x01000000,%/a0\n\t"
700
     "subl  %/a0@(-0x14),%/a0\n\t"
701
     "movel %/a0@(4),%/a0\n\t"
702
     "subql #2,%/a0\n\t"
703
     "bra   1f\n\t"
704
     /* align on a longword boundary */
705
     __ALIGN_STR "\n"
706
     "1:\n\t"
707
     "reset\n\t"
708
     "jmp   %/a0@" : /* Just that gcc scans it for % escapes */ );
709
 
710
  for (;;);
711
 
712
}
713
 
714
extern void *amiga_chip_alloc(long size);
715
 
716
 
717
#define SAVEKMSG_MAXMEM         128*1024
718
 
719
 
720
#define SAVEKMSG_MAGIC1         0x53415645      /* 'SAVE' */
721
#define SAVEKMSG_MAGIC2         0x4B4D5347      /* 'KMSG' */
722
 
723
struct savekmsg {
724
    u_long magic1;              /* SAVEKMSG_MAGIC1 */
725
    u_long magic2;              /* SAVEKMSG_MAGIC2 */
726
    u_long magicptr;            /* address of magic1 */
727
    u_long size;
728
    char data[0];
729
};
730
 
731
static struct savekmsg *savekmsg = NULL;
732
 
733
 
734
static void ami_savekmsg_init(void)
735
{
736
    savekmsg = (struct savekmsg *)amiga_chip_alloc(SAVEKMSG_MAXMEM);
737
    savekmsg->magic1 = SAVEKMSG_MAGIC1;
738
    savekmsg->magic2 = SAVEKMSG_MAGIC2;
739
    savekmsg->magicptr = VTOP(savekmsg);
740
    savekmsg->size = 0;
741
}
742
 
743
 
744
static void ami_mem_print(const char *b)
745
{
746
    int len;
747
 
748
    for (len = 0; b[len]; len++);
749
    if (savekmsg->size+len <= SAVEKMSG_MAXMEM) {
750
        memcpy(savekmsg->data+savekmsg->size, b, len);
751
        savekmsg->size += len;
752
    }
753
}
754
 
755
 
756
void amiga_get_model(char *model)
757
{
758
    strcpy(model, "Amiga ");
759
    switch (boot_info.bi_amiga.model) {
760
        case AMI_500:
761
            strcat(model, "500");
762
            break;
763
        case AMI_500PLUS:
764
            strcat(model, "500+");
765
            break;
766
        case AMI_600:
767
            strcat(model, "600");
768
            break;
769
        case AMI_1000:
770
            strcat(model, "1000");
771
            break;
772
        case AMI_1200:
773
            strcat(model, "1200");
774
            break;
775
        case AMI_2000:
776
            strcat(model, "2000");
777
            break;
778
        case AMI_2500:
779
            strcat(model, "2500");
780
            break;
781
        case AMI_3000:
782
            strcat(model, "3000");
783
            break;
784
        case AMI_3000T:
785
            strcat(model, "3000T");
786
            break;
787
        case AMI_3000PLUS:
788
            strcat(model, "3000+");
789
            break;
790
        case AMI_4000:
791
            strcat(model, "4000");
792
            break;
793
        case AMI_4000T:
794
            strcat(model, "4000T");
795
            break;
796
        case AMI_CDTV:
797
            strcat(model, "CDTV");
798
            break;
799
        case AMI_CD32:
800
            strcat(model, "CD32");
801
            break;
802
        case AMI_DRACO:
803
            strcpy(model, "DRACO");
804
            break;
805
    }
806
}
807
 
808
 
809
int amiga_get_hardware_list(char *buffer)
810
{
811
    int len = 0;
812
 
813
    if (AMIGAHW_PRESENT(CHIP_RAM))
814
        len += sprintf(buffer+len, "Chip RAM:\t%ldK\n",
815
                       boot_info.bi_amiga.chip_size>>10);
816
    len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n",
817
                   boot_info.bi_amiga.psfreq, amiga_eclock);
818
    if (AMIGAHW_PRESENT(AMI_VIDEO)) {
819
        char *type;
820
        switch(boot_info.bi_amiga.chipset) {
821
            case CS_OCS:
822
                type = "OCS";
823
                break;
824
            case CS_ECS:
825
                type = "ECS";
826
                break;
827
            case CS_AGA:
828
                type = "AGA";
829
                break;
830
            default:
831
                type = "Old or Unknown";
832
                break;
833
        }
834
        len += sprintf(buffer+len, "Graphics:\t%s\n", type);
835
    }
836
 
837
#define AMIGAHW_ANNOUNCE(name, str)                             \
838
    if (AMIGAHW_PRESENT(name))                          \
839
        len += sprintf (buffer+len, "\t%s\n", str)
840
 
841
    len += sprintf (buffer + len, "Detected hardware:\n");
842
 
843
    AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video");
844
    AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter");
845
    AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer");
846
    AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio");
847
    AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller");
848
    AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)");
849
    AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)");
850
    AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)");
851
    AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)");
852
    AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive");
853
    AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard");
854
    AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port");
855
    AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port");
856
    AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port");
857
    AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)");
858
    AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)");
859
    AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM");
860
    AMIGAHW_ANNOUNCE(PAULA, "Paula 8364");
861
    AMIGAHW_ANNOUNCE(DENISE, "Denise 8362");
862
    AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373");
863
    AMIGAHW_ANNOUNCE(LISA, "Lisa 8375");
864
    AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371");
865
    AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370");
866
    AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372");
867
    AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372");
868
    AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374");
869
    AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374");
870
    AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick");
871
    if (AMIGAHW_PRESENT(ZORRO))
872
        len += sprintf(buffer+len, "\tZorro AutoConfig: %d Expansion Device%s\n",
873
                       boot_info.bi_amiga.num_autocon,
874
                       boot_info.bi_amiga.num_autocon == 1 ? "" : "s");
875
 
876
    return(len);
877
}

powered by: WebSVN 2.1.0

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