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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/ppc/kernel/setup.c
  3.  *
  4.  *  Copyright (C) 1995  Linus Torvalds
  5.  *  Adapted from 'alpha' version by Gary Thomas
  6.  *  Modified by Cort Dougan (cort@cs.nmt.edu)
  7.  *  Modified by PPC64 Team, IBM Corp
  8.  *
  9.  * This program is free software; you can redistribute it and/or
  10.  * modify it under the terms of the GNU General Public License
  11.  * as published by the Free Software Foundation; either version
  12.  * 2 of the License, or (at your option) any later version.
  13.  */
  14. /*
  15.  * bootup setup stuff..
  16.  */
  17. #include <linux/config.h>
  18. #include <linux/errno.h>
  19. #include <linux/sched.h>
  20. #include <linux/kernel.h>
  21. #include <linux/mm.h>
  22. #include <linux/stddef.h>
  23. #include <linux/unistd.h>
  24. #include <linux/ptrace.h>
  25. #include <linux/slab.h>
  26. #include <linux/user.h>
  27. #include <linux/a.out.h>
  28. #include <linux/tty.h>
  29. #include <linux/major.h>
  30. #include <linux/interrupt.h>
  31. #include <linux/reboot.h>
  32. #include <linux/init.h>
  33. #include <linux/blk.h>
  34. #include <linux/ioport.h>
  35. #include <linux/console.h>
  36. #include <linux/pci.h>
  37. #include <linux/version.h>
  38. #include <linux/adb.h>
  39. #include <linux/module.h>
  40. #include <linux/delay.h>
  41. #include <linux/irq.h>
  42. #include <linux/seq_file.h>
  43. #include <asm/mmu.h>
  44. #include <asm/processor.h>
  45. #include <asm/io.h>
  46. #include <asm/pgtable.h>
  47. #include <asm/prom.h>
  48. #include <asm/rtas.h>
  49. #include <asm/pci-bridge.h>
  50. #include <asm/pci_dma.h>
  51. #include <asm/dma.h>
  52. #include <asm/machdep.h>
  53. #include <asm/irq.h>
  54. #include <asm/keyboard.h>
  55. #include <asm/init.h>
  56. #include <asm/naca.h>
  57. #include <asm/time.h>
  58. #include "local_irq.h"
  59. #include "i8259.h"
  60. #include "open_pic.h"
  61. #include "xics.h"
  62. #include <asm/ppcdebug.h>
  63. extern volatile unsigned char *chrp_int_ack_special;
  64. void chrp_setup_pci_ptrs(void);
  65. void chrp_progress(char *, unsigned short);
  66. void chrp_request_regions(void);
  67. extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);
  68. extern int pckbd_getkeycode(unsigned int scancode);
  69. extern int pckbd_translate(unsigned char scancode, unsigned char *keycode,
  70.    char raw_mode);
  71. extern char pckbd_unexpected_up(unsigned char keycode);
  72. extern void pckbd_leds(unsigned char leds);
  73. extern void pckbd_init_hw(void);
  74. extern unsigned char pckbd_sysrq_xlate[128];
  75. extern void openpic_init_IRQ(void);
  76. extern void init_ras_IRQ(void);
  77. extern void find_and_init_phbs(void);
  78. extern void pSeries_pcibios_fixup(void);
  79. extern void iSeries_pcibios_fixup(void);
  80. extern void pSeries_get_rtc_time(struct rtc_time *rtc_time);
  81. extern int  pSeries_set_rtc_time(struct rtc_time *rtc_time);
  82. void pSeries_calibrate_decr(void);
  83. static void fwnmi_init(void);
  84. extern void SystemReset_FWNMI(void), MachineCheck_FWNMI(void); /* from head.S */
  85. int fwnmi_active;  /* TRUE if an FWNMI handler is present */
  86. kdev_t boot_dev;
  87. unsigned long  virtPython0Facilities = 0;  // python0 facility area (memory mapped io) (64-bit format) VIRTUAL address.
  88. extern HPTE *Hash, *Hash_end;
  89. extern unsigned long Hash_size, Hash_mask;
  90. extern int probingmem;
  91. extern unsigned long loops_per_jiffy;
  92. extern unsigned long ppc_proc_freq;
  93. extern unsigned long ppc_tb_freq;
  94. #ifdef CONFIG_BLK_DEV_RAM
  95. extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */
  96. extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */
  97. extern int rd_image_start; /* starting block # of image */
  98. #endif
  99. void 
  100. chrp_get_cpuinfo(struct seq_file *m)
  101. {
  102. struct device_node *root;
  103. const char *model = "";
  104. seq_printf(m, "timebaset: %lun", ppc_tb_freq);
  105. root = find_path_device("/");
  106. if (root)
  107. model = get_property(root, "model", NULL);
  108. seq_printf(m, "machinett: CHRP %sn", model);
  109. }
  110. void __init chrp_request_regions(void) {
  111. request_region(0x20,0x20,"pic1");
  112. request_region(0xa0,0x20,"pic2");
  113. request_region(0x00,0x20,"dma1");
  114. request_region(0x40,0x20,"timer");
  115. request_region(0x80,0x10,"dma page reg");
  116. request_region(0xc0,0x20,"dma2");
  117. }
  118. void __init
  119. chrp_setup_arch(void)
  120. {
  121. extern char cmd_line[];
  122. struct device_node *root;
  123. unsigned int *opprop;
  124. /* openpic global configuration register (64-bit format). */
  125. /* openpic Interrupt Source Unit pointer (64-bit format). */
  126. /* python0 facility area (mmio) (64-bit format) REAL address. */
  127. /* init to some ~sane value until calibrate_delay() runs */
  128. loops_per_jiffy = 50000000;
  129. #ifdef CONFIG_BLK_DEV_INITRD
  130. /* this is fine for chrp */
  131. initrd_below_start_ok = 1;
  132. if (initrd_start)
  133. ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
  134. else
  135. #endif
  136. ROOT_DEV = to_kdev_t(0x0802); /* sda2 (sda1 is for the kernel) */
  137. printk("Boot arguments: %sn", cmd_line);
  138. fwnmi_init();
  139. /* Find and initialize PCI host bridges */
  140. /* iSeries needs to be done much later. */
  141.   #ifndef CONFIG_PPC_ISERIES
  142. find_and_init_phbs();
  143.   #endif
  144. /* Find the Open PIC if present */
  145. root = find_path_device("/");
  146. opprop = (unsigned int *) get_property(root,
  147. "platform-open-pic", NULL);
  148. if (opprop != 0) {
  149. int n = prom_n_addr_cells(root);
  150. unsigned long openpic;
  151. for (openpic = 0; n > 0; --n)
  152. openpic = (openpic << 32) + *opprop++;
  153. printk(KERN_DEBUG "OpenPIC addr: %lxn", openpic);
  154. OpenPIC_Addr = __ioremap(openpic, 0x40000, _PAGE_NO_CACHE);
  155. }
  156. #ifdef CONFIG_DUMMY_CONSOLE
  157. conswitchp = &dummy_con;
  158. #endif
  159. }
  160. void __init
  161. chrp_init2(void)
  162. {
  163. /*
  164.  * It is sensitive, when this is called (not too earlu)
  165.  * -- tibit
  166.  */
  167. chrp_request_regions();
  168. /* Manually leave the kernel version on the panel. */
  169. ppc_md.progress("Linux ppc64n", 0);
  170. ppc_md.progress(UTS_RELEASE, 0);
  171. }
  172. /* Initialize firmware assisted non-maskable interrupts if
  173.  * the firmware supports this feature.
  174.  *
  175.  */
  176. static void __init fwnmi_init(void)
  177. {
  178. long ret;
  179. int ibm_nmi_register = rtas_token("ibm,nmi-register");
  180. if (ibm_nmi_register == RTAS_UNKNOWN_SERVICE)
  181. return;
  182. ret = rtas_call(ibm_nmi_register, 2, 1, NULL,
  183. __pa((unsigned long)SystemReset_FWNMI),
  184. __pa((unsigned long)MachineCheck_FWNMI));
  185. if (ret == 0)
  186. fwnmi_active = 1;
  187. }
  188. /* Early initialization.  Relocation is on but do not reference unbolted pages */
  189. void __init pSeries_init_early(void)
  190. {
  191. #ifdef CONFIG_PPC_PSERIES /* This ifdef should go away */
  192. void *comport;
  193. hpte_init_pSeries();
  194. tce_init_pSeries();
  195. pSeries_pcibios_init_early();
  196. #ifdef CONFIG_SMP
  197. smp_init_pSeries();
  198. #endif
  199. /* Map the uart for udbg. */
  200. comport = (void *)__ioremap(naca->serialPortAddr, 16, _PAGE_NO_CACHE);
  201. udbg_init_uart(comport);
  202. ppc_md.udbg_putc = udbg_putc;
  203. ppc_md.udbg_getc = udbg_getc;
  204. ppc_md.udbg_getc_poll = udbg_getc_poll;
  205. #endif
  206. }
  207. void __init
  208. chrp_init(unsigned long r3, unsigned long r4, unsigned long r5,
  209.   unsigned long r6, unsigned long r7)
  210. {
  211. #if 0 /* PPPBBB remove this later... -Peter */
  212. #ifdef CONFIG_BLK_DEV_INITRD
  213. /* take care of initrd if we have one */
  214. if ( r6 )
  215. {
  216. initrd_start = __va(r6);
  217. initrd_end = __va(r6 + r7);
  218. }
  219. #endif /* CONFIG_BLK_DEV_INITRD */
  220. #endif
  221. ppc_md.ppc_machine = naca->platform;
  222. ppc_md.setup_arch     = chrp_setup_arch;
  223. ppc_md.setup_residual = NULL;
  224. ppc_md.get_cpuinfo    = chrp_get_cpuinfo;
  225. if(naca->interrupt_controller == IC_OPEN_PIC) {
  226. ppc_md.init_IRQ       = openpic_init_IRQ; 
  227. ppc_md.get_irq        = openpic_get_irq;
  228. } else {
  229. ppc_md.init_IRQ       = xics_init_IRQ;
  230. ppc_md.get_irq        = xics_get_irq;
  231. }
  232. ppc_md.init_ras_IRQ = init_ras_IRQ;
  233.   #ifndef CONFIG_PPC_ISERIES
  234.   ppc_md.pcibios_fixup = pSeries_pcibios_fixup;
  235.   #else 
  236.   ppc_md.pcibios_fixup = NULL;
  237.   // ppc_md.pcibios_fixup = iSeries_pcibios_fixup;
  238.   #endif
  239. ppc_md.init           = chrp_init2;
  240. ppc_md.restart        = rtas_restart;
  241. ppc_md.power_off      = rtas_power_off;
  242. ppc_md.halt           = rtas_halt;
  243. ppc_md.time_init      = NULL;
  244. ppc_md.get_boot_time  = pSeries_get_rtc_time;
  245. ppc_md.get_rtc_time   = pSeries_get_rtc_time;
  246. ppc_md.set_rtc_time   = pSeries_set_rtc_time;
  247. ppc_md.calibrate_decr = pSeries_calibrate_decr;
  248. ppc_md.progress = chrp_progress;
  249. #ifdef CONFIG_VT
  250. ppc_md.kbd_setkeycode    = pckbd_setkeycode;
  251. ppc_md.kbd_getkeycode    = pckbd_getkeycode;
  252. ppc_md.kbd_translate     = pckbd_translate;
  253. ppc_md.kbd_unexpected_up = pckbd_unexpected_up;
  254. ppc_md.kbd_leds          = pckbd_leds;
  255. ppc_md.kbd_init_hw       = pckbd_init_hw;
  256. #ifdef CONFIG_MAGIC_SYSRQ
  257. ppc_md.ppc_kbd_sysrq_xlate = pckbd_sysrq_xlate;
  258. SYSRQ_KEY = 0x63; /* Print Screen */
  259. #endif
  260. #endif
  261. }
  262. void __chrp
  263. chrp_progress(char *s, unsigned short hex)
  264. {
  265. struct device_node *root;
  266. int width, *p;
  267. char *os;
  268. static int display_character, set_indicator;
  269. static int max_width;
  270. if (!rtas.base)
  271. return;
  272. if (max_width == 0) {
  273. if ( (root = find_path_device("/rtas")) &&
  274.      (p = (unsigned int *)get_property(root,
  275.        "ibm,display-line-length",
  276.        NULL)) )
  277. max_width = *p;
  278. else
  279. max_width = 0x10;
  280. display_character = rtas_token("display-character");
  281. set_indicator = rtas_token("set-indicator");
  282. }
  283. if (display_character == RTAS_UNKNOWN_SERVICE) {
  284. /* use hex display */
  285. if (set_indicator == RTAS_UNKNOWN_SERVICE)
  286. return;
  287. rtas_call(set_indicator, 3, 1, NULL, 6, 0, hex);
  288. return;
  289. }
  290. rtas_call(display_character, 1, 1, NULL, 'r');
  291. width = max_width;
  292. os = s;
  293. while ( *os )
  294. {
  295. if ( (*os == 'n') || (*os == 'r') )
  296. width = max_width;
  297. else
  298. width--;
  299. rtas_call(display_character, 1, 1, NULL, *os++ );
  300. /* if we overwrite the screen length */
  301. if ( width == 0 )
  302. while ( (*os != 0) && (*os != 'n') && (*os != 'r') )
  303. os++;
  304. }
  305. /* Blank to end of line. */
  306. while ( width-- > 0 )
  307. rtas_call(display_character, 1, 1, NULL, ' ' );
  308. }
  309. extern void setup_default_decr(void);
  310. void __init pSeries_calibrate_decr(void)
  311. {
  312. struct device_node *cpu;
  313. struct div_result divres;
  314. int *fp;
  315. unsigned long freq, processor_freq;
  316. /*
  317.  * The cpu node should have a timebase-frequency property
  318.  * to tell us the rate at which the decrementer counts. 
  319.  */
  320. freq = 16666000;        /* hardcoded default */
  321. cpu = find_type_devices("cpu");
  322. if (cpu != 0) { 
  323. fp = (int *) get_property(cpu, "timebase-frequency", NULL);
  324. if (fp != 0)
  325. freq = *fp;
  326. }
  327. ppc_tb_freq = freq;
  328. processor_freq = freq;
  329. if (cpu != 0) {
  330. fp = (int *) get_property(cpu, "clock-frequency", NULL);
  331. if (fp != 0)
  332. processor_freq = *fp;
  333. }
  334. ppc_proc_freq = processor_freq;
  335.         printk("time_init: decrementer frequency = %lu.%.6lu MHzn", 
  336.        freq/1000000, freq%1000000 );
  337. printk("time_init: processor frequency   = %lu.%.6lu MHzn",
  338. processor_freq/1000000, processor_freq%1000000 );
  339. tb_ticks_per_jiffy = freq / HZ;
  340. tb_ticks_per_sec = tb_ticks_per_jiffy * HZ;
  341. tb_ticks_per_usec = freq / 1000000;
  342. div128_by_32( 1024*1024, 0, tb_ticks_per_sec, &divres );
  343. tb_to_xs = divres.result_low;
  344. setup_default_decr();
  345. }