Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.19 953 lines 25 kB view raw
1#define m68k_debug_device debug_device 2 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 <linux/types.h> 16#include <linux/kernel.h> 17#include <linux/mm.h> 18#include <linux/kd.h> 19#include <linux/tty.h> 20#include <linux/console.h> 21#include <linux/init.h> 22#ifdef CONFIG_ZORRO 23#include <linux/zorro.h> 24#endif 25 26#include <asm/bootinfo.h> 27#include <asm/setup.h> 28#include <asm/system.h> 29#include <asm/pgtable.h> 30#include <asm/amigahw.h> 31#include <asm/amigaints.h> 32#include <asm/irq.h> 33#include <asm/machdep.h> 34#include <asm/io.h> 35 36unsigned long powerup_PCI_present; 37unsigned long powerup_BPPCPLUS_present; 38unsigned long amiga_model; 39unsigned long amiga_eclock; 40unsigned long amiga_masterclock; 41unsigned long amiga_colorclock; 42unsigned long amiga_chipset; 43unsigned char amiga_vblank; 44unsigned char amiga_psfreq; 45struct amiga_hw_present amiga_hw_present; 46 47static char s_a500[] __initdata = "A500"; 48static char s_a500p[] __initdata = "A500+"; 49static char s_a600[] __initdata = "A600"; 50static char s_a1000[] __initdata = "A1000"; 51static char s_a1200[] __initdata = "A1200"; 52static char s_a2000[] __initdata = "A2000"; 53static char s_a2500[] __initdata = "A2500"; 54static char s_a3000[] __initdata = "A3000"; 55static char s_a3000t[] __initdata = "A3000T"; 56static char s_a3000p[] __initdata = "A3000+"; 57static char s_a4000[] __initdata = "A4000"; 58static char s_a4000t[] __initdata = "A4000T"; 59static char s_cdtv[] __initdata = "CDTV"; 60static char s_cd32[] __initdata = "CD32"; 61static char s_draco[] __initdata = "Draco"; 62static char *amiga_models[] __initdata = { 63 s_a500, s_a500p, s_a600, s_a1000, s_a1200, s_a2000, s_a2500, s_a3000, 64 s_a3000t, s_a3000p, s_a4000, s_a4000t, s_cdtv, s_cd32, s_draco, 65}; 66 67static char amiga_model_name[13] = "Amiga "; 68 69extern char m68k_debug_device[]; 70 71static void amiga_sched_init(irqreturn_t (*handler)(int, void *, struct pt_regs *)); 72/* amiga specific irq functions */ 73extern void amiga_init_IRQ (void); 74extern void (*amiga_default_handler[]) (int, void *, struct pt_regs *); 75extern int amiga_request_irq (unsigned int irq, 76 void (*handler)(int, void *, struct pt_regs *), 77 unsigned long flags, const char *devname, 78 void *dev_id); 79extern void amiga_free_irq (unsigned int irq, void *dev_id); 80extern void amiga_enable_irq (unsigned int); 81extern void amiga_disable_irq (unsigned int); 82static void amiga_get_model(char *model); 83static int amiga_get_hardware_list(char *buffer); 84/* amiga specific timer functions */ 85static unsigned long amiga_gettimeoffset (void); 86static void a3000_gettod (int *, int *, int *, int *, int *, int *); 87static void a2000_gettod (int *, int *, int *, int *, int *, int *); 88static int amiga_hwclk (int, struct hwclk_time *); 89static int amiga_set_clock_mmss (unsigned long); 90static void amiga_reset (void); 91extern void amiga_init_sound(void); 92static void amiga_savekmsg_init(void); 93static void amiga_mem_console_write(struct console *co, const char *b, 94 unsigned int count); 95void amiga_serial_console_write(struct console *co, const char *s, 96 unsigned int count); 97static void amiga_debug_init(void); 98#ifdef CONFIG_HEARTBEAT 99static void amiga_heartbeat(int on); 100#endif 101 102static struct console amiga_console_driver = { 103 .name = "debug", 104 .flags = CON_PRINTBUFFER, 105 .index = -1, 106}; 107 108 109 /* 110 * Motherboard Resources present in all Amiga models 111 */ 112 113static struct { 114 struct resource _ciab, _ciaa, _custom, _kickstart; 115} mb_resources = { 116// { "Ranger Memory", 0x00c00000, 0x00c7ffff }, 117 ._ciab = { "CIA B", 0x00bfd000, 0x00bfdfff }, 118 ._ciaa = { "CIA A", 0x00bfe000, 0x00bfefff }, 119 ._custom = { "Custom I/O", 0x00dff000, 0x00dfffff }, 120 ._kickstart = { "Kickstart ROM", 0x00f80000, 0x00ffffff } 121}; 122 123static struct resource rtc_resource = { 124 NULL, 0x00dc0000, 0x00dcffff 125}; 126 127static struct resource ram_resource[NUM_MEMINFO]; 128 129 130 /* 131 * Parse an Amiga-specific record in the bootinfo 132 */ 133 134int amiga_parse_bootinfo(const struct bi_record *record) 135{ 136 int unknown = 0; 137 const unsigned long *data = record->data; 138 139 switch (record->tag) { 140 case BI_AMIGA_MODEL: 141 { 142 unsigned long d = *data; 143 144 powerup_PCI_present = d & 0x100; 145 amiga_model = d & 0xff; 146 } 147 break; 148 149 case BI_AMIGA_ECLOCK: 150 amiga_eclock = *data; 151 break; 152 153 case BI_AMIGA_CHIPSET: 154 amiga_chipset = *data; 155 break; 156 157 case BI_AMIGA_CHIP_SIZE: 158 amiga_chip_size = *(const int *)data; 159 break; 160 161 case BI_AMIGA_VBLANK: 162 amiga_vblank = *(const unsigned char *)data; 163 break; 164 165 case BI_AMIGA_PSFREQ: 166 amiga_psfreq = *(const unsigned char *)data; 167 break; 168 169 case BI_AMIGA_AUTOCON: 170#ifdef CONFIG_ZORRO 171 if (zorro_num_autocon < ZORRO_NUM_AUTO) { 172 const struct ConfigDev *cd = (struct ConfigDev *)data; 173 struct zorro_dev *dev = &zorro_autocon[zorro_num_autocon++]; 174 dev->rom = cd->cd_Rom; 175 dev->slotaddr = cd->cd_SlotAddr; 176 dev->slotsize = cd->cd_SlotSize; 177 dev->resource.start = (unsigned long)cd->cd_BoardAddr; 178 dev->resource.end = dev->resource.start+cd->cd_BoardSize-1; 179 } else 180 printk("amiga_parse_bootinfo: too many AutoConfig devices\n"); 181#endif /* CONFIG_ZORRO */ 182 break; 183 184 case BI_AMIGA_SERPER: 185 /* serial port period: ignored here */ 186 break; 187 188 case BI_AMIGA_PUP_BRIDGE: 189 powerup_PCI_present = *(const unsigned short *)data; 190 break; 191 192 case BI_AMIGA_BPPC_SCSI: 193 powerup_BPPCPLUS_present = *(const unsigned short *)data; 194 break; 195 196 default: 197 unknown = 1; 198 } 199 return(unknown); 200} 201 202 /* 203 * Identify builtin hardware 204 */ 205 206static void __init amiga_identify(void) 207{ 208 /* Fill in some default values, if necessary */ 209 if (amiga_eclock == 0) 210 amiga_eclock = 709379; 211 212 memset(&amiga_hw_present, 0, sizeof(amiga_hw_present)); 213 214 printk("Amiga hardware found: "); 215 if (amiga_model >= AMI_500 && amiga_model <= AMI_DRACO) { 216 printk("[%s] ", amiga_models[amiga_model-AMI_500]); 217 strcat(amiga_model_name, amiga_models[amiga_model-AMI_500]); 218 } 219 220 switch(amiga_model) { 221 case AMI_UNKNOWN: 222 goto Generic; 223 224 case AMI_600: 225 case AMI_1200: 226 AMIGAHW_SET(A1200_IDE); 227 AMIGAHW_SET(PCMCIA); 228 case AMI_500: 229 case AMI_500PLUS: 230 case AMI_1000: 231 case AMI_2000: 232 case AMI_2500: 233 AMIGAHW_SET(A2000_CLK); /* Is this correct for all models? */ 234 goto Generic; 235 236 case AMI_3000: 237 case AMI_3000T: 238 AMIGAHW_SET(AMBER_FF); 239 AMIGAHW_SET(MAGIC_REKICK); 240 /* fall through */ 241 case AMI_3000PLUS: 242 AMIGAHW_SET(A3000_SCSI); 243 AMIGAHW_SET(A3000_CLK); 244 AMIGAHW_SET(ZORRO3); 245 goto Generic; 246 247 case AMI_4000T: 248 AMIGAHW_SET(A4000_SCSI); 249 /* fall through */ 250 case AMI_4000: 251 AMIGAHW_SET(A4000_IDE); 252 AMIGAHW_SET(A3000_CLK); 253 AMIGAHW_SET(ZORRO3); 254 goto Generic; 255 256 case AMI_CDTV: 257 case AMI_CD32: 258 AMIGAHW_SET(CD_ROM); 259 AMIGAHW_SET(A2000_CLK); /* Is this correct? */ 260 goto Generic; 261 262 Generic: 263 AMIGAHW_SET(AMI_VIDEO); 264 AMIGAHW_SET(AMI_BLITTER); 265 AMIGAHW_SET(AMI_AUDIO); 266 AMIGAHW_SET(AMI_FLOPPY); 267 AMIGAHW_SET(AMI_KEYBOARD); 268 AMIGAHW_SET(AMI_MOUSE); 269 AMIGAHW_SET(AMI_SERIAL); 270 AMIGAHW_SET(AMI_PARALLEL); 271 AMIGAHW_SET(CHIP_RAM); 272 AMIGAHW_SET(PAULA); 273 274 switch(amiga_chipset) { 275 case CS_OCS: 276 case CS_ECS: 277 case CS_AGA: 278 switch (amiga_custom.deniseid & 0xf) { 279 case 0x0c: 280 AMIGAHW_SET(DENISE_HR); 281 break; 282 case 0x08: 283 AMIGAHW_SET(LISA); 284 break; 285 } 286 break; 287 default: 288 AMIGAHW_SET(DENISE); 289 break; 290 } 291 switch ((amiga_custom.vposr>>8) & 0x7f) { 292 case 0x00: 293 AMIGAHW_SET(AGNUS_PAL); 294 break; 295 case 0x10: 296 AMIGAHW_SET(AGNUS_NTSC); 297 break; 298 case 0x20: 299 case 0x21: 300 AMIGAHW_SET(AGNUS_HR_PAL); 301 break; 302 case 0x30: 303 case 0x31: 304 AMIGAHW_SET(AGNUS_HR_NTSC); 305 break; 306 case 0x22: 307 case 0x23: 308 AMIGAHW_SET(ALICE_PAL); 309 break; 310 case 0x32: 311 case 0x33: 312 AMIGAHW_SET(ALICE_NTSC); 313 break; 314 } 315 AMIGAHW_SET(ZORRO); 316 break; 317 318 case AMI_DRACO: 319 panic("No support for Draco yet"); 320 321 default: 322 panic("Unknown Amiga Model"); 323 } 324 325#define AMIGAHW_ANNOUNCE(name, str) \ 326 if (AMIGAHW_PRESENT(name)) \ 327 printk(str) 328 329 AMIGAHW_ANNOUNCE(AMI_VIDEO, "VIDEO "); 330 AMIGAHW_ANNOUNCE(AMI_BLITTER, "BLITTER "); 331 AMIGAHW_ANNOUNCE(AMBER_FF, "AMBER_FF "); 332 AMIGAHW_ANNOUNCE(AMI_AUDIO, "AUDIO "); 333 AMIGAHW_ANNOUNCE(AMI_FLOPPY, "FLOPPY "); 334 AMIGAHW_ANNOUNCE(A3000_SCSI, "A3000_SCSI "); 335 AMIGAHW_ANNOUNCE(A4000_SCSI, "A4000_SCSI "); 336 AMIGAHW_ANNOUNCE(A1200_IDE, "A1200_IDE "); 337 AMIGAHW_ANNOUNCE(A4000_IDE, "A4000_IDE "); 338 AMIGAHW_ANNOUNCE(CD_ROM, "CD_ROM "); 339 AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "KEYBOARD "); 340 AMIGAHW_ANNOUNCE(AMI_MOUSE, "MOUSE "); 341 AMIGAHW_ANNOUNCE(AMI_SERIAL, "SERIAL "); 342 AMIGAHW_ANNOUNCE(AMI_PARALLEL, "PARALLEL "); 343 AMIGAHW_ANNOUNCE(A2000_CLK, "A2000_CLK "); 344 AMIGAHW_ANNOUNCE(A3000_CLK, "A3000_CLK "); 345 AMIGAHW_ANNOUNCE(CHIP_RAM, "CHIP_RAM "); 346 AMIGAHW_ANNOUNCE(PAULA, "PAULA "); 347 AMIGAHW_ANNOUNCE(DENISE, "DENISE "); 348 AMIGAHW_ANNOUNCE(DENISE_HR, "DENISE_HR "); 349 AMIGAHW_ANNOUNCE(LISA, "LISA "); 350 AMIGAHW_ANNOUNCE(AGNUS_PAL, "AGNUS_PAL "); 351 AMIGAHW_ANNOUNCE(AGNUS_NTSC, "AGNUS_NTSC "); 352 AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "AGNUS_HR_PAL "); 353 AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "AGNUS_HR_NTSC "); 354 AMIGAHW_ANNOUNCE(ALICE_PAL, "ALICE_PAL "); 355 AMIGAHW_ANNOUNCE(ALICE_NTSC, "ALICE_NTSC "); 356 AMIGAHW_ANNOUNCE(MAGIC_REKICK, "MAGIC_REKICK "); 357 AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA "); 358 if (AMIGAHW_PRESENT(ZORRO)) 359 printk("ZORRO%s ", AMIGAHW_PRESENT(ZORRO3) ? "3" : ""); 360 printk("\n"); 361 362#undef AMIGAHW_ANNOUNCE 363} 364 365 /* 366 * Setup the Amiga configuration info 367 */ 368 369void __init config_amiga(void) 370{ 371 int i; 372 373 amiga_debug_init(); 374 amiga_identify(); 375 376 /* Some APUS boxes may have PCI memory, but ... */ 377 iomem_resource.name = "Memory"; 378 for (i = 0; i < 4; i++) 379 request_resource(&iomem_resource, &((struct resource *)&mb_resources)[i]); 380 381 mach_sched_init = amiga_sched_init; 382 mach_init_IRQ = amiga_init_IRQ; 383#ifndef CONFIG_APUS 384 mach_default_handler = &amiga_default_handler; 385 mach_request_irq = amiga_request_irq; 386 mach_free_irq = amiga_free_irq; 387 enable_irq = amiga_enable_irq; 388 disable_irq = amiga_disable_irq; 389#endif 390 mach_get_model = amiga_get_model; 391 mach_get_hardware_list = amiga_get_hardware_list; 392 mach_gettimeoffset = amiga_gettimeoffset; 393 if (AMIGAHW_PRESENT(A3000_CLK)){ 394 mach_gettod = a3000_gettod; 395 rtc_resource.name = "A3000 RTC"; 396 request_resource(&iomem_resource, &rtc_resource); 397 } 398 else{ /* if (AMIGAHW_PRESENT(A2000_CLK)) */ 399 mach_gettod = a2000_gettod; 400 rtc_resource.name = "A2000 RTC"; 401 request_resource(&iomem_resource, &rtc_resource); 402 } 403 404 mach_max_dma_address = 0xffffffff; /* 405 * default MAX_DMA=0xffffffff 406 * on all machines. If we don't 407 * do so, the SCSI code will not 408 * be able to allocate any mem 409 * for transfers, unless we are 410 * dealing with a Z2 mem only 411 * system. /Jes 412 */ 413 414 mach_hwclk = amiga_hwclk; 415 mach_set_clock_mmss = amiga_set_clock_mmss; 416 mach_reset = amiga_reset; 417#ifdef CONFIG_HEARTBEAT 418 mach_heartbeat = amiga_heartbeat; 419#endif 420 421 /* Fill in the clock values (based on the 700 kHz E-Clock) */ 422 amiga_masterclock = 40*amiga_eclock; /* 28 MHz */ 423 amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */ 424 425 /* clear all DMA bits */ 426 amiga_custom.dmacon = DMAF_ALL; 427 /* ensure that the DMA master bit is set */ 428 amiga_custom.dmacon = DMAF_SETCLR | DMAF_MASTER; 429 430 /* request all RAM */ 431 for (i = 0; i < m68k_num_memory; i++) { 432 ram_resource[i].name = 433 (m68k_memory[i].addr >= 0x01000000) ? "32-bit Fast RAM" : 434 (m68k_memory[i].addr < 0x00c00000) ? "16-bit Fast RAM" : 435 "16-bit Slow RAM"; 436 ram_resource[i].start = m68k_memory[i].addr; 437 ram_resource[i].end = m68k_memory[i].addr+m68k_memory[i].size-1; 438 request_resource(&iomem_resource, &ram_resource[i]); 439 } 440 441 /* initialize chipram allocator */ 442 amiga_chip_init (); 443 444 /* debugging using chipram */ 445 if (!strcmp( m68k_debug_device, "mem" )){ 446 if (!AMIGAHW_PRESENT(CHIP_RAM)) 447 printk("Warning: no chipram present for debugging\n"); 448 else { 449 amiga_savekmsg_init(); 450 amiga_console_driver.write = amiga_mem_console_write; 451 register_console(&amiga_console_driver); 452 } 453 } 454 455 /* our beloved beeper */ 456 if (AMIGAHW_PRESENT(AMI_AUDIO)) 457 amiga_init_sound(); 458 459 /* 460 * if it is an A3000, set the magic bit that forces 461 * a hard rekick 462 */ 463 if (AMIGAHW_PRESENT(MAGIC_REKICK)) 464 *(unsigned char *)ZTWO_VADDR(0xde0002) |= 0x80; 465} 466 467static unsigned short jiffy_ticks; 468 469static void __init amiga_sched_init(irqreturn_t (*timer_routine)(int, void *, 470 struct pt_regs *)) 471{ 472 static struct resource sched_res = { 473 "timer", 0x00bfd400, 0x00bfd5ff, 474 }; 475 jiffy_ticks = (amiga_eclock+HZ/2)/HZ; 476 477 if (request_resource(&mb_resources._ciab, &sched_res)) 478 printk("Cannot allocate ciab.ta{lo,hi}\n"); 479 ciab.cra &= 0xC0; /* turn off timer A, continuous mode, from Eclk */ 480 ciab.talo = jiffy_ticks % 256; 481 ciab.tahi = jiffy_ticks / 256; 482 483 /* install interrupt service routine for CIAB Timer A 484 * 485 * Please don't change this to use ciaa, as it interferes with the 486 * SCSI code. We'll have to take a look at this later 487 */ 488 request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL); 489 /* start timer */ 490 ciab.cra |= 0x11; 491} 492 493#define TICK_SIZE 10000 494 495extern unsigned char cia_get_irq_mask(unsigned int irq); 496 497/* This is always executed with interrupts disabled. */ 498static unsigned long amiga_gettimeoffset (void) 499{ 500 unsigned short hi, lo, hi2; 501 unsigned long ticks, offset = 0; 502 503 /* read CIA B timer A current value */ 504 hi = ciab.tahi; 505 lo = ciab.talo; 506 hi2 = ciab.tahi; 507 508 if (hi != hi2) { 509 lo = ciab.talo; 510 hi = hi2; 511 } 512 513 ticks = hi << 8 | lo; 514 515 if (ticks > jiffy_ticks / 2) 516 /* check for pending interrupt */ 517 if (cia_get_irq_mask(IRQ_AMIGA_CIAB) & CIA_ICR_TA) 518 offset = 10000; 519 520 ticks = jiffy_ticks - ticks; 521 ticks = (10000 * ticks) / jiffy_ticks; 522 523 return ticks + offset; 524} 525 526static void a3000_gettod (int *yearp, int *monp, int *dayp, 527 int *hourp, int *minp, int *secp) 528{ 529 volatile struct tod3000 *tod = TOD_3000; 530 531 tod->cntrl1 = TOD3000_CNTRL1_HOLD; 532 533 *secp = tod->second1 * 10 + tod->second2; 534 *minp = tod->minute1 * 10 + tod->minute2; 535 *hourp = tod->hour1 * 10 + tod->hour2; 536 *dayp = tod->day1 * 10 + tod->day2; 537 *monp = tod->month1 * 10 + tod->month2; 538 *yearp = tod->year1 * 10 + tod->year2; 539 540 tod->cntrl1 = TOD3000_CNTRL1_FREE; 541} 542 543static void a2000_gettod (int *yearp, int *monp, int *dayp, 544 int *hourp, int *minp, int *secp) 545{ 546 volatile struct tod2000 *tod = TOD_2000; 547 548 tod->cntrl1 = TOD2000_CNTRL1_HOLD; 549 550 while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) 551 ; 552 553 *secp = tod->second1 * 10 + tod->second2; 554 *minp = tod->minute1 * 10 + tod->minute2; 555 *hourp = (tod->hour1 & 3) * 10 + tod->hour2; 556 *dayp = tod->day1 * 10 + tod->day2; 557 *monp = tod->month1 * 10 + tod->month2; 558 *yearp = tod->year1 * 10 + tod->year2; 559 560 if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){ 561 if (!(tod->hour1 & TOD2000_HOUR1_PM) && *hourp == 12) 562 *hourp = 0; 563 else if ((tod->hour1 & TOD2000_HOUR1_PM) && *hourp != 12) 564 *hourp += 12; 565 } 566 567 tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD; 568} 569 570static int amiga_hwclk(int op, struct hwclk_time *t) 571{ 572 if (AMIGAHW_PRESENT(A3000_CLK)) { 573 volatile struct tod3000 *tod = TOD_3000; 574 575 tod->cntrl1 = TOD3000_CNTRL1_HOLD; 576 577 if (!op) { /* read */ 578 t->sec = tod->second1 * 10 + tod->second2; 579 t->min = tod->minute1 * 10 + tod->minute2; 580 t->hour = tod->hour1 * 10 + tod->hour2; 581 t->day = tod->day1 * 10 + tod->day2; 582 t->wday = tod->weekday; 583 t->mon = tod->month1 * 10 + tod->month2 - 1; 584 t->year = tod->year1 * 10 + tod->year2; 585 if (t->year <= 69) 586 t->year += 100; 587 } else { 588 tod->second1 = t->sec / 10; 589 tod->second2 = t->sec % 10; 590 tod->minute1 = t->min / 10; 591 tod->minute2 = t->min % 10; 592 tod->hour1 = t->hour / 10; 593 tod->hour2 = t->hour % 10; 594 tod->day1 = t->day / 10; 595 tod->day2 = t->day % 10; 596 if (t->wday != -1) 597 tod->weekday = t->wday; 598 tod->month1 = (t->mon + 1) / 10; 599 tod->month2 = (t->mon + 1) % 10; 600 if (t->year >= 100) 601 t->year -= 100; 602 tod->year1 = t->year / 10; 603 tod->year2 = t->year % 10; 604 } 605 606 tod->cntrl1 = TOD3000_CNTRL1_FREE; 607 } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { 608 volatile struct tod2000 *tod = TOD_2000; 609 610 tod->cntrl1 = TOD2000_CNTRL1_HOLD; 611 612 while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) 613 ; 614 615 if (!op) { /* read */ 616 t->sec = tod->second1 * 10 + tod->second2; 617 t->min = tod->minute1 * 10 + tod->minute2; 618 t->hour = (tod->hour1 & 3) * 10 + tod->hour2; 619 t->day = tod->day1 * 10 + tod->day2; 620 t->wday = tod->weekday; 621 t->mon = tod->month1 * 10 + tod->month2 - 1; 622 t->year = tod->year1 * 10 + tod->year2; 623 if (t->year <= 69) 624 t->year += 100; 625 626 if (!(tod->cntrl3 & TOD2000_CNTRL3_24HMODE)){ 627 if (!(tod->hour1 & TOD2000_HOUR1_PM) && t->hour == 12) 628 t->hour = 0; 629 else if ((tod->hour1 & TOD2000_HOUR1_PM) && t->hour != 12) 630 t->hour += 12; 631 } 632 } else { 633 tod->second1 = t->sec / 10; 634 tod->second2 = t->sec % 10; 635 tod->minute1 = t->min / 10; 636 tod->minute2 = t->min % 10; 637 if (tod->cntrl3 & TOD2000_CNTRL3_24HMODE) 638 tod->hour1 = t->hour / 10; 639 else if (t->hour >= 12) 640 tod->hour1 = TOD2000_HOUR1_PM + 641 (t->hour - 12) / 10; 642 else 643 tod->hour1 = t->hour / 10; 644 tod->hour2 = t->hour % 10; 645 tod->day1 = t->day / 10; 646 tod->day2 = t->day % 10; 647 if (t->wday != -1) 648 tod->weekday = t->wday; 649 tod->month1 = (t->mon + 1) / 10; 650 tod->month2 = (t->mon + 1) % 10; 651 if (t->year >= 100) 652 t->year -= 100; 653 tod->year1 = t->year / 10; 654 tod->year2 = t->year % 10; 655 } 656 657 tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD; 658 } 659 660 return 0; 661} 662 663static int amiga_set_clock_mmss (unsigned long nowtime) 664{ 665 short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; 666 667 if (AMIGAHW_PRESENT(A3000_CLK)) { 668 volatile struct tod3000 *tod = TOD_3000; 669 670 tod->cntrl1 = TOD3000_CNTRL1_HOLD; 671 672 tod->second1 = real_seconds / 10; 673 tod->second2 = real_seconds % 10; 674 tod->minute1 = real_minutes / 10; 675 tod->minute2 = real_minutes % 10; 676 677 tod->cntrl1 = TOD3000_CNTRL1_FREE; 678 } else /* if (AMIGAHW_PRESENT(A2000_CLK)) */ { 679 volatile struct tod2000 *tod = TOD_2000; 680 681 tod->cntrl1 = TOD2000_CNTRL1_HOLD; 682 683 while (tod->cntrl1 & TOD2000_CNTRL1_BUSY) 684 ; 685 686 tod->second1 = real_seconds / 10; 687 tod->second2 = real_seconds % 10; 688 tod->minute1 = real_minutes / 10; 689 tod->minute2 = real_minutes % 10; 690 691 tod->cntrl1 &= ~TOD2000_CNTRL1_HOLD; 692 } 693 694 return 0; 695} 696 697static NORET_TYPE void amiga_reset( void ) 698 ATTRIB_NORET; 699 700static void amiga_reset (void) 701{ 702 for (;;); 703} 704 705 706 /* 707 * Debugging 708 */ 709 710#define SAVEKMSG_MAXMEM 128*1024 711 712#define SAVEKMSG_MAGIC1 0x53415645 /* 'SAVE' */ 713#define SAVEKMSG_MAGIC2 0x4B4D5347 /* 'KMSG' */ 714 715struct savekmsg { 716 unsigned long magic1; /* SAVEKMSG_MAGIC1 */ 717 unsigned long magic2; /* SAVEKMSG_MAGIC2 */ 718 unsigned long magicptr; /* address of magic1 */ 719 unsigned long size; 720 char data[0]; 721}; 722 723static struct savekmsg *savekmsg = NULL; 724 725static void amiga_mem_console_write(struct console *co, const char *s, 726 unsigned int count) 727{ 728 if (savekmsg->size+count <= SAVEKMSG_MAXMEM-sizeof(struct savekmsg)) { 729 memcpy(savekmsg->data+savekmsg->size, s, count); 730 savekmsg->size += count; 731 } 732} 733 734static void amiga_savekmsg_init(void) 735{ 736 static struct resource debug_res = { "Debug" }; 737 738 savekmsg = amiga_chip_alloc_res(SAVEKMSG_MAXMEM, &debug_res); 739 savekmsg->magic1 = SAVEKMSG_MAGIC1; 740 savekmsg->magic2 = SAVEKMSG_MAGIC2; 741 savekmsg->magicptr = virt_to_phys(savekmsg); 742 savekmsg->size = 0; 743} 744 745static void amiga_serial_putc(char c) 746{ 747 amiga_custom.serdat = (unsigned char)c | 0x100; 748 mb(); 749 while (!(amiga_custom.serdatr & 0x2000)) 750 ; 751} 752 753void amiga_serial_console_write(struct console *co, const char *s, 754 unsigned int count) 755{ 756#if 0 /* def CONFIG_KGDB */ 757 /* FIXME:APUS GDB doesn't seem to like O-packages before it is 758 properly connected with the target. */ 759 __gdb_output_string (s, count); 760#else 761 while (count--) { 762 if (*s == '\n') 763 amiga_serial_putc('\r'); 764 amiga_serial_putc(*s++); 765 } 766#endif 767} 768 769#ifdef CONFIG_SERIAL_CONSOLE 770void amiga_serial_puts(const char *s) 771{ 772 amiga_serial_console_write(NULL, s, strlen(s)); 773} 774 775int amiga_serial_console_wait_key(struct console *co) 776{ 777 int ch; 778 779 while (!(amiga_custom.intreqr & IF_RBF)) 780 barrier(); 781 ch = amiga_custom.serdatr & 0xff; 782 /* clear the interrupt, so that another character can be read */ 783 amiga_custom.intreq = IF_RBF; 784 return ch; 785} 786 787void amiga_serial_gets(struct console *co, char *s, int len) 788{ 789 int ch, cnt = 0; 790 791 while (1) { 792 ch = amiga_serial_console_wait_key(co); 793 794 /* Check for backspace. */ 795 if (ch == 8 || ch == 127) { 796 if (cnt == 0) { 797 amiga_serial_putc('\007'); 798 continue; 799 } 800 cnt--; 801 amiga_serial_puts("\010 \010"); 802 continue; 803 } 804 805 /* Check for enter. */ 806 if (ch == 10 || ch == 13) 807 break; 808 809 /* See if line is too long. */ 810 if (cnt >= len + 1) { 811 amiga_serial_putc(7); 812 cnt--; 813 continue; 814 } 815 816 /* Store and echo character. */ 817 s[cnt++] = ch; 818 amiga_serial_putc(ch); 819 } 820 /* Print enter. */ 821 amiga_serial_puts("\r\n"); 822 s[cnt] = 0; 823} 824#endif 825 826static void __init amiga_debug_init(void) 827{ 828 if (!strcmp( m68k_debug_device, "ser" )) { 829 /* no initialization required (?) */ 830 amiga_console_driver.write = amiga_serial_console_write; 831 register_console(&amiga_console_driver); 832 } 833} 834 835#ifdef CONFIG_HEARTBEAT 836static void amiga_heartbeat(int on) 837{ 838 if (on) 839 ciaa.pra &= ~2; 840 else 841 ciaa.pra |= 2; 842} 843#endif 844 845 /* 846 * Amiga specific parts of /proc 847 */ 848 849static void amiga_get_model(char *model) 850{ 851 strcpy(model, amiga_model_name); 852} 853 854 855static int amiga_get_hardware_list(char *buffer) 856{ 857 int len = 0; 858 859 if (AMIGAHW_PRESENT(CHIP_RAM)) 860 len += sprintf(buffer+len, "Chip RAM:\t%ldK\n", amiga_chip_size>>10); 861 len += sprintf(buffer+len, "PS Freq:\t%dHz\nEClock Freq:\t%ldHz\n", 862 amiga_psfreq, amiga_eclock); 863 if (AMIGAHW_PRESENT(AMI_VIDEO)) { 864 char *type; 865 switch(amiga_chipset) { 866 case CS_OCS: 867 type = "OCS"; 868 break; 869 case CS_ECS: 870 type = "ECS"; 871 break; 872 case CS_AGA: 873 type = "AGA"; 874 break; 875 default: 876 type = "Old or Unknown"; 877 break; 878 } 879 len += sprintf(buffer+len, "Graphics:\t%s\n", type); 880 } 881 882#define AMIGAHW_ANNOUNCE(name, str) \ 883 if (AMIGAHW_PRESENT(name)) \ 884 len += sprintf (buffer+len, "\t%s\n", str) 885 886 len += sprintf (buffer + len, "Detected hardware:\n"); 887 888 AMIGAHW_ANNOUNCE(AMI_VIDEO, "Amiga Video"); 889 AMIGAHW_ANNOUNCE(AMI_BLITTER, "Blitter"); 890 AMIGAHW_ANNOUNCE(AMBER_FF, "Amber Flicker Fixer"); 891 AMIGAHW_ANNOUNCE(AMI_AUDIO, "Amiga Audio"); 892 AMIGAHW_ANNOUNCE(AMI_FLOPPY, "Floppy Controller"); 893 AMIGAHW_ANNOUNCE(A3000_SCSI, "SCSI Controller WD33C93 (A3000 style)"); 894 AMIGAHW_ANNOUNCE(A4000_SCSI, "SCSI Controller NCR53C710 (A4000T style)"); 895 AMIGAHW_ANNOUNCE(A1200_IDE, "IDE Interface (A1200 style)"); 896 AMIGAHW_ANNOUNCE(A4000_IDE, "IDE Interface (A4000 style)"); 897 AMIGAHW_ANNOUNCE(CD_ROM, "Internal CD ROM drive"); 898 AMIGAHW_ANNOUNCE(AMI_KEYBOARD, "Keyboard"); 899 AMIGAHW_ANNOUNCE(AMI_MOUSE, "Mouse Port"); 900 AMIGAHW_ANNOUNCE(AMI_SERIAL, "Serial Port"); 901 AMIGAHW_ANNOUNCE(AMI_PARALLEL, "Parallel Port"); 902 AMIGAHW_ANNOUNCE(A2000_CLK, "Hardware Clock (A2000 style)"); 903 AMIGAHW_ANNOUNCE(A3000_CLK, "Hardware Clock (A3000 style)"); 904 AMIGAHW_ANNOUNCE(CHIP_RAM, "Chip RAM"); 905 AMIGAHW_ANNOUNCE(PAULA, "Paula 8364"); 906 AMIGAHW_ANNOUNCE(DENISE, "Denise 8362"); 907 AMIGAHW_ANNOUNCE(DENISE_HR, "Denise 8373"); 908 AMIGAHW_ANNOUNCE(LISA, "Lisa 8375"); 909 AMIGAHW_ANNOUNCE(AGNUS_PAL, "Normal/Fat PAL Agnus 8367/8371"); 910 AMIGAHW_ANNOUNCE(AGNUS_NTSC, "Normal/Fat NTSC Agnus 8361/8370"); 911 AMIGAHW_ANNOUNCE(AGNUS_HR_PAL, "Fat Hires PAL Agnus 8372"); 912 AMIGAHW_ANNOUNCE(AGNUS_HR_NTSC, "Fat Hires NTSC Agnus 8372"); 913 AMIGAHW_ANNOUNCE(ALICE_PAL, "PAL Alice 8374"); 914 AMIGAHW_ANNOUNCE(ALICE_NTSC, "NTSC Alice 8374"); 915 AMIGAHW_ANNOUNCE(MAGIC_REKICK, "Magic Hard Rekick"); 916 AMIGAHW_ANNOUNCE(PCMCIA, "PCMCIA Slot"); 917 if (AMIGAHW_PRESENT(ZORRO)) 918 len += sprintf(buffer+len, "\tZorro II%s AutoConfig: %d Expansion " 919 "Device%s\n", 920 AMIGAHW_PRESENT(ZORRO3) ? "I" : "", 921 zorro_num_autocon, zorro_num_autocon == 1 ? "" : "s"); 922 923#undef AMIGAHW_ANNOUNCE 924 925 return(len); 926} 927 928#ifdef CONFIG_APUS 929int get_hardware_list(char *buffer) 930{ 931 extern int get_cpuinfo(char *buffer); 932 int len = 0; 933 char model[80]; 934 u_long mem; 935 int i; 936 937 if (mach_get_model) 938 mach_get_model(model); 939 else 940 strcpy(model, "Unknown PowerPC"); 941 942 len += sprintf(buffer+len, "Model:\t\t%s\n", model); 943 len += get_cpuinfo(buffer+len); 944 for (mem = 0, i = 0; i < m68k_realnum_memory; i++) 945 mem += m68k_memory[i].size; 946 len += sprintf(buffer+len, "System Memory:\t%ldK\n", mem>>10); 947 948 if (mach_get_hardware_list) 949 len += mach_get_hardware_list(buffer+len); 950 951 return(len); 952} 953#endif