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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Architecture-specific setup.
  3.  *
  4.  * Copyright (C) 1998-2001 Hewlett-Packard Co
  5.  * David Mosberger-Tang <davidm@hpl.hp.com>
  6.  * Stephane Eranian <eranian@hpl.hp.com>
  7.  * Copyright (C) 2000, Rohit Seth <rohit.seth@intel.com>
  8.  * Copyright (C) 1999 VA Linux Systems
  9.  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
  10.  *
  11.  * 11/12/01 D.Mosberger Convert get_cpuinfo() to seq_file based show_cpuinfo().
  12.  * 04/04/00 D.Mosberger renamed cpu_initialized to cpu_online_map
  13.  * 03/31/00 R.Seth cpu_initialized and current->processor fixes
  14.  * 02/04/00 D.Mosberger some more get_cpuinfo fixes...
  15.  * 02/01/00 R.Seth fixed get_cpuinfo for SMP
  16.  * 01/07/99 S.Eranian added the support for command line argument
  17.  * 06/24/99 W.Drummond added boot_cpu_data.
  18.  */
  19. #include <linux/config.h>
  20. #include <linux/init.h>
  21. #include <linux/acpi.h>
  22. #include <linux/bootmem.h>
  23. #include <linux/delay.h>
  24. #include <linux/kernel.h>
  25. #include <linux/reboot.h>
  26. #include <linux/sched.h>
  27. #include <linux/seq_file.h>
  28. #include <linux/string.h>
  29. #include <linux/threads.h>
  30. #include <linux/console.h>
  31. #include <linux/ioport.h>
  32. #include <linux/efi.h>
  33. #include <asm/ia32.h>
  34. #include <asm/page.h>
  35. #include <asm/machvec.h>
  36. #include <asm/processor.h>
  37. #include <asm/sal.h>
  38. #include <asm/system.h>
  39. #include <asm/mca.h>
  40. #include <asm/smp.h>
  41. #ifdef CONFIG_BLK_DEV_RAM
  42. # include <linux/blk.h>
  43. #endif
  44. #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
  45. # error "struct cpuinfo_ia64 too big!"
  46. #endif
  47. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  48. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  49. extern char _end;
  50. #ifdef CONFIG_NUMA
  51.  struct cpuinfo_ia64 *boot_cpu_data;
  52. #else
  53.  struct cpuinfo_ia64 _cpu_data[NR_CPUS] __attribute__ ((section ("__special_page_section")));
  54. #endif
  55. unsigned long ia64_cycles_per_usec;
  56. struct ia64_boot_param *ia64_boot_param;
  57. struct screen_info screen_info;
  58. unsigned long ia64_iobase; /* virtual address for I/O accesses */
  59. unsigned char aux_device_present = 0xaa;        /* XXX remove this when legacy I/O is gone */
  60. #define COMMAND_LINE_SIZE 512
  61. char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */
  62. /*
  63.  * Entries defined so far:
  64.  *  - boot param structure itself
  65.  *  - memory map
  66.  *  - initrd (optional)
  67.  *  - command line string
  68.  *  - kernel code & data
  69.  *
  70.  * More could be added if necessary
  71.  */
  72. #define IA64_MAX_RSVD_REGIONS 5
  73. struct rsvd_region {
  74. unsigned long start; /* virtual address of beginning of element */
  75. unsigned long end; /* virtual address of end of element + 1 */
  76. };
  77. /*
  78.  * We use a special marker for the end of memory and it uses the extra (+1) slot
  79.  */
  80. static struct rsvd_region rsvd_region[IA64_MAX_RSVD_REGIONS + 1];
  81. static int num_rsvd_regions;
  82. static unsigned long bootmap_start; /* physical address where the bootmem map is located */
  83. static int
  84. find_max_pfn (unsigned long start, unsigned long end, void *arg)
  85. {
  86. unsigned long *max_pfn = arg, pfn;
  87. pfn = (PAGE_ALIGN(end - 1) - PAGE_OFFSET) >> PAGE_SHIFT;
  88. if (pfn > *max_pfn)
  89. *max_pfn = pfn;
  90. return 0;
  91. }
  92. #define IGNORE_PFN0 1 /* XXX fix me: ignore pfn 0 until TLB miss handler is updated... */
  93. /*
  94.  * Free available memory based on the primitive map created from
  95.  * the boot parameters. This routine does not assume the incoming
  96.  * segments are sorted.
  97.  */
  98. static int
  99. free_available_memory (unsigned long start, unsigned long end, void *arg)
  100. {
  101. unsigned long range_start, range_end, prev_start;
  102. int i;
  103. #if IGNORE_PFN0
  104. if (start == PAGE_OFFSET) {
  105. printk("warning: skipping physical page 0n");
  106. start += PAGE_SIZE;
  107. if (start >= end) return 0;
  108. }
  109. #endif
  110. /*
  111.  * lowest possible address(walker uses virtual)
  112.  */
  113. prev_start = PAGE_OFFSET;
  114. for (i = 0; i < num_rsvd_regions; ++i) {
  115. range_start = MAX(start, prev_start);
  116. range_end   = MIN(end, rsvd_region[i].start);
  117. if (range_start < range_end)
  118. free_bootmem(__pa(range_start), range_end - range_start);
  119. /* nothing more available in this segment */
  120. if (range_end == end) return 0;
  121. prev_start = rsvd_region[i].end;
  122. }
  123. /* end of memory marker allows full processing inside loop body */
  124. return 0;
  125. }
  126. /*
  127.  * Find a place to put the bootmap and return its starting address in bootmap_start.
  128.  * This address must be page-aligned.
  129.  */
  130. static int
  131. find_bootmap_location (unsigned long start, unsigned long end, void *arg)
  132. {
  133. unsigned long needed = *(unsigned long *)arg;
  134. unsigned long range_start, range_end, free_start;
  135. int i;
  136. #if IGNORE_PFN0
  137. if (start == PAGE_OFFSET) {
  138. start += PAGE_SIZE;
  139. if (start >= end) return 0;
  140. }
  141. #endif
  142. free_start = PAGE_OFFSET;
  143. for (i = 0; i < num_rsvd_regions; i++) {
  144. range_start = MAX(start, free_start);
  145. range_end   = MIN(end, rsvd_region[i].start & PAGE_MASK);
  146. if (range_end <= range_start) continue; /* skip over empty range */
  147.         if (range_end - range_start >= needed) {
  148. bootmap_start = __pa(range_start);
  149. return 1; /* done */
  150. }
  151. /* nothing more available in this segment */
  152. if (range_end == end) return 0;
  153. free_start = PAGE_ALIGN(rsvd_region[i].end);
  154. }
  155. return 0;
  156. }
  157. static void
  158. sort_regions (struct rsvd_region *rsvd_region, int max)
  159. {
  160. int j;
  161. /* simple bubble sorting */
  162. while (max--) {
  163. for (j = 0; j < max; ++j) {
  164. if (rsvd_region[j].start > rsvd_region[j+1].start) {
  165. struct rsvd_region tmp;
  166. tmp = rsvd_region[j];
  167. rsvd_region[j] = rsvd_region[j + 1];
  168. rsvd_region[j + 1] = tmp;
  169. }
  170. }
  171. }
  172. }
  173. static void
  174. find_memory (void)
  175. {
  176. # define KERNEL_END ((unsigned long) &_end)
  177. unsigned long bootmap_size;
  178. unsigned long max_pfn;
  179. int n = 0;
  180. /*
  181.  * none of the entries in this table overlap
  182.  */
  183. rsvd_region[n].start = (unsigned long) ia64_boot_param;
  184. rsvd_region[n].end   = rsvd_region[n].start + sizeof(*ia64_boot_param);
  185. n++;
  186. rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->efi_memmap);
  187. rsvd_region[n].end   = rsvd_region[n].start + ia64_boot_param->efi_memmap_size;
  188. n++;
  189. rsvd_region[n].start = (unsigned long) __va(ia64_boot_param->command_line);
  190. rsvd_region[n].end   = (rsvd_region[n].start
  191. + strlen(__va(ia64_boot_param->command_line)) + 1);
  192. n++;
  193. rsvd_region[n].start = KERNEL_START;
  194. rsvd_region[n].end   = KERNEL_END;
  195. n++;
  196. #ifdef CONFIG_BLK_DEV_INITRD
  197. if (ia64_boot_param->initrd_start) {
  198. rsvd_region[n].start = (unsigned long)__va(ia64_boot_param->initrd_start);
  199. rsvd_region[n].end   = rsvd_region[n].start + ia64_boot_param->initrd_size;
  200. n++;
  201. }
  202. #endif
  203. /* end of memory marker */
  204. rsvd_region[n].start = ~0UL;
  205. rsvd_region[n].end   = ~0UL;
  206. n++;
  207. num_rsvd_regions = n;
  208. sort_regions(rsvd_region, num_rsvd_regions);
  209. /* first find highest page frame number */
  210. max_pfn = 0;
  211. efi_memmap_walk(find_max_pfn, &max_pfn);
  212. /* how many bytes to cover all the pages */
  213. bootmap_size = bootmem_bootmap_pages(max_pfn) << PAGE_SHIFT;
  214. /* look for a location to hold the bootmap */
  215. bootmap_start = ~0UL;
  216. efi_memmap_walk(find_bootmap_location, &bootmap_size);
  217. if (bootmap_start == ~0UL)
  218. panic("Cannot find %ld bytes for bootmapn", bootmap_size);
  219. bootmap_size = init_bootmem(bootmap_start >> PAGE_SHIFT, max_pfn);
  220. /* Free all available memory, then mark bootmem-map as being in use.  */
  221. efi_memmap_walk(free_available_memory, 0);
  222. reserve_bootmem(bootmap_start, bootmap_size);
  223. #ifdef CONFIG_BLK_DEV_INITRD
  224. if (ia64_boot_param->initrd_start) {
  225. initrd_start = (unsigned long)__va(ia64_boot_param->initrd_start);
  226. initrd_end   = initrd_start+ia64_boot_param->initrd_size;
  227. printk("Initial ramdisk at: 0x%lx (%lu bytes)n",
  228.        initrd_start, ia64_boot_param->initrd_size);
  229. }
  230. #endif
  231. }
  232. void __init
  233. setup_arch (char **cmdline_p)
  234. {
  235. extern unsigned long ia64_iobase;
  236. unsigned long phys_iobase;
  237. unw_init();
  238. *cmdline_p = __va(ia64_boot_param->command_line);
  239. strncpy(saved_command_line, *cmdline_p, sizeof(saved_command_line));
  240. saved_command_line[COMMAND_LINE_SIZE-1] = ''; /* for safety */
  241. efi_init();
  242. iomem_resource.end = ~0UL; /* FIXME probably belongs elsewhere */
  243. find_memory();
  244. #if 0
  245. /* XXX fix me */
  246. init_mm.start_code = (unsigned long) &_stext;
  247. init_mm.end_code = (unsigned long) &_etext;
  248. init_mm.end_data = (unsigned long) &_edata;
  249. init_mm.brk = (unsigned long) &_end;
  250. code_resource.start = virt_to_bus(&_text);
  251. code_resource.end = virt_to_bus(&_etext) - 1;
  252. data_resource.start = virt_to_bus(&_etext);
  253. data_resource.end = virt_to_bus(&_edata) - 1;
  254. #endif
  255. /* process SAL system table: */
  256. ia64_sal_init(efi.sal_systab);
  257. #ifdef CONFIG_IA64_GENERIC
  258. machvec_init(acpi_get_sysname());
  259. #endif
  260. /*
  261.  *  Set `iobase' to the appropriate address in region 6 (uncached access range).
  262.  *
  263.  *  The EFI memory map is the "preferred" location to get the I/O port space base,
  264.  *  rather the relying on AR.KR0. This should become more clear in future SAL
  265.  *  specs. We'll fall back to getting it out of AR.KR0 if no appropriate entry is
  266.  *  found in the memory map.
  267.  */
  268. phys_iobase = efi_get_iobase();
  269. if (phys_iobase)
  270. /* set AR.KR0 since this is all we use it for anyway */
  271. ia64_set_kr(IA64_KR_IO_BASE, phys_iobase);
  272. else {
  273. phys_iobase = ia64_get_kr(IA64_KR_IO_BASE);
  274. printk("No I/O port range found in EFI memory map, falling back to AR.KR0n");
  275. printk("I/O port base = 0x%lxn", phys_iobase);
  276. }
  277. ia64_iobase = (unsigned long) ioremap(phys_iobase, 0);
  278. #ifdef CONFIG_SMP
  279. cpu_physical_id(0) = hard_smp_processor_id();
  280. #endif
  281. cpu_init(); /* initialize the bootstrap CPU */
  282. #ifdef CONFIG_ACPI_BOOT
  283. acpi_boot_init(*cmdline_p);
  284. #endif
  285. #ifdef CONFIG_SERIAL_HCDP
  286. if (efi.hcdp) {
  287. void setup_serial_hcdp(void *);
  288. /* Setup the serial ports described by HCDP */
  289. setup_serial_hcdp(efi.hcdp);
  290. }
  291. #endif
  292. #ifdef CONFIG_VT
  293. # if defined(CONFIG_DUMMY_CONSOLE)
  294. conswitchp = &dummy_con;
  295. # endif
  296. # if defined(CONFIG_VGA_CONSOLE)
  297. /*
  298.  * Non-legacy systems may route legacy VGA MMIO range to system
  299.  * memory.  vga_con probes the MMIO hole, so memory looks like
  300.  * a VGA device to it.  The EFI memory map can tell us if it's
  301.  * memory so we can avoid this problem.
  302.  */
  303. if (efi_mem_type(0xA0000) != EFI_CONVENTIONAL_MEMORY)
  304. conswitchp = &vga_con;
  305. # endif
  306. #endif
  307. #ifdef CONFIG_IA64_MCA
  308. /* enable IA-64 Machine Check Abort Handling */
  309. ia64_mca_init();
  310. #endif
  311. platform_setup(cmdline_p);
  312. paging_init();
  313. unw_create_gate_table();
  314. }
  315. /*
  316.  * Display cpu info for all cpu's.
  317.  */
  318. static int
  319. show_cpuinfo (struct seq_file *m, void *v)
  320. {
  321. #ifdef CONFIG_SMP
  322. # define lpj c->loops_per_jiffy
  323. # define cpu c->processor
  324. #else
  325. # define lpj loops_per_jiffy
  326. # define cpu 0
  327. #endif
  328. char family[32], features[128], *cp;
  329. struct cpuinfo_ia64 *c = v;
  330. unsigned long mask;
  331. mask = c->features;
  332. switch (c->family) {
  333.       case 0x07: memcpy(family, "Itanium", 8); break;
  334.       case 0x1f: memcpy(family, "Itanium 2", 10); break;
  335.       default: sprintf(family, "%u", c->family); break;
  336. }
  337. /* build the feature string: */
  338. memcpy(features, " standard", 10);
  339. cp = features;
  340. if (mask & 1) {
  341. strcpy(cp, " branchlong");
  342. cp = strchr(cp, '');
  343. mask &= ~1UL;
  344. }
  345. if (mask)
  346. sprintf(cp, " 0x%lx", mask);
  347. seq_printf(m,
  348.    "processor  : %dn"
  349.    "vendor     : %sn"
  350.    "arch       : IA-64n"
  351.    "family     : %sn"
  352.    "model      : %un"
  353.    "revision   : %un"
  354.    "archrev    : %un"
  355.    "features   :%sn" /* don't change this---it _is_ right! */
  356.    "cpu number : %lun"
  357.    "cpu regs   : %un"
  358.    "cpu MHz    : %lu.%06lun"
  359.    "itc MHz    : %lu.%06lun"
  360.    "BogoMIPS   : %lu.%02lunn",
  361.    cpu, c->vendor, family, c->model, c->revision, c->archrev,
  362.    features, c->ppn, c->number,
  363.    c->proc_freq / 1000000, c->proc_freq % 1000000,
  364.    c->itc_freq / 1000000, c->itc_freq % 1000000,
  365.    lpj*HZ/500000, (lpj*HZ/5000) % 100);
  366. return 0;
  367. }
  368. static void *
  369. c_start (struct seq_file *m, loff_t *pos)
  370. {
  371. #ifdef CONFIG_SMP
  372. while (*pos < NR_CPUS && !(cpu_online_map & (1UL << *pos)))
  373. ++*pos;
  374. #endif
  375. return *pos < NR_CPUS ? cpu_data(*pos) : NULL;
  376. }
  377. static void *
  378. c_next (struct seq_file *m, void *v, loff_t *pos)
  379. {
  380. ++*pos;
  381. return c_start(m, pos);
  382. }
  383. static void
  384. c_stop (struct seq_file *m, void *v)
  385. {
  386. }
  387. struct seq_operations cpuinfo_op = {
  388. start: c_start,
  389. next: c_next,
  390. stop: c_stop,
  391. show: show_cpuinfo
  392. };
  393. void
  394. identify_cpu (struct cpuinfo_ia64 *c)
  395. {
  396. union {
  397. unsigned long bits[5];
  398. struct {
  399. /* id 0 & 1: */
  400. char vendor[16];
  401. /* id 2 */
  402. u64 ppn; /* processor serial number */
  403. /* id 3: */
  404. unsigned number :  8;
  405. unsigned revision :  8;
  406. unsigned model :  8;
  407. unsigned family :  8;
  408. unsigned archrev :  8;
  409. unsigned reserved : 24;
  410. /* id 4: */
  411. u64 features;
  412. } field;
  413. } cpuid;
  414. pal_vm_info_1_u_t vm1;
  415. pal_vm_info_2_u_t vm2;
  416. pal_status_t status;
  417. unsigned long impl_va_msb = 50, phys_addr_size = 44; /* Itanium defaults */
  418. int i;
  419. for (i = 0; i < 5; ++i)
  420. cpuid.bits[i] = ia64_get_cpuid(i);
  421. memcpy(c->vendor, cpuid.field.vendor, 16);
  422. #ifdef CONFIG_SMP
  423. c->processor = smp_processor_id();
  424. #endif
  425. c->ppn = cpuid.field.ppn;
  426. c->number = cpuid.field.number;
  427. c->revision = cpuid.field.revision;
  428. c->model = cpuid.field.model;
  429. c->family = cpuid.field.family;
  430. c->archrev = cpuid.field.archrev;
  431. c->features = cpuid.field.features;
  432. status = ia64_pal_vm_summary(&vm1, &vm2);
  433. if (status == PAL_STATUS_SUCCESS) {
  434. impl_va_msb = vm2.pal_vm_info_2_s.impl_va_msb;
  435. phys_addr_size = vm1.pal_vm_info_1_s.phys_add_size;
  436. }
  437. printk("CPU %d: %lu virtual and %lu physical address bitsn",
  438.        smp_processor_id(), impl_va_msb + 1, phys_addr_size);
  439. c->unimpl_va_mask = ~((7L<<61) | ((1L << (impl_va_msb + 1)) - 1));
  440. c->unimpl_pa_mask = ~((1L<<63) | ((1L << phys_addr_size) - 1));
  441. }
  442. /*
  443.  * cpu_init() initializes state that is per-CPU.  This function acts
  444.  * as a 'CPU state barrier', nothing should get across.
  445.  */
  446. void
  447. cpu_init (void)
  448. {
  449. extern void __init ia64_mmu_init (void *);
  450. unsigned long num_phys_stacked;
  451. pal_vm_info_2_u_t vmi;
  452. unsigned int max_ctx;
  453. struct cpuinfo_ia64 *my_cpu_data;
  454. #ifdef CONFIG_NUMA
  455. int cpu, order;
  456. /*
  457.  * If NUMA is configured, the cpu_data array is not preallocated. The boot cpu
  458.  * allocates entries for every possible cpu. As the remaining cpus come online,
  459.  * they reallocate a new cpu_data structure on their local node. This extra work
  460.  * is required because some boot code references all cpu_data structures
  461.  * before the cpus are actually started.
  462.  */
  463. if (!boot_cpu_data) {
  464. my_cpu_data = alloc_bootmem_pages_node(NODE_DATA(numa_node_id()),
  465.        sizeof(struct cpuinfo_ia64));
  466. boot_cpu_data = my_cpu_data;
  467. my_cpu_data->cpu_data[0] = my_cpu_data;
  468. for (cpu = 1; cpu < NR_CPUS; ++cpu)
  469. my_cpu_data->cpu_data[cpu]
  470. = alloc_bootmem_pages_node(NODE_DATA(numa_node_id()),
  471.    sizeof(struct cpuinfo_ia64));
  472. for (cpu = 1; cpu < NR_CPUS; ++cpu)
  473. memcpy(my_cpu_data->cpu_data[cpu]->cpu_data,
  474.        my_cpu_data->cpu_data, sizeof(my_cpu_data->cpu_data));
  475. } else {
  476. order = get_order(sizeof(struct cpuinfo_ia64));
  477. my_cpu_data = page_address(alloc_pages_node(numa_node_id(), GFP_KERNEL, order));
  478. memcpy(my_cpu_data, boot_cpu_data->cpu_data[smp_processor_id()],
  479.        sizeof(struct cpuinfo_ia64));
  480. __free_pages(virt_to_page(boot_cpu_data->cpu_data[smp_processor_id()]),
  481.      order);
  482. for (cpu = 0; cpu < NR_CPUS; ++cpu)
  483. boot_cpu_data->cpu_data[cpu]->cpu_data[smp_processor_id()] = my_cpu_data;
  484. }
  485. #else
  486. my_cpu_data = cpu_data(smp_processor_id());
  487. #endif
  488. /*
  489.  * We can't pass "local_cpu_data" to identify_cpu() because we haven't called
  490.  * ia64_mmu_init() yet.  And we can't call ia64_mmu_init() first because it
  491.  * depends on the data returned by identify_cpu().  We break the dependency by
  492.  * accessing cpu_data() the old way, through identity mapped space.
  493.  */
  494. identify_cpu(my_cpu_data);
  495. #ifdef CONFIG_MCKINLEY
  496. {
  497. #define FEATURE_SET 16
  498. struct ia64_pal_retval iprv;
  499. if (my_cpu_data->family == 0x1f) {
  500. PAL_CALL_PHYS(iprv, PAL_PROC_GET_FEATURES, 0, FEATURE_SET, 0);
  501. if ((iprv.status == 0) && (iprv.v0 & 0x80) && (iprv.v2 & 0x80)) {
  502. PAL_CALL_PHYS(iprv, PAL_PROC_SET_FEATURES,
  503.               (iprv.v1 | 0x80), FEATURE_SET, 0);
  504. }
  505. }
  506. }
  507. #endif
  508. /* Clear the stack memory reserved for pt_regs: */
  509. memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
  510. /*
  511.  * Initialize default control register to defer all speculative faults.  The
  512.  * kernel MUST NOT depend on a particular setting of these bits (in other words,
  513.  * the kernel must have recovery code for all speculative accesses).  Turn on
  514.  * dcr.lc as per recommendation by the architecture team.  Most IA-32 apps
  515.  * shouldn't be affected by this (moral: keep your ia32 locks aligned and you'll
  516.  * be fine).
  517.  */
  518. ia64_set_dcr(  IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
  519.      | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC);
  520. #ifndef CONFIG_SMP
  521. ia64_set_fpu_owner(0);
  522. #endif
  523. atomic_inc(&init_mm.mm_count);
  524. current->active_mm = &init_mm;
  525. ia64_mmu_init(my_cpu_data);
  526. #ifdef CONFIG_IA32_SUPPORT
  527. /* initialize global ia32 state - CR0 and CR4 */
  528. asm volatile ("mov ar.cflg = %0" :: "r" (((ulong) IA32_CR4 << 32) | IA32_CR0));
  529. #endif
  530. /* disable all local interrupt sources: */
  531. ia64_set_itv(1 << 16);
  532. ia64_set_lrr0(1 << 16);
  533. ia64_set_lrr1(1 << 16);
  534. ia64_set_pmv(1 << 16);
  535. ia64_set_cmcv(1 << 16);
  536. /* clear TPR & XTP to enable all interrupt classes: */
  537. ia64_set_tpr(0);
  538. #ifdef CONFIG_SMP
  539. normal_xtp();
  540. #endif
  541. /* set ia64_ctx.max_rid to the maximum RID that is supported by all CPUs: */
  542. if (ia64_pal_vm_summary(NULL, &vmi) == 0)
  543. max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
  544. else {
  545. printk("cpu_init: PAL VM summary failed, assuming 18 RID bitsn");
  546. max_ctx = (1U << 15) - 1; /* use architected minimum */
  547. }
  548. while (max_ctx < ia64_ctx.max_ctx) {
  549. unsigned int old = ia64_ctx.max_ctx;
  550. if (cmpxchg(&ia64_ctx.max_ctx, old, max_ctx) == old)
  551. break;
  552. }
  553. if (ia64_pal_rse_info(&num_phys_stacked, 0) != 0) {
  554. printk ("cpu_init: PAL RSE info failed, assuming 96 physical stacked regsn");
  555. num_phys_stacked = 96;
  556. }
  557. local_cpu_data->phys_stacked_size_p8 = num_phys_stacked*8 + 8;
  558. platform_cpu_init();
  559. }