prep_setup.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:22k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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