File: /usr/src/linux/arch/ia64/kernel/setup.c

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