* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / ppc / kernel / chrp_setup.c
blob2739c541daa119f747b23cce1f7a6b24854aa150
1 /*
2 * linux/arch/ppc/kernel/setup.c
4 * Copyright (C) 1995 Linus Torvalds
5 * Adapted from 'alpha' version by Gary Thomas
6 * Modified by Cort Dougan (cort@cs.nmt.edu)
7 */
9 /*
10 * bootup setup stuff..
13 #include <linux/config.h>
14 #include <linux/module.h>
15 #include <linux/errno.h>
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
18 #include <linux/mm.h>
19 #include <linux/stddef.h>
20 #include <linux/unistd.h>
21 #include <linux/ptrace.h>
22 #include <linux/malloc.h>
23 #include <linux/user.h>
24 #include <linux/a.out.h>
25 #include <linux/tty.h>
26 #include <linux/major.h>
27 #include <linux/interrupt.h>
28 #include <linux/reboot.h>
29 #include <linux/init.h>
30 #include <linux/blk.h>
31 #include <linux/ioport.h>
32 #include <linux/console.h>
33 #include <linux/pci.h>
34 #include <linux/openpic.h>
35 #include <linux/version.h>
36 #include <linux/adb.h>
37 #include <linux/module.h>
39 #include <asm/mmu.h>
40 #include <asm/processor.h>
41 #include <asm/io.h>
42 #include <asm/pgtable.h>
43 #include <linux/ide.h>
44 #include <asm/ide.h>
45 #include <asm/prom.h>
46 #include <asm/gg2.h>
47 #include <asm/pci-bridge.h>
48 #include <asm/dma.h>
49 #include <asm/machdep.h>
50 #include <asm/irq.h>
51 #include <asm/hydra.h>
52 #include <asm/keyboard.h>
54 #include "time.h"
55 #include "local_irq.h"
56 #include "i8259.h"
57 #include "open_pic.h"
59 extern volatile unsigned char *chrp_int_ack_special;
61 unsigned long chrp_get_rtc_time(void);
62 int chrp_set_rtc_time(unsigned long nowtime);
63 void chrp_calibrate_decr(void);
64 void chrp_time_init(void);
66 void chrp_setup_pci_ptrs(void);
67 extern void chrp_progress(char *, unsigned short);
68 void chrp_event_scan(void);
70 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
71 extern int pckbd_getkeycode(unsigned int scancode);
72 extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
73 char raw_mode);
74 extern char pckbd_unexpected_up(unsigned char keycode);
75 extern void pckbd_leds(unsigned char leds);
76 extern void pckbd_init_hw(void);
77 extern unsigned char pckbd_sysrq_xlate[128];
78 extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);
79 extern int mackbd_getkeycode(unsigned int scancode);
80 extern int mackbd_translate(unsigned char scancode, unsigned char *keycode,
81 char raw_mode);
82 extern char mackbd_unexpected_up(unsigned char keycode);
83 extern void mackbd_leds(unsigned char leds);
84 extern void mackbd_init_hw(void);
85 extern unsigned char mackbd_sysrq_xlate[128];
87 kdev_t boot_dev;
89 extern PTE *Hash, *Hash_end;
90 extern unsigned long Hash_size, Hash_mask;
91 extern int probingmem;
92 extern unsigned long loops_per_sec;
94 unsigned long empty_zero_page[1024];
96 #ifdef CONFIG_BLK_DEV_RAM
97 extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
98 extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
99 extern int rd_image_start; /* starting block # of image */
100 #endif
102 static const char *gg2_memtypes[4] = {
103 "FPM", "SDRAM", "EDO", "BEDO"
105 static const char *gg2_cachesizes[4] = {
106 "256 KB", "512 KB", "1 MB", "Reserved"
108 static const char *gg2_cachetypes[4] = {
109 "Asynchronous", "Reserved", "Flow-Through Synchronous",
110 "Pipelined Synchronous"
112 static const char *gg2_cachemodes[4] = {
113 "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
117 chrp_get_cpuinfo(char *buffer)
119 int i, len, sdramen;
120 unsigned int t;
121 struct device_node *root;
122 const char *model = "";
124 root = find_path_device("/");
125 if (root)
126 model = get_property(root, "model", NULL);
127 len = sprintf(buffer,"machine\t\t: CHRP %s\n", model);
129 /* longtrail (goldengate) stuff */
130 if ( !strncmp( model, "IBM,LongTrail", 9 ) )
132 /* VLSI VAS96011/12 `Golden Gate 2' */
133 /* Memory banks */
134 sdramen = (in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+
135 GG2_PCI_DRAM_CTRL))
136 >>31) & 1;
137 for (i = 0; i < (sdramen ? 4 : 6); i++) {
138 t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+
139 GG2_PCI_DRAM_BANK0+
140 i*4));
141 if (!(t & 1))
142 continue;
143 switch ((t>>8) & 0x1f) {
144 case 0x1f:
145 model = "4 MB";
146 break;
147 case 0x1e:
148 model = "8 MB";
149 break;
150 case 0x1c:
151 model = "16 MB";
152 break;
153 case 0x18:
154 model = "32 MB";
155 break;
156 case 0x10:
157 model = "64 MB";
158 break;
159 case 0x00:
160 model = "128 MB";
161 break;
162 default:
163 model = "Reserved";
164 break;
166 len += sprintf(buffer+len, "memory bank %d\t: %s %s\n", i, model,
167 gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
169 /* L2 cache */
170 t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+GG2_PCI_CC_CTRL));
171 len += sprintf(buffer+len, "board l2\t: %s %s (%s)\n",
172 gg2_cachesizes[(t>>7) & 3],
173 gg2_cachetypes[(t>>2) & 3],
174 gg2_cachemodes[t & 3]);
176 return len;
180 * Fixes for the National Semiconductor PC78308VUL SuperI/O
182 * Some versions of Open Firmware incorrectly initialize the IRQ settings
183 * for keyboard and mouse
185 static inline void __init sio_write(u8 val, u8 index)
187 outb(index, 0x15c);
188 outb(val, 0x15d);
191 static inline u8 __init sio_read(u8 index)
193 outb(index, 0x15c);
194 return inb(0x15d);
197 static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
198 u8 type)
200 u8 level0, type0, active;
202 /* select logical device */
203 sio_write(device, 0x07);
204 active = sio_read(0x30);
205 level0 = sio_read(0x70);
206 type0 = sio_read(0x71);
207 printk("sio: %s irq level %d, type %d, %sactive: ", name, level0, type0,
208 !active ? "in" : "");
209 if (level0 == level && type0 == type && active)
210 printk("OK\n");
211 else {
212 printk("remapping to level %d, type %d, active\n", level, type);
213 sio_write(0x01, 0x30);
214 sio_write(level, 0x70);
215 sio_write(type, 0x71);
220 static void __init sio_init(void)
222 /* logical device 0 (KBC/Keyboard) */
223 sio_fixup_irq("keyboard", 0, 1, 2);
224 /* select logical device 1 (KBC/Mouse) */
225 sio_fixup_irq("mouse", 1, 12, 2);
229 void __init
230 chrp_setup_arch(unsigned long * memory_start_p, unsigned long * memory_end_p)
232 extern char cmd_line[];
233 struct device_node *device;
235 /* init to some ~sane value until calibrate_delay() runs */
236 loops_per_sec = 50000000;
238 #ifdef CONFIG_BLK_DEV_INITRD
239 /* this is fine for chrp */
240 initrd_below_start_ok = 1;
242 if (initrd_start)
243 ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
244 else
245 #endif
246 ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
248 printk("Boot arguments: %s\n", cmd_line);
250 request_region(0x20,0x20,"pic1");
251 request_region(0xa0,0x20,"pic2");
252 request_region(0x00,0x20,"dma1");
253 request_region(0x40,0x20,"timer");
254 request_region(0x80,0x10,"dma page reg");
255 request_region(0xc0,0x20,"dma2");
257 /* PCI bridge config space access area -
258 * appears to be not in devtree on longtrail. */
259 ioremap(GG2_PCI_CONFIG_BASE, 0x80000);
261 * Temporary fixes for PCI devices.
262 * -- Geert
264 hydra_init(); /* Mac I/O */
266 /* Some IBM machines don't have the hydra -- Cort */
267 if ( !OpenPIC )
269 OpenPIC = (struct OpenPIC *)*(unsigned long *)get_property(
270 find_path_device("/"), "platform-open-pic", NULL);
271 OpenPIC = ioremap((unsigned long)OpenPIC, sizeof(struct OpenPIC));
275 * Fix the Super I/O configuration
277 sio_init();
278 #ifdef CONFIG_DUMMY_CONSOLE
279 conswitchp = &dummy_con;
280 #endif
281 *memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p);
283 /* Get the event scan rate for the rtas so we know how
284 * often it expects a heartbeat. -- Cort
286 if ( rtas_data )
288 struct property *p;
289 device = find_devices("rtas");
290 for ( p = device->properties;
291 p && strncmp(p->name, "rtas-event-scan-rate", 20);
292 p = p->next )
293 /* nothing */ ;
294 if ( p && *(unsigned long *)p->value )
296 ppc_md.heartbeat = chrp_event_scan;
297 ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1;
298 ppc_md.heartbeat_count = 1;
299 printk("RTAS Event Scan Rate: %lu (%lu jiffies)\n",
300 *(unsigned long *)p->value, ppc_md.heartbeat_reset );
305 void
306 chrp_event_scan(void)
308 unsigned char log[1024];
309 unsigned long ret = 0;
310 /* XXX: we should loop until the hardware says no more error logs -- Cort */
311 call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0,
312 __pa(log), 1024 );
313 ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
316 void
317 chrp_restart(char *cmd)
319 printk("RTAS system-reboot returned %d\n",
320 call_rtas("system-reboot", 0, 1, NULL));
321 for (;;);
324 void
325 chrp_power_off(void)
327 /* allow power on only with power button press */
328 printk("RTAS power-off returned %d\n",
329 call_rtas("power-off", 2, 1, NULL,0xffffffff,0xffffffff));
330 for (;;);
333 void
334 chrp_halt(void)
336 chrp_power_off();
339 u_int
340 chrp_irq_cannonicalize(u_int irq)
342 if (irq == 2)
344 return 9;
346 else
348 return irq;
352 int chrp_get_irq( struct pt_regs *regs )
354 int irq;
356 irq = openpic_irq( smp_processor_id() );
357 if (irq == IRQ_8259_CASCADE)
360 * This magic address generates a PCI IACK cycle.
362 if ( chrp_int_ack_special )
363 irq = *chrp_int_ack_special;
364 else
365 irq = i8259_irq( smp_processor_id() );
367 * Acknowledge as soon as possible to allow i8259
368 * interrupt nesting */
369 openpic_eoi( smp_processor_id() );
371 if (irq == OPENPIC_VEC_SPURIOUS)
373 * Spurious interrupts should never be
374 * acknowledged
376 irq = -1;
377 return irq;
380 void chrp_post_irq(int irq)
383 * If it's an i8259 irq then we've already done the
384 * openpic irq. So we just check to make sure the controller
385 * is an openpic and if it is then eoi -- Cort
387 if ( irq_desc[irq].ctl == &open_pic )
388 openpic_eoi( smp_processor_id() );
391 #if 0
392 void
393 chrp_do_IRQ(struct pt_regs *regs,
394 int cpu,
395 int isfake)
397 int irq;
398 unsigned long bits = 0;
399 int openpic_eoi_done = 0;
401 #ifdef __SMP__
403 unsigned int loops = 1000000;
404 while (test_bit(0, &global_irq_lock)) {
405 if (smp_processor_id() == global_irq_holder) {
406 printk("uh oh, interrupt while we hold global irq lock!\n");
407 #ifdef CONFIG_XMON
408 xmon(0);
409 #endif
410 break;
412 if (loops-- == 0) {
413 printk("do_IRQ waiting for irq lock (holder=%d)\n", global_irq_holder);
414 #ifdef CONFIG_XMON
415 xmon(0);
416 #endif
420 #endif /* __SMP__ */
422 irq = openpic_irq(0);
423 if (irq == IRQ_8259_CASCADE)
426 * This magic address generates a PCI IACK cycle.
428 * This should go in the above mask/ack code soon. -- Cort
430 if ( chrp_int_ack_special )
431 irq = *chrp_int_ack_special;
432 else
433 irq = i8259_irq(0);
435 * Acknowledge as soon as possible to allow i8259
436 * interrupt nesting */
437 openpic_eoi(0);
438 openpic_eoi_done = 1;
440 if (irq == OPENPIC_VEC_SPURIOUS)
443 * Spurious interrupts should never be
444 * acknowledged
446 ppc_spurious_interrupts++;
447 openpic_eoi_done = 1;
448 goto out;
450 bits = 1UL << irq;
452 if (irq < 0)
454 printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
455 irq, regs->nip);
456 ppc_spurious_interrupts++;
458 else
460 ppc_irq_dispatch_handler( regs, irq );
462 out:
463 if (!openpic_eoi_done)
464 openpic_eoi(0);
466 #endif
468 void __init chrp_init_IRQ(void)
470 struct device_node *np;
471 int i;
473 if ( !(np = find_devices("pci") ) )
474 printk("Cannot find pci to get ack address\n");
475 else
477 chrp_int_ack_special = (volatile unsigned char *)
478 (*(unsigned long *)get_property(np,
479 "8259-interrupt-acknowledge", NULL));
481 open_pic.irq_offset = 16;
482 for ( i = 16 ; i < NR_IRQS ; i++ )
483 irq_desc[i].ctl = &open_pic;
484 openpic_init(1);
485 for ( i = 0 ; i < 16 ; i++ )
486 irq_desc[i].ctl = &i8259_pic;
487 i8259_init();
488 #ifdef CONFIG_XMON
489 request_irq(openpic_to_irq(HYDRA_INT_ADB_NMI),
490 xmon_irq, 0, "NMI", 0);
491 #endif /* CONFIG_XMON */
492 #ifdef __SMP__
493 request_irq(openpic_to_irq(OPENPIC_VEC_IPI),
494 openpic_ipi_action, 0, "IPI0", 0);
495 #endif /* __SMP__ */
498 void __init
499 chrp_init2(void)
501 pmac_nvram_init();
504 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
506 * IDE stuff.
508 unsigned int chrp_ide_irq = 0;
509 int chrp_ide_ports_known = 0;
510 ide_ioreg_t chrp_ide_regbase[MAX_HWIFS];
511 ide_ioreg_t chrp_idedma_regbase;
513 void
514 chrp_ide_probe(void)
516 struct pci_dev *pdev = pci_find_device(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, NULL);
518 chrp_ide_ports_known = 1;
520 if(pdev) {
521 chrp_ide_regbase[0]=pdev->resource[0].start;
522 chrp_ide_regbase[1]=pdev->resource[2].start;
523 chrp_idedma_regbase=pdev->resource[4].start;
524 chrp_ide_irq=pdev->irq;
528 void
529 chrp_ide_insw(ide_ioreg_t port, void *buf, int ns)
531 ide_insw(port+_IO_BASE, buf, ns);
534 void
535 chrp_ide_outsw(ide_ioreg_t port, void *buf, int ns)
537 ide_outsw(port+_IO_BASE, buf, ns);
541 chrp_ide_default_irq(ide_ioreg_t base)
543 if (chrp_ide_ports_known == 0)
544 chrp_ide_probe();
545 return chrp_ide_irq;
548 ide_ioreg_t
549 chrp_ide_default_io_base(int index)
551 if (chrp_ide_ports_known == 0)
552 chrp_ide_probe();
553 return chrp_ide_regbase[index];
557 chrp_ide_check_region(ide_ioreg_t from, unsigned int extent)
559 return check_region(from, extent);
562 void
563 chrp_ide_request_region(ide_ioreg_t from,
564 unsigned int extent,
565 const char *name)
567 request_region(from, extent, name);
570 void
571 chrp_ide_release_region(ide_ioreg_t from,
572 unsigned int extent)
574 release_region(from, extent);
577 void
578 chrp_ide_fix_driveid(struct hd_driveid *id)
580 ppc_generic_ide_fix_driveid(id);
583 void
584 chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
586 ide_ioreg_t reg = data_port;
587 int i;
589 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
590 hw->io_ports[i] = reg;
591 reg += 1;
593 if (ctrl_port) {
594 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
595 } else {
596 hw->io_ports[IDE_CONTROL_OFFSET] = 0;
598 if (irq != NULL)
599 hw->irq = chrp_ide_irq;
602 #if defined(CONFIG_BLK_DEV_IDE_MODULE)
603 EXPORT_SYMBOL(chrp_ide_irq);
604 EXPORT_SYMBOL(chrp_ide_ports_known);
605 EXPORT_SYMBOL(chrp_ide_regbase);
606 EXPORT_SYMBOL(chrp_ide_probe);
607 #endif
608 #endif
610 void __init
611 chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
612 unsigned long r6, unsigned long r7)
614 chrp_setup_pci_ptrs();
615 #ifdef CONFIG_BLK_DEV_INITRD
616 /* take care of initrd if we have one */
617 if ( r6 )
619 initrd_start = r6 + KERNELBASE;
620 initrd_end = r6 + r7 + KERNELBASE;
622 #endif /* CONFIG_BLK_DEV_INITRD */
624 /* pci_dram_offset/isa_io_base/isa_mem_base set by setup_pci_ptrs() */
625 ISA_DMA_THRESHOLD = ~0L;
626 DMA_MODE_READ = 0x44;
627 DMA_MODE_WRITE = 0x48;
629 ppc_md.setup_arch = chrp_setup_arch;
630 ppc_md.setup_residual = NULL;
631 ppc_md.get_cpuinfo = chrp_get_cpuinfo;
632 ppc_md.irq_cannonicalize = chrp_irq_cannonicalize;
633 ppc_md.init_IRQ = chrp_init_IRQ;
634 ppc_md.get_irq = chrp_get_irq;
635 ppc_md.post_irq = chrp_post_irq;
637 ppc_md.init = chrp_init2;
639 ppc_md.restart = chrp_restart;
640 ppc_md.power_off = chrp_power_off;
641 ppc_md.halt = chrp_halt;
643 ppc_md.time_init = chrp_time_init;
644 ppc_md.set_rtc_time = chrp_set_rtc_time;
645 ppc_md.get_rtc_time = chrp_get_rtc_time;
646 ppc_md.calibrate_decr = chrp_calibrate_decr;
648 #ifdef CONFIG_VT
649 #ifdef CONFIG_MAC_KEYBOAD
650 if (adb_driver == NULL)
652 ppc_md.kbd_setkeycode = pckbd_setkeycode;
653 ppc_md.kbd_getkeycode = pckbd_getkeycode;
654 ppc_md.kbd_translate = pckbd_translate;
655 ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
656 ppc_md.kbd_leds = pckbd_leds;
657 ppc_md.kbd_init_hw = pckbd_init_hw;
658 #ifdef CONFIG_MAGIC_SYSRQ
659 ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
660 SYSRQ_KEY = 0x54;
661 #endif
663 else
665 ppc_md.kbd_setkeycode = mackbd_setkeycode;
666 ppc_md.kbd_getkeycode = mackbd_getkeycode;
667 ppc_md.kbd_translate = mackbd_translate;
668 ppc_md.kbd_unexpected_up = mackbd_unexpected_up;
669 ppc_md.kbd_leds = mackbd_leds;
670 ppc_md.kbd_init_hw = mackbd_init_hw;
671 #ifdef CONFIG_MAGIC_SYSRQ
672 ppc_md.ppc_kbd_sysrq_xlate = mackbd_sysrq_xlate;
673 SYSRQ_KEY = 0x69;
674 #endif
676 #else
677 ppc_md.kbd_setkeycode = pckbd_setkeycode;
678 ppc_md.kbd_getkeycode = pckbd_getkeycode;
679 ppc_md.kbd_translate = pckbd_translate;
680 ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
681 ppc_md.kbd_leds = pckbd_leds;
682 ppc_md.kbd_init_hw = pckbd_init_hw;
683 #ifdef CONFIG_MAGIC_SYSRQ
684 ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
685 SYSRQ_KEY = 0x54;
686 #endif
687 if ( rtas_data )
688 ppc_md.progress = chrp_progress;
689 #endif
690 #endif
692 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
693 ppc_ide_md.insw = chrp_ide_insw;
694 ppc_ide_md.outsw = chrp_ide_outsw;
695 ppc_ide_md.default_irq = chrp_ide_default_irq;
696 ppc_ide_md.default_io_base = chrp_ide_default_io_base;
697 ppc_ide_md.ide_check_region = chrp_ide_check_region;
698 ppc_ide_md.ide_request_region = chrp_ide_request_region;
699 ppc_ide_md.ide_release_region = chrp_ide_release_region;
700 ppc_ide_md.fix_driveid = chrp_ide_fix_driveid;
701 ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;
703 ppc_ide_md.io_base = _IO_BASE;
704 #endif
706 * Print the banner, then scroll down so boot progress
707 * can be printed. -- Cort
709 if ( ppc_md.progress ) ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0x0);
712 void
713 chrp_progress(char *s, unsigned short hex)
715 extern unsigned int rtas_data;
716 int max_width, width;
717 struct device_node *root;
718 char *os = s;
719 unsigned long *p;
721 if ( (root = find_path_device("/rtas")) &&
722 (p = (unsigned long *)get_property(root,
723 "ibm,display-line-length",
724 NULL)) )
725 max_width = *p;
726 else
727 max_width = 0x10;
729 if ( (_machine != _MACH_chrp) || !rtas_data )
730 return;
731 if ( call_rtas( "display-character", 1, 1, NULL, '\r' ) )
733 /* assume no display-character RTAS method - use hex display */
734 return;
737 width = max_width;
738 while ( *os )
740 if ( (*os == '\n') || (*os == '\r') )
741 width = max_width;
742 else
743 width--;
744 call_rtas( "display-character", 1, 1, NULL, *os++ );
745 /* if we overwrite the screen length */
746 if ( width == 0 )
747 while ( (*os != 0) && (*os != '\n') && (*os != '\r') )
748 os++;
751 /*while ( width-- > 0 )*/
752 call_rtas( "display-character", 1, 1, NULL, ' ' );