v2.4.8 -> v2.4.8.1
[opensuse:kernel.git] / arch / ppc / kernel / prep_setup.c
1 /*
2  * BK Id: SCCS/s.prep_setup.c 1.26 08/05/01 16:18:54 trini
3  */
4 /*
5  *  linux/arch/ppc/kernel/setup.c
6  *
7  *  Copyright (C) 1995  Linus Torvalds
8  *  Adapted from 'alpha' version by Gary Thomas
9  *  Modified by Cort Dougan (cort@cs.nmt.edu)
10  */
11
12 /*
13  * bootup setup stuff..
14  */
15
16 #include <linux/config.h>
17 #include <linux/delay.h>
18 #include <linux/module.h>
19 #include <linux/errno.h>
20 #include <linux/sched.h>
21 #include <linux/kernel.h>
22 #include <linux/mm.h>
23 #include <linux/stddef.h>
24 #include <linux/unistd.h>
25 #include <linux/ptrace.h>
26 #include <linux/slab.h>
27 #include <linux/user.h>
28 #include <linux/a.out.h>
29 #include <linux/tty.h>
30 #include <linux/major.h>
31 #include <linux/interrupt.h>
32 #include <linux/reboot.h>
33 #include <linux/init.h>
34 #include <linux/blk.h>
35 #include <linux/ioport.h>
36 #include <linux/console.h>
37 #include <linux/timex.h>
38 #include <linux/pci.h>
39 #include <linux/ide.h>
40
41 #include <asm/init.h>
42 #include <asm/mmu.h>
43 #include <asm/processor.h>
44 #include <asm/residual.h>
45 #include <asm/io.h>
46 #include <asm/pgtable.h>
47 #include <asm/cache.h>
48 #include <asm/dma.h>
49 #include <asm/machdep.h>
50 #include <asm/mk48t59.h>
51 #include <asm/prep_nvram.h>
52 #include <asm/raven.h>
53 #include <asm/keyboard.h>
54 #include <asm/vga.h>
55 #include <asm/time.h>
56
57 #include "local_irq.h"
58 #include "i8259.h"
59 #include "open_pic.h"
60
61 #if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
62 #include <../drivers/sound/sound_config.h>
63 #include <../drivers/sound/dev_table.h>
64 #endif
65
66 unsigned char ucSystemType;
67 unsigned char ucBoardRev;
68 unsigned char ucBoardRevMaj, ucBoardRevMin;
69
70 extern unsigned long mc146818_get_rtc_time(void);
71 extern int mc146818_set_rtc_time(unsigned long nowtime);
72 extern unsigned long mk48t59_get_rtc_time(void);
73 extern int mk48t59_set_rtc_time(unsigned long nowtime);
74
75 extern unsigned char prep_nvram_read_val(int addr);
76 extern void prep_nvram_write_val(int addr,
77                                  unsigned char val);
78 extern unsigned char rs_nvram_read_val(int addr);
79 extern void rs_nvram_write_val(int addr,
80                                  unsigned char val);
81
82 extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
83 extern int pckbd_getkeycode(unsigned int scancode);
84 extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
85                            char raw_mode);
86 extern char pckbd_unexpected_up(unsigned char keycode);
87 extern void pckbd_leds(unsigned char leds);
88 extern void pckbd_init_hw(void);
89 extern unsigned char pckbd_sysrq_xlate[128];
90
91 extern void prep_find_bridges(void);
92 extern char saved_command_line[256];
93
94 int _prep_type;
95
96 #define cached_21       (((char *)(ppc_cached_irq_mask))[3])
97 #define cached_A1       (((char *)(ppc_cached_irq_mask))[2])
98
99 /* for the mac fs */
100 kdev_t boot_dev;
101 /* used in nasty hack for sound - see prep_setup_arch() -- Cort */
102 long ppc_cs4232_dma, ppc_cs4232_dma2;
103
104 extern PTE *Hash, *Hash_end;
105 extern unsigned long Hash_size, Hash_mask;
106 extern int probingmem;
107 extern unsigned long loops_per_jiffy;
108
109 #ifdef CONFIG_BLK_DEV_RAM
110 extern int rd_doload;           /* 1 = load ramdisk, 0 = don't load */
111 extern int rd_prompt;           /* 1 = prompt for ramdisk, 0 = don't prompt */
112 extern int rd_image_start;      /* starting block # of image */
113 #endif
114
115 #ifdef CONFIG_SOUND_MODULE
116 EXPORT_SYMBOL(ppc_cs4232_dma);
117 EXPORT_SYMBOL(ppc_cs4232_dma2);
118 #endif
119
120 int __prep
121 prep_get_cpuinfo(char *buffer)
122 {
123         extern char *Motherboard_map_name;
124         int len;
125 #ifdef CONFIG_PREP_RESIDUAL
126         int i;
127 #endif
128
129 #ifdef CONFIG_SMP
130 #define CD(X)           (cpu_data[n].X)  
131 #else
132 #define CD(X) (X)
133 #endif
134   
135         len = sprintf(buffer,"machine\t\t: PReP %s\n",Motherboard_map_name);
136
137         
138         switch ( _prep_type )
139         {
140         case _PREP_IBM:
141                 if ((*(unsigned char *)0x8000080c) & (1<<6))
142                         len += sprintf(buffer+len,"Upgrade CPU\n");
143                 len += sprintf(buffer+len,"L2\t\t: ");
144                 if ((*(unsigned char *)0x8000080c) & (1<<7))
145                 {
146                         len += sprintf(buffer+len,"not present\n");
147                         goto no_l2;
148                 }
149                 len += sprintf(buffer+len,"%sKb,",
150                                (((*(unsigned char *)0x8000080d)>>2)&1)?"512":"256");
151                 len += sprintf(buffer+len,"%ssync\n",
152                                ((*(unsigned char *)0x8000080d)>>7) ? "":"a");
153                 break;
154         case _PREP_Motorola:
155                 len += sprintf(buffer+len,"L2\t\t: ");
156                 switch(*((unsigned char *)CACHECRBA) & L2CACHE_MASK)
157                 {
158                 case L2CACHE_512KB:
159                         len += sprintf(buffer+len,"512Kb");
160                         break;
161                 case L2CACHE_256KB:
162                         len += sprintf(buffer+len,"256Kb");
163                         break;
164                 case L2CACHE_1MB:
165                         len += sprintf(buffer+len,"1MB");
166                         break;
167                 case L2CACHE_NONE:
168                         len += sprintf(buffer+len,"none\n");
169                         goto no_l2;
170                         break;
171                 default:
172                         len += sprintf(buffer+len, "%x\n",
173                                        *((unsigned char *)CACHECRBA));
174                 }
175                 
176                 len += sprintf(buffer+len,",parity %s",
177                                (*((unsigned char *)CACHECRBA) & L2CACHE_PARITY) ?
178                                "enabled" : "disabled");
179                 
180                 len += sprintf(buffer+len, " SRAM:");
181                 
182                 switch ( ((*((unsigned char *)CACHECRBA) & 0xf0) >> 4) & ~(0x3) )
183                 {
184                 case 1: len += sprintf(buffer+len,
185                                        "synchronous,parity,flow-through\n");
186                         break;
187                 case 2: len += sprintf(buffer+len,"asynchronous,no parity\n");
188                         break;
189                 case 3: len += sprintf(buffer+len,"asynchronous,parity\n");
190                         break;
191                 default:len += sprintf(buffer+len,
192                                        "synchronous,pipelined,no parity\n");
193                         break;
194                 }
195                 break;
196         default:
197                 break;
198         }
199         
200         
201 no_l2:
202 #ifndef CONFIG_PREP_RESIDUAL
203         return len;
204 #else   
205         if ( res->ResidualLength == 0 )
206                 return len;
207         
208         /* print info about SIMMs */
209         len += sprintf(buffer+len,"simms\t\t: ");
210         for ( i = 0 ; (res->ActualNumMemories) && (i < MAX_MEMS) ; i++ )
211         {
212                 if ( res->Memories[i].SIMMSize != 0 )
213                         len += sprintf(buffer+len,"%d:%ldM ",i,
214                                        (res->Memories[i].SIMMSize > 1024) ?
215                                        res->Memories[i].SIMMSize>>20 :
216                                        res->Memories[i].SIMMSize);
217         }
218         len += sprintf(buffer+len,"\n");
219         return len;
220 #endif
221 }
222
223 void __init
224 prep_setup_arch(void)
225 {
226         unsigned char reg;
227 #if 0 /* unused?? */
228         unsigned char ucMothMemType;
229         unsigned char ucEquipPres1;
230 #endif
231
232         /* init to some ~sane value until calibrate_delay() runs */
233         loops_per_jiffy = 50000000;
234         
235         /* Lookup PCI host bridges */
236         prep_find_bridges();
237         
238         /* Set up floppy in PS/2 mode */
239         outb(0x09, SIO_CONFIG_RA);
240         reg = inb(SIO_CONFIG_RD);
241         reg = (reg & 0x3F) | 0x40;
242         outb(reg, SIO_CONFIG_RD);
243         outb(reg, SIO_CONFIG_RD);       /* Have to write twice to change! */
244
245         /*
246          * We need to set up the NvRAM access routines early as prep_init
247          * has yet to be called
248          */
249         ppc_md.nvram_read_val = prep_nvram_read_val;
250         ppc_md.nvram_write_val = prep_nvram_write_val;
251
252         /* we should determine this according to what we find! -- Cort */
253         switch ( _prep_type )
254         {
255         case _PREP_IBM:
256                 /* Enable L2.  Assume we don't need to flush -- Cort*/
257                 *(unsigned char *)(0x8000081c) |= 3;
258                 ROOT_DEV = to_kdev_t(0x0301); /* hda1 */
259                 break;
260         case _PREP_Motorola:
261                 /* Enable L2.  Assume we don't need to flush -- Cort*/
262                 *(unsigned char *)(0x8000081c) |= 3;
263 #ifdef CONFIG_BLK_DEV_INITRD
264                 if (initrd_start)
265                         ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); /* /dev/ram */
266                 else
267 #endif
268 #ifdef CONFIG_ROOT_NFS
269                         ROOT_DEV = to_kdev_t(0x00ff); /* /dev/nfs */
270 #else
271                         ROOT_DEV = to_kdev_t(0x0802); /* /dev/sda2 */
272 #endif
273                 break;
274         }
275
276       /* Read in NVRAM data */ 
277       init_prep_nvram();
278        
279       /* if no bootargs, look in NVRAM */
280       if ( cmd_line[0] == '\0' ) {
281               char *bootargs;
282               bootargs = prep_nvram_get_var("bootargs");
283               if (bootargs != NULL) {
284                       strcpy(cmd_line, bootargs);
285
286                       /* again.. */
287                       strcpy(saved_command_line, cmd_line);
288               }
289       }
290
291 #ifdef CONFIG_SOUND_CS4232
292         /*
293          * setup proper values for the cs4232 driver so we don't have
294          * to recompile for the motorola or ibm workstations sound systems.
295          * This is a really nasty hack, but unless we change the driver
296          * it's the only way to support both addrs from one binary.
297          * -- Cort
298          */
299         if ( _machine == _MACH_prep )
300         {
301                 extern struct card_info snd_installed_cards[];
302                 struct card_info  *snd_ptr;
303
304                 for ( snd_ptr = snd_installed_cards; 
305                       snd_ptr < &snd_installed_cards[num_sound_cards];
306                       snd_ptr++ )
307                 {
308                         if ( snd_ptr->card_type == SNDCARD_CS4232 )
309                         {
310                                 if ( _prep_type == _PREP_Motorola )
311                                 {
312                                         snd_ptr->config.io_base = 0x830;
313                                         snd_ptr->config.irq = 10;
314                                         snd_ptr->config.dma = ppc_cs4232_dma = 6;
315                                         snd_ptr->config.dma2 = ppc_cs4232_dma2 = 7;
316                                 }
317                                 if ( _prep_type == _PREP_IBM )
318                                 {
319                                         snd_ptr->config.io_base = 0x530;
320                                         snd_ptr->config.irq =  5;
321                                         snd_ptr->config.dma = ppc_cs4232_dma = 1;
322                                         /* this is wrong - but leave it for now */
323                                         snd_ptr->config.dma2 = ppc_cs4232_dma2 = 7;
324                                 }
325                         }
326                 }
327         }
328 #endif /* CONFIG_SOUND_CS4232 */        
329
330         /*print_residual_device_info();*/
331
332         raven_init();
333
334 #ifdef CONFIG_VGA_CONSOLE
335         /* remap the VGA memory */
336         vgacon_remap_base = 0xf0000000;
337         /*vgacon_remap_base = ioremap(0xc0000000, 0xba000);*/
338         conswitchp = &vga_con;
339 #elif defined(CONFIG_DUMMY_CONSOLE)
340         conswitchp = &dummy_con;
341 #endif
342 }
343
344 /*
345  * Determine the decrementer frequency from the residual data
346  * This allows for a faster boot as we do not need to calibrate the
347  * decrementer against another clock. This is important for embedded systems.
348  */
349 void __init prep_res_calibrate_decr(void)
350 {
351 #ifdef CONFIG_PREP_RESIDUAL     
352         unsigned long freq, divisor=4;
353
354         freq = res->VitalProductData.ProcessorBusHz;
355         printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
356                (freq/divisor)/1000000, (freq/divisor)%1000000);
357         tb_ticks_per_jiffy = freq / HZ / divisor;
358         tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000);
359 #endif  
360 }
361
362 /*
363  * Uses the on-board timer to calibrate the on-chip decrementer register
364  * for prep systems.  On the pmac the OF tells us what the frequency is
365  * but on prep we have to figure it out.
366  * -- Cort
367  */
368 /* Done with 3 interrupts: the first one primes the cache and the
369  * 2 following ones measure the interval. The precision of the method
370  * is still doubtful due to the short interval sampled.
371  */
372 static volatile int calibrate_steps __initdata = 3;
373 static unsigned tbstamp __initdata = 0;
374
375 void __init
376 prep_calibrate_decr_handler(int            irq,
377                             void           *dev,
378                             struct pt_regs *regs)
379 {
380         unsigned long t, freq;
381         int step=--calibrate_steps;
382
383         t = get_tbl();
384         if (step > 0) {
385                 tbstamp = t;
386         } else {
387                 freq = (t - tbstamp)*HZ;
388                 printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
389                        freq/1000000, freq%1000000);
390                 tb_ticks_per_jiffy = freq / HZ;
391                 tb_to_us = mulhwu_scale_factor(freq, 1000000);
392         }
393 }
394
395 void __init prep_calibrate_decr(void)
396 {
397         unsigned long flags;
398
399
400         save_flags(flags);
401
402 #define TIMER0_COUNT 0x40
403 #define TIMER_CONTROL 0x43
404         /* set timer to periodic mode */
405         outb_p(0x34,TIMER_CONTROL);/* binary, mode 2, LSB/MSB, ch 0 */
406         /* set the clock to ~100 Hz */
407         outb_p(LATCH & 0xff , TIMER0_COUNT);    /* LSB */
408         outb(LATCH >> 8 , TIMER0_COUNT);        /* MSB */
409         
410         if (request_irq(0, prep_calibrate_decr_handler, 0, "timer", NULL) != 0)
411                 panic("Could not allocate timer IRQ!");
412         __sti();
413         while ( calibrate_steps ) /* nothing */; /* wait for calibrate */
414         restore_flags(flags);
415         free_irq( 0, NULL);
416 }
417
418
419 static long __init mk48t59_init(void) {
420         unsigned char tmp;
421
422         tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
423         if (tmp & MK48T59_RTC_CB_STOP) {
424                 printk("Warning: RTC was stopped, date will be wrong.\n");
425                 ppc_md.nvram_write_val(MK48T59_RTC_CONTROLB, 
426                                        tmp & ~MK48T59_RTC_CB_STOP);
427                 /* Low frequency crystal oscillators may take a very long
428                  * time to startup and stabilize. For now just ignore the
429                  * the issue, but attempting to calibrate the decrementer
430                  * from the RTC just after this wakeup is likely to be very 
431                  * inaccurate. Firmware should not allow to load
432                  * the OS with the clock stopped anyway...
433                  */
434         }
435         /* Ensure that the clock registers are updated */
436         tmp = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
437         tmp &= ~(MK48T59_RTC_CA_READ | MK48T59_RTC_CA_WRITE);
438         ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, tmp);
439         return 0;
440 }
441
442 /* We use the NVRAM RTC to time a second to calibrate the decrementer,
443  * the RTC registers have just been set up in the right state by the
444  * preceding routine.
445  */
446 void __init mk48t59_calibrate_decr(void)
447 {
448         unsigned long freq;
449         unsigned long t1;
450         unsigned char save_control;
451         long i;
452         unsigned char sec;
453  
454                 
455         /* Make sure the time is not stopped. */
456         save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLB);
457         
458         ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
459                              (save_control & (~MK48T59_RTC_CB_STOP)));
460
461         /* Now make sure the read bit is off so the value will change. */
462         save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
463         save_control &= ~MK48T59_RTC_CA_READ;
464         ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
465
466
467         /* Read the seconds value to see when it changes. */
468         sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
469         /* Actually this is bad for precision, we should have a loop in
470          * which we only read the seconds counter. nvram_read_val writes
471          * the address bytes on every call and this takes a lot of time.
472          * Perhaps an nvram_wait_change method returning a time
473          * stamp with a loop count as parameter would be the  solution.
474          */
475         for (i = 0 ; i < 1000000 ; i++) { /* may take up to 1 second... */
476            t1 = get_tbl();
477            if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {
478               break;
479            }
480         }
481
482         sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
483         for (i = 0 ; i < 1000000 ; i++) { /* Should take up 1 second... */
484            freq = get_tbl()-t1;
485            if (ppc_md.nvram_read_val(MK48T59_RTC_SECONDS) != sec) {
486               break;
487            }
488         }
489
490         printk("time_init: decrementer frequency = %lu.%.6lu MHz\n",
491                freq/1000000, freq%1000000);
492         tb_ticks_per_jiffy = freq / HZ;
493         tb_to_us = mulhwu_scale_factor(freq, 1000000);
494 }
495
496 void __prep
497 prep_restart(char *cmd)
498 {
499         unsigned long i = 10000;
500
501         __cli();
502
503         /* set exception prefix high - to the prom */
504         _nmask_and_or_msr(0, MSR_IP);
505
506         /* make sure bit 0 (reset) is a 0 */
507         outb( inb(0x92) & ~1L , 0x92 );
508         /* signal a reset to system control port A - soft reset */
509         outb( inb(0x92) | 1 , 0x92 );
510
511         while ( i != 0 ) i++;
512         panic("restart failed\n");
513 }
514
515 /*
516  * This function will restart a board regardless of port 92 functionality
517  */
518 void __prep
519 prep_direct_restart(char *cmd)
520 {
521         u32 jumpaddr=0xfff00100;
522         u32 defaultmsr=MSR_IP;
523
524         /*
525          * This will ALWAYS work regardless of port 92
526          * functionality
527          */
528         __cli();
529
530         __asm__ __volatile__("\n\
531         mtspr   26, %1  /* SRR0 */      \n\
532         mtspr   27, %0  /* SRR1 */      \n\
533         rfi"
534         :
535         : "r" (defaultmsr), "r" (jumpaddr));
536         /*
537          * Not reached
538          */
539 }
540
541 void __prep
542 prep_halt(void)
543 {
544         unsigned long flags;
545         __cli();
546         /* set exception prefix high - to the prom */
547         save_flags( flags );
548         restore_flags( flags|MSR_IP );
549
550         /* make sure bit 0 (reset) is a 0 */
551         outb( inb(0x92) & ~1L , 0x92 );
552         /* signal a reset to system control port A - soft reset */
553         outb( inb(0x92) | 1 , 0x92 );
554
555         while ( 1 ) ;
556         /*
557          * Not reached
558          */
559 }
560
561 /*
562  * On IBM PReP's, power management is handled by a Signetics 87c750 behind the
563  * Utah component on the ISA bus. To access the 750 you must write a series of
564  * nibbles to port 0x82a (decoded by the Utah). This is described somewhat in
565  * the IBM Carolina Technical Specification.
566  * -Hollis
567  */
568 static void __prep
569 utah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value)
570 {
571         /*
572          * byte1: 0 0 0 1 0  d  a5 a4
573          * byte2: 0 0 0 1 a3 a2 a1 a0
574          *
575          * d = the bit's value, enabled or disabled
576          * (a5 a4 a3) = the byte number, minus 20
577          * (a2 a1 a0) = the bit number
578          *
579          * example: set the 5th bit of byte 21 (21.5)
580          *     a5 a4 a3 = 001 (byte 1)
581          *     a2 a1 a0 = 101 (bit 5)
582          *
583          *     byte1 = 0001 0100 (0x14)
584          *     byte2 = 0001 1101 (0x1d)
585          */
586         unsigned char byte1=0x10, byte2=0x10;
587         const unsigned int pm_reg_1=0x82a; /* ISA address */
588
589         /* the 750's '20.0' is accessed as '0.0' through Utah (which adds 20) */
590         bytenum -= 20;
591
592         byte1 |= (!!value) << 2;                /* set d */
593         byte1 |= (bytenum >> 1) & 0x3;  /* set a5, a4 */
594
595         byte2 |= (bytenum & 0x1) << 3;  /* set a3 */
596         byte2 |= bitnum & 0x7;                  /* set a2, a1, a0 */
597
598         outb(byte1, pm_reg_1);          /* first nibble */
599         mb();
600         udelay(100);                            /* important: let controller recover */
601
602         outb(byte2, pm_reg_1);          /* second nibble */
603         mb();
604         udelay(100);                            /* important: let controller recover */
605 }
606
607 void __prep
608 prep_power_off(void)
609 {
610         if ( _prep_type == _PREP_IBM) {
611                 /* tested on:
612                  *              Carolina's: 7248-43P, 6070 (PowerSeries 850)
613                  * should work on:
614                  *              Carolina: 6050 (PowerSeries 830)
615                  *              7043-140 (Tiger 1)
616                  */
617                 unsigned long flags;
618                 __cli();
619                 /* set exception prefix high - to the prom */
620                 save_flags( flags );
621                 restore_flags( flags|MSR_IP );
622
623                 utah_sig87c750_setbit(21, 5, 1); /* set bit 21.5, "PMEXEC_OFF" */
624
625                 while ( 1 ) ;
626                 /* not reached */
627         } else {
628                 prep_halt();
629         }
630 }
631
632 int __prep
633 prep_setup_residual(char *buffer)
634 {
635         int len = 0;
636
637         /* PREP's without residual data will give incorrect values here */
638         len += sprintf(len+buffer, "clock\t\t: ");
639 #ifdef CONFIG_PREP_RESIDUAL     
640         if ( res->ResidualLength )
641                 len += sprintf(len+buffer, "%ldMHz\n",
642                        (res->VitalProductData.ProcessorHz > 1024) ?
643                        res->VitalProductData.ProcessorHz>>20 :
644                        res->VitalProductData.ProcessorHz);
645         else
646 #endif /* CONFIG_PREP_RESIDUAL */
647                 len += sprintf(len+buffer, "???\n");
648
649         return len;
650 }
651
652 u_int __prep
653 prep_irq_cannonicalize(u_int irq)
654 {
655         if (irq == 2)
656         {
657                 return 9;
658         }
659         else
660         {
661                 return irq;
662         }
663 }
664
665 #if 0
666 void __prep
667 prep_do_IRQ(struct pt_regs *regs, int cpu)
668 {
669         int irq;
670
671         if ( (irq = i8259_irq(0)) < 0 )
672         {
673                 printk(KERN_DEBUG "Bogus interrupt from PC = %lx\n",
674                        regs->nip);
675                 ppc_spurious_interrupts++;
676                 return;
677         }
678         ppc_irq_dispatch_handler( regs, irq );
679 }
680 #endif
681
682 int __prep
683 prep_get_irq(struct pt_regs *regs)
684 {
685         return i8259_irq(smp_processor_id());
686 }               
687
688 void __init
689 prep_init_IRQ(void)
690 {
691         int i;
692
693         if (OpenPIC_Addr != NULL)
694                 openpic_init(1, NUM_8259_INTERRUPTS, 0, -1);
695         for ( i = 0 ; i < NUM_8259_INTERRUPTS  ; i++ )
696                 irq_desc[i].handler = &i8259_pic;
697         i8259_init();   
698 }
699
700 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
701 /*
702  * IDE stuff.
703  */
704 void __prep
705 prep_ide_insw(ide_ioreg_t port, void *buf, int ns)
706 {
707         _insw((unsigned short *)((port)+_IO_BASE), buf, ns);
708 }
709
710 void __prep
711 prep_ide_outsw(ide_ioreg_t port, void *buf, int ns)
712 {
713         _outsw((unsigned short *)((port)+_IO_BASE), buf, ns);
714 }
715
716 int __prep
717 prep_ide_default_irq(ide_ioreg_t base)
718 {
719         switch (base) {
720                 case 0x1f0: return 13;
721                 case 0x170: return 13;
722                 case 0x1e8: return 11;
723                 case 0x168: return 10;
724                 default:
725                         return 0;
726         }
727 }
728
729 ide_ioreg_t __prep
730 prep_ide_default_io_base(int index)
731 {
732         switch (index) {
733                 case 0: return 0x1f0;
734                 case 1: return 0x170;
735                 case 2: return 0x1e8;
736                 case 3: return 0x168;
737                 default:
738                         return 0;
739         }
740 }
741
742 int __prep
743 prep_ide_check_region(ide_ioreg_t from, unsigned int extent)
744 {
745         return check_region(from, extent);
746 }
747
748 void __prep
749 prep_ide_request_region(ide_ioreg_t from,
750                         unsigned int extent,
751                         const char *name)
752 {
753         request_region(from, extent, name);
754 }
755
756 void __prep
757 prep_ide_release_region(ide_ioreg_t from,
758                         unsigned int extent)
759 {
760         release_region(from, extent);
761 }
762
763 void __init
764 prep_ide_init_hwif_ports (hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
765 {
766         ide_ioreg_t reg = data_port;
767         int i;
768
769         for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
770                 hw->io_ports[i] = reg;
771                 reg += 1;
772         }
773         if (ctrl_port) {
774                 hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
775         } else {
776                 hw->io_ports[IDE_CONTROL_OFFSET] =  hw->io_ports[IDE_DATA_OFFSET] + 0x206;
777         }
778         if (irq != NULL)
779                 *irq = 0;
780 }
781 #endif
782
783 /*
784  * This finds the amount of physical ram and does necessary
785  * setup for prep.  This is pretty architecture specific so
786  * this will likely stay separate from the pmac.
787  * -- Cort
788  */
789 unsigned long __init prep_find_end_of_memory(void)
790 {
791         unsigned long total;
792 #ifdef CONFIG_PREP_RESIDUAL     
793         total = res->TotalMemory;
794 #else
795         total = 0;
796 #endif  
797
798         if (total == 0 )
799         {
800                 /*
801                  * I need a way to probe the amount of memory if the residual
802                  * data doesn't contain it. -- Cort
803                  */
804                 printk("Ramsize from residual data was 0 -- Probing for value\n");
805                 total = 0x02000000;
806                 printk("Ramsize default to be %ldM\n", total>>20);
807         }
808
809         return (total);
810 }
811
812 unsigned long *MotSave_SmpIar;
813 unsigned char *MotSave_CpusState[2];
814
815 void __init
816 prep_init2(void)
817 {
818 #ifdef CONFIG_NVRAM  
819         request_region(PREP_NVRAM_AS0, 0x8, "nvram");
820 #endif
821         request_region(0x20,0x20,"pic1");
822         request_region(0xa0,0x20,"pic2");
823         request_region(0x00,0x20,"dma1");
824         request_region(0x40,0x20,"timer");
825         request_region(0x80,0x10,"dma page reg");
826         request_region(0xc0,0x20,"dma2");
827 }
828
829 void __init
830 prep_init(unsigned long r3, unsigned long r4, unsigned long r5,
831           unsigned long r6, unsigned long r7)
832 {
833 #ifdef CONFIG_PREP_RESIDUAL     
834         RESIDUAL *old_res = (RESIDUAL *)(r3 + KERNELBASE);
835
836         /* make a copy of residual data */
837         if ( r3 )
838         {
839                 memcpy((void *)res,(void *)(r3+KERNELBASE),
840                        sizeof(RESIDUAL));
841
842                 /* These need to be saved for the Motorola Prep 
843                  * MVME4600 and Dual MTX boards.
844                  */
845                 MotSave_SmpIar = &old_res->VitalProductData.SmpIar;
846                 MotSave_CpusState[0] = &old_res->Cpus[0].CpuState;
847                 MotSave_CpusState[1] = &old_res->Cpus[1].CpuState;
848         }
849 #endif
850
851 #ifdef CONFIG_BLK_DEV_INITRD
852         if ( r4 )
853         {
854                 initrd_start = r4 + KERNELBASE;
855                 initrd_end = r5 + KERNELBASE;
856         }
857 #endif /* CONFIG_BLK_DEV_INITRD */
858
859         /* Copy cmd_line parameters */
860         if ( r6)
861         {
862                 *(char *)(r7 + KERNELBASE) = 0;
863                 strcpy(cmd_line, (char *)(r6 + KERNELBASE));
864         }
865         
866         isa_io_base = PREP_ISA_IO_BASE;
867         isa_mem_base = PREP_ISA_MEM_BASE;
868         pci_dram_offset = PREP_PCI_DRAM_OFFSET;
869         ISA_DMA_THRESHOLD = 0x00ffffff;
870         DMA_MODE_READ = 0x44;
871         DMA_MODE_WRITE = 0x48;
872
873         /* figure out what kind of prep workstation we are */
874 #ifdef CONFIG_PREP_RESIDUAL     
875         if ( res->ResidualLength != 0 )
876         {
877                 if ( !strncmp(res->VitalProductData.PrintableModel,"IBM",3) )
878                         _prep_type = _PREP_IBM;
879                 else
880                         _prep_type = _PREP_Motorola;
881         }
882         else /* assume motorola if no residual (netboot?) */
883 #endif    
884         {
885                 _prep_type = _PREP_Motorola;
886         }
887
888         ppc_md.setup_arch     = prep_setup_arch;
889         ppc_md.setup_residual = prep_setup_residual;
890         ppc_md.get_cpuinfo    = prep_get_cpuinfo;
891         ppc_md.irq_cannonicalize = prep_irq_cannonicalize;
892         ppc_md.init_IRQ       = prep_init_IRQ;
893         /* this gets changed later on if we have an OpenPIC -- Cort */
894         ppc_md.get_irq        = prep_get_irq;
895         ppc_md.init           = prep_init2;
896
897         ppc_md.restart        = prep_restart;
898         ppc_md.power_off      = prep_power_off;
899         ppc_md.halt           = prep_halt;
900
901         ppc_md.time_init      = NULL;
902         if (_prep_type == _PREP_IBM) {
903                 ppc_md.set_rtc_time   = mc146818_set_rtc_time;
904                 ppc_md.get_rtc_time   = mc146818_get_rtc_time;
905                 ppc_md.calibrate_decr = prep_calibrate_decr;
906         }
907         else {
908                 ppc_md.set_rtc_time   = mk48t59_set_rtc_time;
909                 ppc_md.get_rtc_time   = mk48t59_get_rtc_time;
910                 ppc_md.calibrate_decr = mk48t59_calibrate_decr;
911                 ppc_md.time_init      = mk48t59_init;
912         }
913
914         ppc_md.find_end_of_memory = prep_find_end_of_memory;
915
916 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
917         ppc_ide_md.insw = prep_ide_insw;
918         ppc_ide_md.outsw = prep_ide_outsw;
919         ppc_ide_md.default_irq = prep_ide_default_irq;
920         ppc_ide_md.default_io_base = prep_ide_default_io_base;
921         ppc_ide_md.ide_check_region = prep_ide_check_region;
922         ppc_ide_md.ide_request_region = prep_ide_request_region;
923         ppc_ide_md.ide_release_region = prep_ide_release_region;
924         ppc_ide_md.fix_driveid = NULL;
925         ppc_ide_md.ide_init_hwif = prep_ide_init_hwif_ports;
926 #endif          
927         ppc_ide_md.io_base = _IO_BASE;
928
929 #ifdef CONFIG_VT
930         ppc_md.kbd_setkeycode    = pckbd_setkeycode;
931         ppc_md.kbd_getkeycode    = pckbd_getkeycode;
932         ppc_md.kbd_translate     = pckbd_translate;
933         ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
934         ppc_md.kbd_leds          = pckbd_leds;
935         ppc_md.kbd_init_hw       = pckbd_init_hw;
936 #ifdef CONFIG_MAGIC_SYSRQ
937         ppc_md.ppc_kbd_sysrq_xlate       = pckbd_sysrq_xlate;
938         SYSRQ_KEY = 0x54;
939 #endif
940 #endif
941 }