prep_setup.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:23k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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