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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * 
  3.  * Common boot and setup code.
  4.  *
  5.  * Copyright (C) 2001 PPC64 Team, IBM Corp
  6.  *
  7.  *      This program is free software; you can redistribute it and/or
  8.  *      modify it under the terms of the GNU General Public License
  9.  *      as published by the Free Software Foundation; either version
  10.  *      2 of the License, or (at your option) any later version.
  11.  */
  12. #include <linux/config.h>
  13. #include <linux/module.h>
  14. #include <linux/string.h>
  15. #include <linux/sched.h>
  16. #include <linux/init.h>
  17. #include <linux/reboot.h>
  18. #include <linux/delay.h>
  19. #include <linux/blk.h>
  20. #include <linux/ide.h>
  21. #include <linux/seq_file.h>
  22. #include <linux/ioport.h>
  23. #include <linux/console.h>
  24. #include <linux/version.h>
  25. #include <asm/init.h>
  26. #include <asm/io.h>
  27. #include <asm/prom.h>
  28. #include <asm/processor.h>
  29. #include <asm/pgtable.h>
  30. #include <asm/bootinfo.h>
  31. #include <asm/smp.h>
  32. #include <asm/elf.h>
  33. #include <asm/machdep.h>
  34. #include <asm/iSeries/LparData.h>
  35. #include <asm/naca.h>
  36. #include <asm/paca.h>
  37. #include <asm/ppcdebug.h>
  38. #include <asm/time.h>
  39. extern unsigned long klimit;
  40. /* extern void *stab; */
  41. extern HTAB htab_data;
  42. extern unsigned long loops_per_jiffy;
  43. extern int preferred_console; /* from kernel/printk.c */
  44. extern unsigned long embedded_sysmap_start;
  45. extern unsigned long embedded_sysmap_end;
  46. int have_of = 1;
  47. extern void  chrp_init(unsigned long r3,
  48.        unsigned long r4,
  49.        unsigned long r5,
  50.        unsigned long r6,
  51.        unsigned long r7);
  52. extern void chrp_init_map_io_space( void );
  53. extern void iSeries_init( void );
  54. extern void iSeries_init_early( void );
  55. extern void pSeries_init_early( void );
  56. extern void pSeriesLP_init_early(void);
  57. extern void mm_init_ppc64( void ); 
  58. unsigned long decr_overclock = 1;
  59. unsigned long decr_overclock_proc0 = 1;
  60. unsigned long decr_overclock_set = 0;
  61. unsigned long decr_overclock_proc0_set = 0;
  62. #ifdef CONFIG_XMON
  63. extern void xmon_map_scc(void);
  64. #endif
  65. #ifdef CONFIG_KDB
  66. extern void kdb_map_scc(void);
  67. #endif
  68. char saved_command_line[256];
  69. unsigned char aux_device_present;
  70. void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5,
  71.     unsigned long r6, unsigned long r7);
  72. int parse_bootinfo(void);
  73. #ifdef CONFIG_MAGIC_SYSRQ
  74. unsigned long SYSRQ_KEY;
  75. #endif /* CONFIG_MAGIC_SYSRQ */
  76. struct machdep_calls ppc_md;
  77. /*
  78.  * Perhaps we can put the pmac screen_info[] here
  79.  * on pmac as well so we don't need the ifdef's.
  80.  * Until we get multiple-console support in here
  81.  * that is.  -- Cort
  82.  * Maybe tie it to serial consoles, since this is really what
  83.  * these processors use on existing boards.  -- Dan
  84.  */ 
  85. struct screen_info screen_info = {
  86. 0, 25, /* orig-x, orig-y */
  87. 0, /* unused */
  88. 0, /* orig-video-page */
  89. 0, /* orig-video-mode */
  90. 80, /* orig-video-cols */
  91. 0,0,0, /* ega_ax, ega_bx, ega_cx */
  92. 25, /* orig-video-lines */
  93. 1, /* orig-video-isVGA */
  94. 16 /* orig-video-points */
  95. };
  96. /*
  97.  * These are used in binfmt_elf.c to put aux entries on the stack
  98.  * for each elf executable being started.
  99.  */
  100. int dcache_bsize;
  101. int icache_bsize;
  102. int ucache_bsize;
  103. static struct console udbg_console = {
  104. name: "udbg",
  105. write: udbg_console_write,
  106. flags: CON_PRINTBUFFER,
  107. index: -1,
  108. };
  109. /*
  110.  * Do some initial setup of the system.  The paramters are those which 
  111.  * were passed in from the bootloader.
  112.  */
  113. void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
  114.   unsigned long r6, unsigned long r7)
  115. {
  116. /* This should be fixed properly in kernel/resource.c */
  117. iomem_resource.end = MEM_SPACE_LIMIT;
  118. /* pSeries systems are identified in prom.c via OF. */
  119. if ( itLpNaca.xLparInstalled == 1 )
  120. naca->platform = PLATFORM_ISERIES_LPAR;
  121. switch (naca->platform) {
  122. case PLATFORM_ISERIES_LPAR:
  123. iSeries_init_early();
  124. break;
  125. #ifdef CONFIG_PPC_PSERIES
  126. case PLATFORM_PSERIES:
  127. pSeries_init_early();
  128. #ifdef CONFIG_BLK_DEV_INITRD
  129. initrd_start = initrd_end = 0;
  130. #endif
  131. parse_bootinfo();
  132. break;
  133. case PLATFORM_PSERIES_LPAR:
  134. pSeriesLP_init_early();
  135. #ifdef CONFIG_BLK_DEV_INITRD
  136. initrd_start = initrd_end = 0;
  137. #endif
  138. parse_bootinfo();
  139. break;
  140. #endif
  141. }
  142. if (naca->platform & PLATFORM_PSERIES) {
  143. register_console(&udbg_console);
  144. preferred_console = -1;
  145. }
  146. printk("Starting Linux PPC64 %sn", UTS_RELEASE);
  147. printk("-----------------------------------------------------n");
  148. printk("naca                       = 0x%pn", naca);
  149. printk("naca->processorCount       = 0x%xn", naca->processorCount);
  150. printk("naca->physicalMemorySize   = 0x%lxn", naca->physicalMemorySize);
  151. printk("naca->dCacheL1LineSize     = 0x%xn", naca->dCacheL1LineSize);
  152. printk("naca->dCacheL1LogLineSize  = 0x%xn", naca->dCacheL1LogLineSize);
  153. printk("naca->dCacheL1LinesPerPage = 0x%xn", naca->dCacheL1LinesPerPage);
  154. printk("naca->iCacheL1LineSize     = 0x%xn", naca->iCacheL1LineSize);
  155. printk("naca->iCacheL1LogLineSize  = 0x%xn", naca->iCacheL1LogLineSize);
  156. printk("naca->iCacheL1LinesPerPage = 0x%xn", naca->iCacheL1LinesPerPage);
  157. printk("naca->pftSize              = 0x%lxn", naca->pftSize);
  158. printk("naca->debug_switch         = 0x%lxn", naca->debug_switch);
  159. printk("naca->interrupt_controller = 0x%lxn", naca->interrupt_controller);
  160. printk("htab_data.htab             = 0x%pn", htab_data.htab);
  161. printk("htab_data.num_ptegs        = 0x%lxn", htab_data.htab_num_ptegs);
  162. printk("-----------------------------------------------------n");
  163. if (naca->platform & PLATFORM_PSERIES) {
  164. finish_device_tree();
  165. chrp_init(r3, r4, r5, r6, r7);
  166. }
  167. mm_init_ppc64();
  168. switch (naca->platform) {
  169.     case PLATFORM_ISERIES_LPAR:
  170. iSeries_init();
  171. break;
  172.     default:
  173. /* The following relies on the device tree being */
  174. /* fully configured.                             */
  175. parse_cmd_line(r3, r4, r5, r6, r7);
  176. }
  177. ppc64_boot_msg(0x10, "Setup System");
  178. }
  179. /* This is called just before console_init().
  180.  * It will be obsolete when Linux gets real early console support (2.5?)
  181.  * We need to hack preferred_console to retain the correct behavior
  182.  */
  183. void setup_before_console_init(void)
  184. {
  185. if (naca->platform & PLATFORM_PSERIES) {
  186. int save = preferred_console;
  187. unregister_console(&udbg_console);
  188. preferred_console = save;
  189. }
  190. }
  191. void machine_restart(char *cmd)
  192. {
  193. ppc_md.restart(cmd);
  194. }
  195.   
  196. void machine_power_off(void)
  197. {
  198. ppc_md.power_off();
  199. }
  200.   
  201. void machine_halt(void)
  202. {
  203. ppc_md.halt();
  204. }
  205. unsigned long ppc_proc_freq;
  206. unsigned long ppc_tb_freq;
  207. static int show_cpuinfo(struct seq_file *m, void *v)
  208. {
  209. unsigned long cpu_id = (unsigned long)v - 1;
  210. unsigned int pvr;
  211. unsigned short maj;
  212. unsigned short min;
  213. #ifdef CONFIG_SMP
  214. if (cpu_id == NR_CPUS) {
  215. if (ppc_md.get_cpuinfo != NULL)
  216. ppc_md.get_cpuinfo(m);
  217. return 0;
  218. }
  219. if (!(cpu_online_map & (1<<cpu_id)))
  220. return 0;
  221. #endif
  222. pvr = paca[cpu_id].pvr;
  223. maj = (pvr >> 8) & 0xFF;
  224. min = pvr & 0xFF;
  225. seq_printf(m, "processort: %lun", cpu_id);
  226. seq_printf(m, "cputt: ");
  227. pvr = paca[cpu_id].pvr;
  228. switch (PVR_VER(pvr)) {
  229. case PV_NORTHSTAR:
  230. seq_printf(m, "RS64-II (northstar)n");
  231. break;
  232. case PV_PULSAR:
  233. seq_printf(m, "RS64-III (pulsar)n");
  234. break;
  235. case PV_POWER4:
  236. seq_printf(m, "POWER4 (gp)n");
  237. break;
  238. case PV_ICESTAR:
  239. seq_printf(m, "RS64-III (icestar)n");
  240. break;
  241. case PV_SSTAR:
  242. seq_printf(m, "RS64-IV (sstar)n");
  243. break;
  244. case PV_630:
  245. seq_printf(m, "POWER3 (630)n");
  246. break;
  247. case PV_630p:
  248. seq_printf(m, "POWER3 (630+)n");
  249. break;
  250. case PV_POWER4p:
  251. seq_printf(m, "POWER4+ (gq)n");
  252. break;
  253. default:
  254. seq_printf(m, "Unknown (%08x)n", pvr);
  255. break;
  256. }
  257. /*
  258.  * Assume here that all clock rates are the same in a
  259.  * smp system.  -- Cort
  260.  */
  261. if (naca->platform != PLATFORM_ISERIES_LPAR) {
  262. struct device_node *cpu_node;
  263. int *fp;
  264. cpu_node = find_type_devices("cpu");
  265. if (cpu_node) {
  266. fp = (int *) get_property(cpu_node, "clock-frequency",
  267.   NULL);
  268. if (fp)
  269. seq_printf(m, "clocktt: %dMHzn",
  270.    *fp / 1000000);
  271. }
  272. }
  273. if (ppc_md.setup_residual != NULL)
  274. ppc_md.setup_residual(m, cpu_id);
  275. seq_printf(m, "revisiont: %hd.%hdnn", maj, min);
  276. return 0;
  277. }
  278. static void *c_start(struct seq_file *m, loff_t *pos)
  279. {
  280. return *pos <= NR_CPUS ? (void *)((*pos)+1) : NULL;
  281. }
  282. static void *c_next(struct seq_file *m, void *v, loff_t *pos)
  283. {
  284. ++*pos;
  285. return c_start(m, pos);
  286. }
  287. static void c_stop(struct seq_file *m, void *v)
  288. {
  289. }
  290. struct seq_operations cpuinfo_op = {
  291. start: c_start,
  292. next: c_next,
  293. stop: c_stop,
  294. show: show_cpuinfo,
  295. };
  296. /*
  297.  * Fetch the cmd_line from open firmware. */
  298. void parse_cmd_line(unsigned long r3, unsigned long r4, unsigned long r5,
  299.   unsigned long r6, unsigned long r7)
  300. {
  301. struct device_node *chosen;
  302. char *p;
  303. #ifdef CONFIG_BLK_DEV_INITRD
  304. if ((initrd_start == 0) && r3 && r4 && r4 != 0xdeadbeef) {
  305. initrd_start = (r3 >= KERNELBASE) ? r3 : (unsigned long)__va(r3);
  306. initrd_end = initrd_start + r4;
  307. ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
  308. initrd_below_start_ok = 1;
  309. }
  310. #endif
  311. /* Look for mem= option on command line */
  312. if (strstr(cmd_line, "mem=")) {
  313. char *q;
  314. unsigned long maxmem = 0;
  315. extern unsigned long __max_memory;
  316. for (q = cmd_line; (p = strstr(q, "mem=")) != 0; ) {
  317. q = p + 4;
  318. if (p > cmd_line && p[-1] != ' ')
  319. continue;
  320. maxmem = simple_strtoul(q, &q, 0);
  321. if (*q == 'k' || *q == 'K') {
  322. maxmem <<= 10;
  323. ++q;
  324. } else if (*q == 'm' || *q == 'M') {
  325. maxmem <<= 20;
  326. ++q;
  327. }
  328. }
  329. __max_memory = maxmem;
  330. }
  331. }
  332. char *bi_tag2str(unsigned long tag)
  333. {
  334. switch (tag) {
  335. case BI_FIRST:
  336. return "BI_FIRST";
  337. case BI_LAST:
  338. return "BI_LAST";
  339. case BI_CMD_LINE:
  340. return "BI_CMD_LINE";
  341. case BI_BOOTLOADER_ID:
  342. return "BI_BOOTLOADER_ID";
  343. case BI_INITRD:
  344. return "BI_INITRD";
  345. case BI_SYSMAP:
  346. return "BI_SYSMAP";
  347. case BI_MACHTYPE:
  348. return "BI_MACHTYPE";
  349. default:
  350. return "BI_UNKNOWN";
  351. }
  352. }
  353. int parse_bootinfo(void)
  354. {
  355. struct bi_record *rec;
  356. extern char *sysmap;
  357. extern unsigned long sysmap_size;
  358. rec = prom.bi_recs;
  359. if ( rec == NULL || rec->tag != BI_FIRST )
  360. return -1;
  361. for ( ; rec->tag != BI_LAST ; rec = bi_rec_next(rec) ) {
  362. switch (rec->tag) {
  363. case BI_CMD_LINE:
  364. memcpy(cmd_line, (void *)rec->data, rec->size);
  365. break;
  366. case BI_SYSMAP:
  367. sysmap = (char *)((rec->data[0] >= (KERNELBASE))
  368. ? rec->data[0] : (unsigned long)__va(rec->data[0]));
  369. sysmap_size = rec->data[1];
  370. break;
  371. #ifdef CONFIG_BLK_DEV_INITRD
  372. case BI_INITRD:
  373. initrd_start = (unsigned long)__va(rec->data[0]);
  374. initrd_end = initrd_start + rec->data[1];
  375. ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
  376. initrd_below_start_ok = 1;
  377. break;
  378. #endif /* CONFIG_BLK_DEV_INITRD */
  379. }
  380. }
  381. return 0;
  382. }
  383. void __init ppc_init(void)
  384. {
  385. /* clear the progress line */
  386. ppc_md.progress(" ", 0xffff);
  387. if (ppc_md.init != NULL) {
  388. ppc_md.init();
  389. }
  390. }
  391. void __init ppc64_calibrate_delay(void)
  392. {
  393. loops_per_jiffy = tb_ticks_per_jiffy;
  394. printk("Calibrating delay loop... %lu.%02lu BogoMipsn",
  395.        loops_per_jiffy/(500000/HZ),
  396.        loops_per_jiffy/(5000/HZ) % 100);
  397. }
  398. extern void (*calibrate_delay)(void);
  399. /*
  400.  * Called into from start_kernel, after lock_kernel has been called.
  401.  * Initializes bootmem, which is unsed to manage page allocation until
  402.  * mem_init is called.
  403.  */
  404. void __init setup_arch(char **cmdline_p)
  405. {
  406. extern int panic_timeout;
  407. extern char _etext[], _edata[];
  408. extern void do_init_bootmem(void);
  409. calibrate_delay = ppc64_calibrate_delay;
  410. ppc64_boot_msg(0x12, "Setup Arch");
  411. #ifdef CONFIG_XMON
  412. xmon_map_scc();
  413. if (strstr(cmd_line, "xmon"))
  414. xmon(0);
  415. #endif /* CONFIG_XMON */
  416. #ifdef CONFIG_KDB
  417. kdb_map_scc();
  418. if (strstr(cmd_line, "kdb=early"))
  419. kdb(KDB_REASON_CALL,0,0);
  420. #endif
  421. #if defined(CONFIG_KGDB)
  422. kgdb_map_scc();
  423. set_debug_traps();
  424. breakpoint();
  425. #endif
  426. /*
  427.  * Set cache line size based on type of cpu as a default.
  428.  * Systems with OF can look in the properties on the cpu node(s)
  429.  * for a possibly more accurate value.
  430.  */
  431. dcache_bsize = naca->dCacheL1LineSize; 
  432. icache_bsize = naca->iCacheL1LineSize; 
  433. /* reboot on panic */
  434. panic_timeout = 180;
  435. init_mm.start_code = PAGE_OFFSET;
  436. init_mm.end_code = (unsigned long) _etext;
  437. init_mm.end_data = (unsigned long) _edata;
  438. init_mm.brk = (unsigned long) klimit;
  439. /* Save unparsed command line copy for /proc/cmdline */
  440. strcpy(saved_command_line, cmd_line);
  441. *cmdline_p = cmd_line;
  442. /* set up the bootmem stuff with available memory */
  443. do_init_bootmem();
  444. ppc_md.setup_arch();
  445. paging_init();
  446. ppc64_boot_msg(0x15, "Setup Done");
  447. }
  448. #ifdef CONFIG_IDE
  449. /* Convert the shorts/longs in hd_driveid from little to big endian;
  450.  * chars are endian independant, of course, but strings need to be flipped.
  451.  * (Despite what it says in drivers/block/ide.h, they come up as little
  452.  * endian...)
  453.  *
  454.  * Changes to linux/hdreg.h may require changes here. */
  455. void ppc64_ide_fix_driveid(struct hd_driveid *id)
  456. {
  457.         int i;
  458. unsigned short *stringcast;
  459. id->config         = __le16_to_cpu(id->config);
  460. id->cyls           = __le16_to_cpu(id->cyls);
  461. id->reserved2      = __le16_to_cpu(id->reserved2);
  462. id->heads          = __le16_to_cpu(id->heads);
  463. id->track_bytes    = __le16_to_cpu(id->track_bytes);
  464. id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
  465. id->sectors        = __le16_to_cpu(id->sectors);
  466. id->vendor0        = __le16_to_cpu(id->vendor0);
  467. id->vendor1        = __le16_to_cpu(id->vendor1);
  468. id->vendor2        = __le16_to_cpu(id->vendor2);
  469. stringcast = (unsigned short *)&id->serial_no[0];
  470. for (i = 0; i < (20/2); i++)
  471.         stringcast[i] = __le16_to_cpu(stringcast[i]);
  472. id->buf_type       = __le16_to_cpu(id->buf_type);
  473. id->buf_size       = __le16_to_cpu(id->buf_size);
  474. id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
  475. stringcast = (unsigned short *)&id->fw_rev[0];
  476. for (i = 0; i < (8/2); i++)
  477.         stringcast[i] = __le16_to_cpu(stringcast[i]);
  478. stringcast = (unsigned short *)&id->model[0];
  479. for (i = 0; i < (40/2); i++)
  480.         stringcast[i] = __le16_to_cpu(stringcast[i]);
  481. id->dword_io       = __le16_to_cpu(id->dword_io);
  482. id->reserved50     = __le16_to_cpu(id->reserved50);
  483. id->field_valid    = __le16_to_cpu(id->field_valid);
  484. id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
  485. id->cur_heads      = __le16_to_cpu(id->cur_heads);
  486. id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
  487. id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
  488. id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
  489. id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
  490. id->dma_1word      = __le16_to_cpu(id->dma_1word);
  491. id->dma_mword      = __le16_to_cpu(id->dma_mword);
  492. id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
  493. id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
  494. id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
  495. id->eide_pio       = __le16_to_cpu(id->eide_pio);
  496. id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
  497. for (i = 0; i < 2; i++)
  498. id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
  499.         for (i = 0; i < 4; i++)
  500.                 id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
  501. id->queue_depth    = __le16_to_cpu(id->queue_depth);
  502. for (i = 0; i < 4; i++)
  503. id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
  504. id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
  505. id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
  506. id->command_set_1  = __le16_to_cpu(id->command_set_1);
  507. id->command_set_2  = __le16_to_cpu(id->command_set_2);
  508. id->cfsse          = __le16_to_cpu(id->cfsse);
  509. id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
  510. id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
  511. id->csf_default    = __le16_to_cpu(id->csf_default);
  512. id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
  513. id->word89         = __le16_to_cpu(id->word89);
  514. id->word90         = __le16_to_cpu(id->word90);
  515. id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
  516. id->word92         = __le16_to_cpu(id->word92);
  517. id->hw_config      = __le16_to_cpu(id->hw_config);
  518. id->acoustic       = __le16_to_cpu(id->acoustic);
  519. for (i = 0; i < 5; i++)
  520. id->words95_99[i]  = __le16_to_cpu(id->words95_99[i]);
  521. id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
  522. for (i = 0; i < 21; i++)
  523. id->words104_125[i]  = __le16_to_cpu(id->words104_125[i]);
  524. id->last_lun       = __le16_to_cpu(id->last_lun);
  525. id->word127        = __le16_to_cpu(id->word127);
  526. id->dlf            = __le16_to_cpu(id->dlf);
  527. id->csfo           = __le16_to_cpu(id->csfo);
  528. for (i = 0; i < 26; i++)
  529. id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
  530. id->word156        = __le16_to_cpu(id->word156);
  531. for (i = 0; i < 3; i++)
  532. id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
  533. id->cfa_power=__le16_to_cpu(id->cfa_power);
  534. for (i = 0; i < 15; i++)
  535. id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
  536. for (i = 0; i < 29; i++)
  537. id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
  538. for (i = 0; i < 48; i++)
  539. id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
  540. id->integrity_word=__le16_to_cpu(id->integrity_word);
  541. }
  542. #endif
  543. /* ToDo: do something useful if ppc_md is not yet setup. */
  544. #define PPC64_LINUX_FUNCTION 0x0f000000
  545. #define PPC64_IPL_MESSAGE 0xc0000000
  546. #define PPC64_TERM_MESSAGE 0xb0000000
  547. #define PPC64_ATTN_MESSAGE 0xa0000000
  548. #define PPC64_DUMP_MESSAGE 0xd0000000
  549. static void ppc64_do_msg(unsigned int src, const char *msg)
  550. {
  551. if (ppc_md.progress) {
  552. char buf[32];
  553. sprintf(buf, "%08x        n", src);
  554. ppc_md.progress(buf, 0);
  555. sprintf(buf, "%-16s", msg);
  556. ppc_md.progress(buf, 0);
  557. }
  558. }
  559. /* Print a boot progress message. */
  560. void ppc64_boot_msg(unsigned int src, const char *msg)
  561. {
  562. ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_IPL_MESSAGE|src, msg);
  563. printk("[boot]%04x %sn", src, msg);
  564. }
  565. /* Print a termination message (print only -- does not stop the kernel) */
  566. void ppc64_terminate_msg(unsigned int src, const char *msg)
  567. {
  568. ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_TERM_MESSAGE|src, msg);
  569. printk("[terminate]%04x %sn", src, msg);
  570. }
  571. /* Print something that needs attention (device error, etc) */
  572. void ppc64_attention_msg(unsigned int src, const char *msg)
  573. {
  574. ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_ATTN_MESSAGE|src, msg);
  575. printk("[attention]%04x %sn", src, msg);
  576. }
  577. /* Print a dump progress message. */
  578. void ppc64_dump_msg(unsigned int src, const char *msg)
  579. {
  580. ppc64_do_msg(PPC64_LINUX_FUNCTION|PPC64_DUMP_MESSAGE|src, msg);
  581. printk("[dump]%04x %sn", src, msg);
  582. }
  583. void exception_trace(unsigned long trap)
  584. {
  585. unsigned long x, srr0, srr1, reg20, reg1, reg21;
  586. asm("mflr %0" : "=r" (x) :);
  587. asm("mfspr %0,0x1a" : "=r" (srr0) :);
  588. asm("mfspr %0,0x1b" : "=r" (srr1) :);
  589. asm("mr %0,1" : "=r" (reg1) :);
  590. asm("mr %0,20" : "=r" (reg20) :);
  591. asm("mr %0,21" : "=r" (reg21) :);
  592. udbg_puts("n");
  593. udbg_puts("Took an exception : "); udbg_puthex(x); udbg_puts("n");
  594. udbg_puts("   "); udbg_puthex(reg1); udbg_puts("n");
  595. udbg_puts("   "); udbg_puthex(reg20); udbg_puts("n");
  596. udbg_puts("   "); udbg_puthex(reg21); udbg_puts("n");
  597. udbg_puts("   "); udbg_puthex(srr0); udbg_puts("n");
  598. udbg_puts("   "); udbg_puthex(srr1); udbg_puts("n");
  599. }
  600. int set_spread_lpevents( char * str )
  601. {
  602. /* The parameter is the number of processors to share in processing lp events */
  603. unsigned long i;
  604. unsigned long val = simple_strtoul( str, NULL, 0 );
  605. if ( ( val > 0 ) && ( val <= MAX_PACAS ) ) {
  606. for ( i=1; i<val; ++i )
  607. paca[i].lpQueuePtr = paca[0].lpQueuePtr;
  608. printk("lpevent processing spread over %ld processorsn", val);
  609. }
  610. else
  611. printk("invalid spreaqd_lpevents %ldn", val);
  612. return 1;
  613. }
  614. /* This should only be called on processor 0 during calibrate decr */
  615. void setup_default_decr(void)
  616. {
  617. struct paca_struct *lpaca = get_paca();
  618. if ( decr_overclock_set && !decr_overclock_proc0_set )
  619. decr_overclock_proc0 = decr_overclock;
  620. lpaca->default_decr = tb_ticks_per_jiffy / decr_overclock_proc0;
  621. lpaca->next_jiffy_update_tb = get_tb() + tb_ticks_per_jiffy;
  622. }
  623. int set_decr_overclock_proc0( char * str )
  624. {
  625. unsigned long val = simple_strtoul( str, NULL, 0 );
  626. if ( ( val >= 1 ) && ( val <= 48 ) ) {
  627. decr_overclock_proc0_set = 1;
  628. decr_overclock_proc0 = val;
  629. printk("proc 0 decrementer overclock factor of %ldn", val);
  630. }
  631. else
  632. printk("invalid proc 0 decrementer overclock factor of %ldn", val);
  633. return 1;
  634. }
  635. int set_decr_overclock( char * str )
  636. {
  637. unsigned long val = simple_strtoul( str, NULL, 0 );
  638. if ( ( val >= 1 ) && ( val <= 48 ) ) {
  639. decr_overclock_set = 1;
  640. decr_overclock = val;
  641. printk("decrementer overclock factor of %ldn", val);
  642. }
  643. else
  644. printk("invalid decrementer overclock factor of %ldn", val);
  645. return 1;
  646. }
  647. __setup("spread_lpevents=", set_spread_lpevents );
  648. __setup("decr_overclock_proc0=", set_decr_overclock_proc0 );
  649. __setup("decr_overclock=", set_decr_overclock );