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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.chrp_setup.c 1.40 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. /*
  12.  * bootup setup stuff..
  13.  */
  14. #include <linux/config.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/slab.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/version.h>
  35. #include <linux/adb.h>
  36. #include <linux/module.h>
  37. #include <linux/delay.h>
  38. #include <linux/ide.h>
  39. #include <linux/seq_file.h>
  40. #include <asm/mmu.h>
  41. #include <asm/processor.h>
  42. #include <asm/io.h>
  43. #include <asm/pgtable.h>
  44. #include <asm/prom.h>
  45. #include <asm/gg2.h>
  46. #include <asm/pci-bridge.h>
  47. #include <asm/dma.h>
  48. #include <asm/machdep.h>
  49. #include <asm/irq.h>
  50. #include <asm/hydra.h>
  51. #include <asm/keyboard.h>
  52. #include <asm/sections.h>
  53. #include <asm/time.h>
  54. #include <asm/btext.h>
  55. #include "local_irq.h"
  56. #include "i8259.h"
  57. #include "open_pic.h"
  58. #include "xics.h"
  59. unsigned long chrp_get_rtc_time(void);
  60. int chrp_set_rtc_time(unsigned long nowtime);
  61. void chrp_calibrate_decr(void);
  62. long chrp_time_init(void);
  63. void chrp_find_bridges(void);
  64. void chrp_event_scan(void);
  65. void rtas_display_progress(char *, unsigned short);
  66. void rtas_indicator_progress(char *, unsigned short);
  67. void btext_progress(char *, unsigned short);
  68. extern unsigned long pmac_find_end_of_memory(void);
  69. extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
  70. extern int pckbd_getkeycode(unsigned int scancode);
  71. extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
  72.    char raw_mode);
  73. extern char pckbd_unexpected_up(unsigned char keycode);
  74. extern void pckbd_leds(unsigned char leds);
  75. extern void pckbd_init_hw(void);
  76. extern unsigned char pckbd_sysrq_xlate[128];
  77. extern void select_adb_keyboard(void);
  78. extern int of_show_percpuinfo(struct seq_file *, int);
  79. extern kdev_t boot_dev;
  80. extern PTE *Hash, *Hash_end;
  81. extern unsigned long Hash_size, Hash_mask;
  82. extern int probingmem;
  83. extern unsigned long loops_per_jiffy;
  84. static int max_width;
  85. #ifdef CONFIG_SMP
  86. extern struct smp_ops_t chrp_smp_ops;
  87. extern struct smp_ops_t xics_smp_ops;
  88. #endif
  89. static const char *gg2_memtypes[4] = {
  90. "FPM", "SDRAM", "EDO", "BEDO"
  91. };
  92. static const char *gg2_cachesizes[4] = {
  93. "256 KB", "512 KB", "1 MB", "Reserved"
  94. };
  95. static const char *gg2_cachetypes[4] = {
  96. "Asynchronous", "Reserved", "Flow-Through Synchronous",
  97. "Pipelined Synchronous"
  98. };
  99. static const char *gg2_cachemodes[4] = {
  100. "Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
  101. };
  102. int __chrp
  103. chrp_show_cpuinfo(struct seq_file *m)
  104. {
  105. int i, sdramen;
  106. unsigned int t;
  107. struct device_node *root;
  108. const char *model = "";
  109. root = find_path_device("/");
  110. if (root)
  111. model = get_property(root, "model", NULL);
  112. seq_printf(m, "machinett: CHRP %sn", model);
  113. /* longtrail (goldengate) stuff */
  114. if (!strncmp(model, "IBM,LongTrail", 13)) {
  115. /* VLSI VAS96011/12 `Golden Gate 2' */
  116. /* Memory banks */
  117. sdramen = (in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+
  118. GG2_PCI_DRAM_CTRL))
  119.    >>31) & 1;
  120. for (i = 0; i < (sdramen ? 4 : 6); i++) {
  121. t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+
  122.  GG2_PCI_DRAM_BANK0+
  123.  i*4));
  124. if (!(t & 1))
  125. continue;
  126. switch ((t>>8) & 0x1f) {
  127. case 0x1f:
  128. model = "4 MB";
  129. break;
  130. case 0x1e:
  131. model = "8 MB";
  132. break;
  133. case 0x1c:
  134. model = "16 MB";
  135. break;
  136. case 0x18:
  137. model = "32 MB";
  138. break;
  139. case 0x10:
  140. model = "64 MB";
  141. break;
  142. case 0x00:
  143. model = "128 MB";
  144. break;
  145. default:
  146. model = "Reserved";
  147. break;
  148. }
  149. seq_printf(m, "memory bank %dt: %s %sn", i, model,
  150.    gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]);
  151. }
  152. /* L2 cache */
  153. t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+GG2_PCI_CC_CTRL));
  154. seq_printf(m, "board l2t: %s %s (%s)n",
  155.    gg2_cachesizes[(t>>7) & 3],
  156.    gg2_cachetypes[(t>>2) & 3],
  157.    gg2_cachemodes[t & 3]);
  158. }
  159. return 0;
  160. }
  161. /*
  162.  *  Fixes for the National Semiconductor PC78308VUL SuperI/O
  163.  *
  164.  *  Some versions of Open Firmware incorrectly initialize the IRQ settings
  165.  *  for keyboard and mouse
  166.  */
  167. static inline void __init sio_write(u8 val, u8 index)
  168. {
  169. outb(index, 0x15c);
  170. outb(val, 0x15d);
  171. }
  172. static inline u8 __init sio_read(u8 index)
  173. {
  174. outb(index, 0x15c);
  175. return inb(0x15d);
  176. }
  177. static void __init sio_fixup_irq(const char *name, u8 device, u8 level,
  178.      u8 type)
  179. {
  180. u8 level0, type0, active;
  181. /* select logical device */
  182. sio_write(device, 0x07);
  183. active = sio_read(0x30);
  184. level0 = sio_read(0x70);
  185. type0 = sio_read(0x71);
  186. if (level0 != level || type0 != type || !active) {
  187. printk(KERN_WARNING "sio: %s irq level %d, type %d, %sactive: "
  188.        "remapping to level %d, type %d, activen",
  189.        name, level0, type0, !active ? "in" : "", level, type);
  190. sio_write(0x01, 0x30);
  191. sio_write(level, 0x70);
  192. sio_write(type, 0x71);
  193. }
  194. }
  195. static void __init sio_init(void)
  196. {
  197. struct device_node *root;
  198. if ((root = find_path_device("/")) &&
  199.     !strncmp(get_property(root, "model", NULL), "IBM,LongTrail", 13)) {
  200. /* logical device 0 (KBC/Keyboard) */
  201. sio_fixup_irq("keyboard", 0, 1, 2);
  202. /* select logical device 1 (KBC/Mouse) */
  203. sio_fixup_irq("mouse", 1, 12, 2);
  204. }
  205. }
  206. void __init
  207. chrp_setup_arch(void)
  208. {
  209. struct device_node *device;
  210. /* init to some ~sane value until calibrate_delay() runs */
  211. loops_per_jiffy = 50000000/HZ;
  212. #ifdef CONFIG_BLK_DEV_INITRD
  213. /* this is fine for chrp */
  214. initrd_below_start_ok = 1;
  215. if (initrd_start)
  216. ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
  217. else
  218. #endif
  219. ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
  220. /* Lookup PCI host bridges */
  221. chrp_find_bridges();
  222. #ifndef CONFIG_PPC64BRIDGE
  223. /*
  224.  *  Temporary fixes for PCI devices.
  225.  *  -- Geert
  226.  */
  227. hydra_init(); /* Mac I/O */
  228. #endif /* CONFIG_PPC64BRIDGE */
  229. /* Some IBM machines don't have the hydra -- Cort */
  230. if (!OpenPIC_Addr) {
  231. struct device_node *root;
  232. unsigned long *opprop;
  233. int n;
  234. root = find_path_device("/");
  235. opprop = (unsigned long *) get_property
  236. (root, "platform-open-pic", NULL);
  237. n = prom_n_addr_cells(root);
  238. if (opprop != 0) {
  239. printk("OpenPIC addrs: %lx %lx %lxn",
  240.        opprop[n-1], opprop[2*n-1], opprop[3*n-1]);
  241. OpenPIC_Addr = ioremap(opprop[n-1], 0x40000);
  242. }
  243. }
  244. /*
  245.  *  Fix the Super I/O configuration
  246.  */
  247. sio_init();
  248. /*
  249.  *  Setup the console operations
  250.  */
  251. #ifdef CONFIG_DUMMY_CONSOLE
  252. conswitchp = &dummy_con;
  253. #endif
  254. /* Get the event scan rate for the rtas so we know how
  255.  * often it expects a heartbeat. -- Cort
  256.  */
  257. if ( rtas_data ) {
  258. struct property *p;
  259. device = find_devices("rtas");
  260. for ( p = device->properties;
  261.       p && strncmp(p->name, "rtas-event-scan-rate", 20);
  262.       p = p->next )
  263. /* nothing */ ;
  264. if ( p && *(unsigned long *)p->value ) {
  265. ppc_md.heartbeat = chrp_event_scan;
  266. ppc_md.heartbeat_reset = (HZ/(*(unsigned long *)p->value)*30)-1;
  267. ppc_md.heartbeat_count = 1;
  268. printk("RTAS Event Scan Rate: %lu (%lu jiffies)n",
  269.        *(unsigned long *)p->value, ppc_md.heartbeat_reset );
  270. }
  271. }
  272. }
  273. void __chrp
  274. chrp_event_scan(void)
  275. {
  276. unsigned char log[1024];
  277. unsigned long ret = 0;
  278. /* XXX: we should loop until the hardware says no more error logs -- Cort */
  279. call_rtas( "event-scan", 4, 1, &ret, 0xffffffff, 0,
  280.    __pa(log), 1024 );
  281. ppc_md.heartbeat_count = ppc_md.heartbeat_reset;
  282. }
  283. void __chrp
  284. chrp_restart(char *cmd)
  285. {
  286. printk("RTAS system-reboot returned %dn",
  287.        call_rtas("system-reboot", 0, 1, NULL));
  288. for (;;);
  289. }
  290. void __chrp
  291. chrp_power_off(void)
  292. {
  293. /* allow power on only with power button press */
  294. printk("RTAS power-off returned %dn",
  295.        call_rtas("power-off", 2, 1, NULL,0xffffffff,0xffffffff));
  296. for (;;);
  297. }
  298. void __chrp
  299. chrp_halt(void)
  300. {
  301. chrp_power_off();
  302. }
  303. u_int __chrp
  304. chrp_irq_cannonicalize(u_int irq)
  305. {
  306. if (irq == 2)
  307. return 9;
  308. return irq;
  309. }
  310. void __init chrp_init_IRQ(void)
  311. {
  312. struct device_node *np;
  313. int i;
  314. unsigned int *addrp;
  315. unsigned char* chrp_int_ack_special = 0;
  316. unsigned char init_senses[NR_IRQS - NUM_8259_INTERRUPTS];
  317. int nmi_irq = -1;
  318. #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
  319. struct device_node *kbd;
  320. #endif
  321. if (!(np = find_devices("pci"))
  322.     || !(addrp = (unsigned int *)
  323.  get_property(np, "8259-interrupt-acknowledge", NULL)))
  324. printk("Cannot find pci to get ack addressn");
  325. else
  326. chrp_int_ack_special = (unsigned char *)
  327. ioremap(addrp[prom_n_addr_cells(np)-1], 1);
  328. /* hydra still sets OpenPIC_InitSenses to a static set of values */
  329. if (OpenPIC_InitSenses == NULL) {
  330. prom_get_irq_senses(init_senses, NUM_8259_INTERRUPTS, NR_IRQS);
  331. OpenPIC_InitSenses = init_senses;
  332. OpenPIC_NumInitSenses = NR_IRQS - NUM_8259_INTERRUPTS;
  333. }
  334. openpic_init(1, NUM_8259_INTERRUPTS, chrp_int_ack_special, nmi_irq);
  335. for ( i = 0 ; i < NUM_8259_INTERRUPTS  ; i++ )
  336. irq_desc[i].handler = &i8259_pic;
  337. i8259_init(NULL);
  338. #if defined(CONFIG_VT) && defined(CONFIG_ADB_KEYBOARD) && defined(XMON)
  339. /* see if there is a keyboard in the device tree
  340.    with a parent of type "adb" */
  341. for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next)
  342. if (kbd->parent && kbd->parent->type
  343.     && strcmp(kbd->parent->type, "adb") == 0)
  344. break;
  345. if (kbd)
  346. request_irq( HYDRA_INT_ADB_NMI, xmon_irq, 0, "XMON break", 0);
  347. #endif
  348. }
  349. void __init
  350. chrp_init2(void)
  351. {
  352. #ifdef CONFIG_NVRAM  
  353. pmac_nvram_init();
  354. #endif
  355. request_region(0x20,0x20,"pic1");
  356. request_region(0xa0,0x20,"pic2");
  357. request_region(0x00,0x20,"dma1");
  358. request_region(0x40,0x20,"timer");
  359. request_region(0x80,0x10,"dma page reg");
  360. request_region(0xc0,0x20,"dma2");
  361. if (ppc_md.progress)
  362. ppc_md.progress("  Have fun!    ", 0x7777);
  363. #if defined(CONFIG_VT) && (defined(CONFIG_ADB_KEYBOARD) || defined(CONFIG_INPUT))
  364. /* see if there is a keyboard in the device tree
  365.    with a parent of type "adb" */
  366. {
  367. struct device_node *kbd;
  368. for (kbd = find_devices("keyboard"); kbd; kbd = kbd->next) {
  369. if (kbd->parent && kbd->parent->type
  370.     && strcmp(kbd->parent->type, "adb") == 0) {
  371. select_adb_keyboard();
  372. break;
  373. }
  374. }
  375. }
  376. #endif /* CONFIG_VT && (CONFIG_ADB_KEYBOARD || CONFIG_INPUT) */
  377. }
  378. #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
  379. /*
  380.  * IDE stuff.
  381.  */
  382. static int __chrp
  383. chrp_ide_check_region(ide_ioreg_t from, unsigned int extent)
  384. {
  385.         return check_region(from, extent);
  386. }
  387. static void __chrp
  388. chrp_ide_request_region(ide_ioreg_t from,
  389. unsigned int extent,
  390. const char *name)
  391. {
  392.         request_region(from, extent, name);
  393. }
  394. static void __chrp
  395. chrp_ide_release_region(ide_ioreg_t from,
  396. unsigned int extent)
  397. {
  398.         release_region(from, extent);
  399. }
  400. static void __chrp
  401. chrp_ide_init_hwif_ports(hw_regs_t *hw, ide_ioreg_t data_port, ide_ioreg_t ctrl_port, int *irq)
  402. {
  403. ide_ioreg_t reg = data_port;
  404. int i;
  405. for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
  406. hw->io_ports[i] = reg;
  407. reg += 1;
  408. }
  409. hw->io_ports[IDE_CONTROL_OFFSET] = ctrl_port;
  410. }
  411. #endif
  412. /*
  413.  * One of the main thing these mappings are needed for is so that
  414.  * xmon can get to the serial port early on.  We probably should
  415.  * handle the machines with the mpc106 as well as the python (F50)
  416.  * and the GG2 (longtrail).  Actually we should look in the device
  417.  * tree and do the right thing.
  418.  */
  419. static void __init
  420. chrp_map_io(void)
  421. {
  422. char *name;
  423. /*
  424.  * The code below tends to get removed, please don't take it out.
  425.  * The F50 needs this mapping and it you take it out I'll track you
  426.  * down and slap your hands.  If it causes problems please email me.
  427.  *  -- Cort <cort@fsmlabs.com>
  428.  */
  429. name = get_property(find_path_device("/"), "name", NULL);
  430. if (name && strncmp(name, "IBM-70", 6) == 0
  431.     && strstr(name, "-F50")) {
  432. io_block_mapping(0x80000000, 0x80000000, 0x10000000, _PAGE_IO);
  433. io_block_mapping(0x90000000, 0x90000000, 0x10000000, _PAGE_IO);
  434. return;
  435. } else {
  436. io_block_mapping(0xf8000000, 0xf8000000, 0x04000000, _PAGE_IO);
  437. }
  438. }
  439. void __init
  440. chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
  441.   unsigned long r6, unsigned long r7)
  442. {
  443. #ifdef CONFIG_BLK_DEV_INITRD
  444. /* take care of initrd if we have one */
  445. if ( r6 )
  446. {
  447. initrd_start = r6 + KERNELBASE;
  448. initrd_end = r6 + r7 + KERNELBASE;
  449. }
  450. #endif /* CONFIG_BLK_DEV_INITRD */
  451. ISA_DMA_THRESHOLD = ~0L;
  452. DMA_MODE_READ = 0x44;
  453. DMA_MODE_WRITE = 0x48;
  454. isa_io_base = CHRP_ISA_IO_BASE; /* default value */
  455. ppc_md.setup_arch     = chrp_setup_arch;
  456. ppc_md.show_percpuinfo = of_show_percpuinfo;
  457. ppc_md.show_cpuinfo   = chrp_show_cpuinfo;
  458. ppc_md.irq_cannonicalize = chrp_irq_cannonicalize;
  459. #ifndef CONFIG_POWER4
  460. ppc_md.init_IRQ       = chrp_init_IRQ;
  461. ppc_md.get_irq        = openpic_get_irq;
  462. #else
  463. ppc_md.init_IRQ       = xics_init_IRQ;
  464. ppc_md.get_irq       = xics_get_irq;
  465. #endif /* CONFIG_POWER4 */
  466. ppc_md.init           = chrp_init2;
  467. ppc_md.restart        = chrp_restart;
  468. ppc_md.power_off      = chrp_power_off;
  469. ppc_md.halt           = chrp_halt;
  470. ppc_md.time_init      = chrp_time_init;
  471. ppc_md.set_rtc_time   = chrp_set_rtc_time;
  472. ppc_md.get_rtc_time   = chrp_get_rtc_time;
  473. ppc_md.calibrate_decr = chrp_calibrate_decr;
  474. ppc_md.find_end_of_memory = pmac_find_end_of_memory;
  475. ppc_md.setup_io_mappings = chrp_map_io;
  476. #ifdef CONFIG_VT
  477. /* these are adjusted in chrp_init2 if we have an ADB keyboard */
  478. ppc_md.kbd_setkeycode    = pckbd_setkeycode;
  479. ppc_md.kbd_getkeycode    = pckbd_getkeycode;
  480. ppc_md.kbd_translate     = pckbd_translate;
  481. ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
  482. ppc_md.kbd_leds          = pckbd_leds;
  483. ppc_md.kbd_init_hw       = pckbd_init_hw;
  484. #ifdef CONFIG_MAGIC_SYSRQ
  485. ppc_md.ppc_kbd_sysrq_xlate  = pckbd_sysrq_xlate;
  486. SYSRQ_KEY = 0x54;
  487. #endif /* CONFIG_MAGIC_SYSRQ */
  488. #endif /* CONFIG_VT */
  489. if (rtas_data) {
  490. struct device_node *rtas;
  491. unsigned int *p;
  492. rtas = find_devices("rtas");
  493. if (rtas != NULL) {
  494. if (get_property(rtas, "display-character", NULL)) {
  495. ppc_md.progress = rtas_display_progress;
  496. p = (unsigned int *) get_property
  497.        (rtas, "ibm,display-line-length", NULL);
  498. if (p)
  499. max_width = *p;
  500. } else if (get_property(rtas, "set-indicator", NULL))
  501. ppc_md.progress = rtas_indicator_progress;
  502. }
  503. }
  504. #ifdef CONFIG_BOOTX_TEXT
  505. if (ppc_md.progress == NULL && boot_text_mapped)
  506. ppc_md.progress = btext_progress;
  507. #endif
  508. #ifdef CONFIG_SMP
  509. #ifndef CONFIG_POWER4
  510. ppc_md.smp_ops = &chrp_smp_ops;
  511. #else
  512. ppc_md.smp_ops = &xics_smp_ops;
  513. #endif /* CONFIG_POWER4 */
  514. #endif /* CONFIG_SMP */
  515. #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
  516.         ppc_ide_md.ide_check_region = chrp_ide_check_region;
  517.         ppc_ide_md.ide_request_region = chrp_ide_request_region;
  518.         ppc_ide_md.ide_release_region = chrp_ide_release_region;
  519.         ppc_ide_md.ide_init_hwif = chrp_ide_init_hwif_ports;
  520. #endif
  521. /*
  522.  * Print the banner, then scroll down so boot progress
  523.  * can be printed.  -- Cort 
  524.  */
  525. if ( ppc_md.progress ) ppc_md.progress("Linux/PPC "UTS_RELEASE"n", 0x0);
  526. }
  527. void __chrp
  528. rtas_display_progress(char *s, unsigned short hex)
  529. {
  530. int width;
  531. char *os = s;
  532. if ( call_rtas( "display-character", 1, 1, NULL, 'r' ) )
  533. return;
  534. width = max_width;
  535. while ( *os )
  536. {
  537. if ( (*os == 'n') || (*os == 'r') )
  538. width = max_width;
  539. else
  540. width--;
  541. call_rtas( "display-character", 1, 1, NULL, *os++ );
  542. /* if we overwrite the screen length */
  543. if ( width == 0 )
  544. while ( (*os != 0) && (*os != 'n') && (*os != 'r') )
  545. os++;
  546. }
  547. /*while ( width-- > 0 )*/
  548. call_rtas( "display-character", 1, 1, NULL, ' ' );
  549. }
  550. void __chrp
  551. rtas_indicator_progress(char *s, unsigned short hex)
  552. {
  553. call_rtas("set-indicator", 3, 1, NULL, 6, 0, hex);
  554. }
  555. #ifdef CONFIG_BOOTX_TEXT
  556. void
  557. btext_progress(char *s, unsigned short hex)
  558. {
  559. prom_print(s);
  560. prom_print("n");
  561. }
  562. #endif /* CONFIG_BOOTX_TEXT */