2 * linux/arch/i386/kernel/setup.c
4 * Copyright (C) 1995 Linus Torvalds
6 * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
8 * Memory region support
9 * David Parsons <orc@pell.chi.il.us>, July-August 1999
11 * Added E820 sanitization routine (removes overlapping memory regions);
12 * Brian Moyle <bmoyle@mvista.com>, February 2001
14 * Moved CPU detection code to cpu/${cpu}.c
15 * Patrick Mochel <mochel@osdl.org>, March 2002
17 * Provisions for empty E820 memory regions (reported by certain BIOSes).
18 * Alex Achenbach <xela@slit.de>, December 2002.
23 * This file handles the architecture-dependent parts of initialization
26 #include <linux/sched.h>
28 #include <linux/tty.h>
29 #include <linux/ioport.h>
30 #include <linux/acpi.h>
31 #include <linux/apm_bios.h>
32 #include <linux/initrd.h>
33 #include <linux/bootmem.h>
34 #include <linux/seq_file.h>
35 #include <linux/console.h>
36 #include <linux/root_dev.h>
37 #include <linux/highmem.h>
38 #include <linux/module.h>
39 #include <video/edid.h>
41 #include <asm/mpspec.h>
43 #include <asm/setup.h>
44 #include <asm/arch_hooks.h>
45 #include <asm/sections.h>
46 #include <asm/io_apic.h>
48 #include "setup_arch_pre.h"
49 #include "mach_resources.h"
51 int disable_pse __initdata = 0;
53 static inline char * __init machine_specific_memory_setup(void);
59 /* cpu data as detected by the assembly code in head.S */
60 struct cpuinfo_x86 new_cpu_data __initdata = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
61 /* common cpu data for all cpus */
62 struct cpuinfo_x86 boot_cpu_data = { 0, 0, 0, 0, -1, 1, 0, 0, -1 };
64 unsigned long mmu_cr4_features;
65 EXPORT_SYMBOL_GPL(mmu_cr4_features);
67 #ifdef CONFIG_ACPI_INTERPRETER
68 int acpi_disabled = 0;
70 int acpi_disabled = 1;
72 EXPORT_SYMBOL(acpi_disabled);
74 #ifdef CONFIG_ACPI_BOOT
75 int acpi_irq __initdata = 1; /* enable IRQ */
76 int acpi_ht __initdata = 1; /* enable HT */
79 int acpi_force __initdata = 0;
83 /* for MCA, but anyone else can use it if they want */
84 unsigned int machine_id;
85 unsigned int machine_submodel_id;
86 unsigned int BIOS_revision;
87 unsigned int mca_pentium_flag;
89 /* For PCI or other memory-mapped resources */
90 unsigned long pci_mem_start = 0x10000000;
92 /* user-defined highmem size */
93 static unsigned int highmem_pages = -1;
98 struct drive_info_struct { char dummy[32]; } drive_info;
99 struct screen_info screen_info;
100 struct apm_info apm_info;
101 struct sys_desc_table_struct {
102 unsigned short length;
103 unsigned char table[0];
105 struct edid_info edid_info;
106 struct ist_info ist_info;
109 unsigned char aux_device_present;
111 extern void early_cpu_init(void);
112 extern void dmi_scan_machine(void);
113 extern void generic_apic_probe(char *);
114 extern int root_mountflags;
117 unsigned long saved_videomode;
119 #define RAMDISK_IMAGE_START_MASK 0x07FF
120 #define RAMDISK_PROMPT_FLAG 0x8000
121 #define RAMDISK_LOAD_FLAG 0x4000
123 static char command_line[COMMAND_LINE_SIZE];
124 char saved_command_line[COMMAND_LINE_SIZE];
126 static struct resource code_resource = { "Kernel code", 0x100000, 0 };
127 static struct resource data_resource = { "Kernel data", 0, 0 };
129 static void __init probe_roms(void)
133 request_resource(&iomem_resource, rom_resources+0);
135 /* Video ROM is standard at C000:0000 - C7FF:0000, check signature */
136 probe_video_rom(roms);
139 probe_extension_roms(roms);
142 static void __init limit_regions(unsigned long long size)
144 unsigned long long current_addr = 0;
147 for (i = 0; i < e820.nr_map; i++) {
148 if (e820.map[i].type == E820_RAM) {
149 current_addr = e820.map[i].addr + e820.map[i].size;
150 if (current_addr >= size) {
151 e820.map[i].size -= current_addr-size;
159 static void __init add_memory_region(unsigned long long start,
160 unsigned long long size, int type)
165 printk(KERN_ERR "Ooops! Too many entries in the memory map!\n");
169 e820.map[x].addr = start;
170 e820.map[x].size = size;
171 e820.map[x].type = type;
173 } /* add_memory_region */
177 static void __init print_memory_map(char *who)
181 for (i = 0; i < e820.nr_map; i++) {
182 printk(" %s: %016Lx - %016Lx ", who,
184 e820.map[i].addr + e820.map[i].size);
185 switch (e820.map[i].type) {
186 case E820_RAM: printk("(usable)\n");
189 printk("(reserved)\n");
192 printk("(ACPI data)\n");
195 printk("(ACPI NVS)\n");
197 default: printk("type %lu\n", e820.map[i].type);
204 * Sanitize the BIOS e820 map.
206 * Some e820 responses include overlapping entries. The following
207 * replaces the original e820 map with a new one, removing overlaps.
210 struct change_member {
211 struct e820entry *pbios; /* pointer to original bios entry */
212 unsigned long long addr; /* address for this change point */
214 struct change_member change_point_list[2*E820MAX] __initdata;
215 struct change_member *change_point[2*E820MAX] __initdata;
216 struct e820entry *overlap_list[E820MAX] __initdata;
217 struct e820entry new_bios[E820MAX] __initdata;
219 static int __init sanitize_e820_map(struct e820entry * biosmap, char * pnr_map)
221 struct change_member *change_tmp;
222 unsigned long current_type, last_type;
223 unsigned long long last_addr;
224 int chgidx, still_changing;
227 int old_nr, new_nr, chg_nr;
231 Visually we're performing the following (1,2,3,4 = memory types)...
233 Sample memory map (w/overlaps):
234 ____22__________________
235 ______________________4_
236 ____1111________________
237 _44_____________________
238 11111111________________
239 ____________________33__
240 ___________44___________
241 __________33333_________
242 ______________22________
243 ___________________2222_
244 _________111111111______
245 _____________________11_
246 _________________4______
248 Sanitized equivalent (no overlap):
249 1_______________________
250 _44_____________________
251 ___1____________________
252 ____22__________________
253 ______11________________
254 _________1______________
255 __________3_____________
256 ___________44___________
257 _____________33_________
258 _______________2________
259 ________________1_______
260 _________________4______
261 ___________________2____
262 ____________________33__
263 ______________________4_
266 /* if there's only one memory region, don't bother */
272 /* bail out if we find any unreasonable addresses in bios map */
273 for (i=0; i<old_nr; i++)
274 if (biosmap[i].addr + biosmap[i].size < biosmap[i].addr)
277 /* create pointers for initial change-point information (for sorting) */
278 for (i=0; i < 2*old_nr; i++)
279 change_point[i] = &change_point_list[i];
281 /* record all known change-points (starting and ending addresses),
282 omitting those that are for empty memory regions */
284 for (i=0; i < old_nr; i++) {
285 if (biosmap[i].size != 0) {
286 change_point[chgidx]->addr = biosmap[i].addr;
287 change_point[chgidx++]->pbios = &biosmap[i];
288 change_point[chgidx]->addr = biosmap[i].addr + biosmap[i].size;
289 change_point[chgidx++]->pbios = &biosmap[i];
292 chg_nr = chgidx; /* true number of change-points */
294 /* sort change-point list by memory addresses (low -> high) */
296 while (still_changing) {
298 for (i=1; i < chg_nr; i++) {
299 /* if <current_addr> > <last_addr>, swap */
300 /* or, if current=<start_addr> & last=<end_addr>, swap */
301 if ((change_point[i]->addr < change_point[i-1]->addr) ||
302 ((change_point[i]->addr == change_point[i-1]->addr) &&
303 (change_point[i]->addr == change_point[i]->pbios->addr) &&
304 (change_point[i-1]->addr != change_point[i-1]->pbios->addr))
307 change_tmp = change_point[i];
308 change_point[i] = change_point[i-1];
309 change_point[i-1] = change_tmp;
315 /* create a new bios memory map, removing overlaps */
316 overlap_entries=0; /* number of entries in the overlap table */
317 new_bios_entry=0; /* index for creating new bios map entries */
318 last_type = 0; /* start with undefined memory type */
319 last_addr = 0; /* start with 0 as last starting address */
320 /* loop through change-points, determining affect on the new bios map */
321 for (chgidx=0; chgidx < chg_nr; chgidx++)
323 /* keep track of all overlapping bios entries */
324 if (change_point[chgidx]->addr == change_point[chgidx]->pbios->addr)
326 /* add map entry to overlap list (> 1 entry implies an overlap) */
327 overlap_list[overlap_entries++]=change_point[chgidx]->pbios;
331 /* remove entry from list (order independent, so swap with last) */
332 for (i=0; i<overlap_entries; i++)
334 if (overlap_list[i] == change_point[chgidx]->pbios)
335 overlap_list[i] = overlap_list[overlap_entries-1];
339 /* if there are overlapping entries, decide which "type" to use */
340 /* (larger value takes precedence -- 1=usable, 2,3,4,4+=unusable) */
342 for (i=0; i<overlap_entries; i++)
343 if (overlap_list[i]->type > current_type)
344 current_type = overlap_list[i]->type;
345 /* continue building up new bios map based on this information */
346 if (current_type != last_type) {
347 if (last_type != 0) {
348 new_bios[new_bios_entry].size =
349 change_point[chgidx]->addr - last_addr;
350 /* move forward only if the new size was non-zero */
351 if (new_bios[new_bios_entry].size != 0)
352 if (++new_bios_entry >= E820MAX)
353 break; /* no more space left for new bios entries */
355 if (current_type != 0) {
356 new_bios[new_bios_entry].addr = change_point[chgidx]->addr;
357 new_bios[new_bios_entry].type = current_type;
358 last_addr=change_point[chgidx]->addr;
360 last_type = current_type;
363 new_nr = new_bios_entry; /* retain count for new bios entries */
365 /* copy new bios mapping into original location */
366 memcpy(biosmap, new_bios, new_nr*sizeof(struct e820entry));
373 * Copy the BIOS e820 map into a safe place.
375 * Sanity-check it while we're at it..
377 * If we're lucky and live on a modern system, the setup code
378 * will have given us a memory map that we can use to properly
379 * set up memory. If we aren't, we'll fake a memory map.
381 * We check to see that the memory map contains at least 2 elements
382 * before we'll use it, because the detection code in setup.S may
383 * not be perfect and most every PC known to man has two memory
384 * regions: one from 0 to 640k, and one from 1mb up. (The IBM
385 * thinkpad 560x, for example, does not cooperate with the memory
388 static int __init copy_e820_map(struct e820entry * biosmap, int nr_map)
390 /* Only one memory region (or negative)? Ignore it */
395 unsigned long long start = biosmap->addr;
396 unsigned long long size = biosmap->size;
397 unsigned long long end = start + size;
398 unsigned long type = biosmap->type;
400 /* Overflow in 64 bits? Ignore the memory map. */
405 * Some BIOSes claim RAM in the 640k - 1M region.
406 * Not right. Fix it up.
408 if (type == E820_RAM) {
409 if (start < 0x100000ULL && end > 0xA0000ULL) {
410 if (start < 0xA0000ULL)
411 add_memory_region(start, 0xA0000ULL-start, type);
412 if (end <= 0x100000ULL)
418 add_memory_region(start, size, type);
419 } while (biosmap++,--nr_map);
423 #if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
425 struct edd_info edd[EDDMAXNR];
427 * copy_edd() - Copy the BIOS EDD information
428 * from empty_zero_page into a safe place.
431 static inline void copy_edd(void)
434 memcpy(edd, EDD_BUF, sizeof(edd));
437 #define copy_edd() do {} while (0)
441 * Do NOT EVER look at the BIOS memory size location.
442 * It does not work on many machines.
444 #define LOWMEMSIZE() (0x9f000)
446 static void __init setup_memory_region(void)
448 char *who = machine_specific_memory_setup();
450 printk(KERN_INFO "BIOS-provided physical RAM map:\n");
451 print_memory_map(who);
452 } /* setup_memory_region */
455 static void __init parse_cmdline_early (char ** cmdline_p)
457 char c = ' ', *to = command_line, *from = COMMAND_LINE;
461 /* Save unparsed command line copy for /proc/cmdline */
462 memcpy(saved_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);
463 saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
467 * "mem=nopentium" disables the 4MB page tables.
468 * "mem=XXX[kKmM]" defines a memory region from HIGH_MEM
469 * to <mem>, overriding the bios size.
470 * "memmap=XXX[KkmM]@XXX[KkmM]" defines a memory region from
471 * <start> to <start>+<mem>, overriding the bios size.
473 * HPA tells me bootloaders need to parse mem=, so no new
474 * option should be mem= [also see Documentation/i386/boot.txt]
476 if (c == ' ' && !memcmp(from, "mem=", 4)) {
477 if (to != command_line)
479 if (!memcmp(from+4, "nopentium", 9)) {
481 clear_bit(X86_FEATURE_PSE, boot_cpu_data.x86_capability);
484 /* If the user specifies memory size, we
485 * limit the BIOS-provided memory map to
486 * that size. exactmap can be used to specify
487 * the exact map. mem=number can be used to
488 * trim the existing memory map.
490 unsigned long long mem_size;
492 mem_size = memparse(from+4, &from);
493 limit_regions(mem_size);
498 if (c == ' ' && !memcmp(from, "memmap=", 7)) {
499 if (to != command_line)
501 if (!memcmp(from+7, "exactmap", 8)) {
506 /* If the user specifies memory size, we
507 * limit the BIOS-provided memory map to
508 * that size. exactmap can be used to specify
509 * the exact map. mem=number can be used to
510 * trim the existing memory map.
512 unsigned long long start_at, mem_size;
514 mem_size = memparse(from+7, &from);
516 start_at = memparse(from+1, &from);
517 add_memory_region(start_at, mem_size, E820_RAM);
518 } else if (*from == '#') {
519 start_at = memparse(from+1, &from);
520 add_memory_region(start_at, mem_size, E820_ACPI);
521 } else if (*from == '$') {
522 start_at = memparse(from+1, &from);
523 add_memory_region(start_at, mem_size, E820_RESERVED);
525 limit_regions(mem_size);
531 #ifdef CONFIG_ACPI_BOOT
532 /* "acpi=off" disables both ACPI table parsing and interpreter */
533 else if (!memcmp(from, "acpi=off", 8)) {
538 /* acpi=force to over-ride black-list */
539 else if (!memcmp(from, "acpi=force", 10)) {
545 /* Limit ACPI just to boot-time to enable HT */
546 else if (!memcmp(from, "acpi=ht", 7)) {
548 if (!acpi_force) acpi_disabled = 1;
551 /* "pci=noacpi" disables ACPI interrupt routing */
552 else if (!memcmp(from, "pci=noacpi", 10)) {
556 #ifdef CONFIG_X86_LOCAL_APIC
557 /* disable IO-APIC */
558 else if (!memcmp(from, "noapic", 6))
559 disable_ioapic_setup();
560 #endif /* CONFIG_X86_LOCAL_APIC */
561 #endif /* CONFIG_ACPI_BOOT */
564 * highmem=size forces highmem to be exactly 'size' bytes.
565 * This works even on boxes that have no highmem otherwise.
566 * This also works to reduce highmem size on bigger boxes.
568 if (c == ' ' && !memcmp(from, "highmem=", 8))
569 highmem_pages = memparse(from+8, &from) >> PAGE_SHIFT;
574 if (COMMAND_LINE_SIZE <= ++len)
579 *cmdline_p = command_line;
581 printk(KERN_INFO "user-defined physical RAM map:\n");
582 print_memory_map("user");
587 * Find the highest page frame number we have available
589 void __init find_max_pfn(void)
594 for (i = 0; i < e820.nr_map; i++) {
595 unsigned long start, end;
597 if (e820.map[i].type != E820_RAM)
599 start = PFN_UP(e820.map[i].addr);
600 end = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
609 * Determine low and high memory ranges:
611 unsigned long __init find_max_low_pfn(void)
613 unsigned long max_low_pfn;
615 max_low_pfn = max_pfn;
616 if (max_low_pfn > MAXMEM_PFN) {
617 if (highmem_pages == -1)
618 highmem_pages = max_pfn - MAXMEM_PFN;
619 if (highmem_pages + MAXMEM_PFN < max_pfn)
620 max_pfn = MAXMEM_PFN + highmem_pages;
621 if (highmem_pages + MAXMEM_PFN > max_pfn) {
622 printk("only %luMB highmem pages available, ignoring highmem size of %uMB.\n", pages_to_mb(max_pfn - MAXMEM_PFN), pages_to_mb(highmem_pages));
625 max_low_pfn = MAXMEM_PFN;
626 #ifndef CONFIG_HIGHMEM
627 /* Maximum memory usable is what is directly addressable */
628 printk(KERN_WARNING "Warning only %ldMB will be used.\n",
630 if (max_pfn > MAX_NONPAE_PFN)
631 printk(KERN_WARNING "Use a PAE enabled kernel.\n");
633 printk(KERN_WARNING "Use a HIGHMEM enabled kernel.\n");
634 max_pfn = MAXMEM_PFN;
635 #else /* !CONFIG_HIGHMEM */
636 #ifndef CONFIG_X86_PAE
637 if (max_pfn > MAX_NONPAE_PFN) {
638 max_pfn = MAX_NONPAE_PFN;
639 printk(KERN_WARNING "Warning only 4GB will be used.\n");
640 printk(KERN_WARNING "Use a PAE enabled kernel.\n");
642 #endif /* !CONFIG_X86_PAE */
643 #endif /* !CONFIG_HIGHMEM */
645 if (highmem_pages == -1)
647 #ifdef CONFIG_HIGHMEM
648 if (highmem_pages >= max_pfn) {
649 printk(KERN_ERR "highmem size specified (%uMB) is bigger than pages available (%luMB)!.\n", pages_to_mb(highmem_pages), pages_to_mb(max_pfn));
653 if (max_low_pfn-highmem_pages < 64*1024*1024/PAGE_SIZE){
654 printk(KERN_ERR "highmem size %uMB results in smaller than 64MB lowmem, ignoring it.\n", pages_to_mb(highmem_pages));
657 max_low_pfn -= highmem_pages;
661 printk(KERN_ERR "ignoring highmem size on non-highmem kernel!\n");
667 #ifndef CONFIG_DISCONTIGMEM
669 * Register fully available low RAM pages with the bootmem allocator.
671 static void __init register_bootmem_low_pages(unsigned long max_low_pfn)
675 for (i = 0; i < e820.nr_map; i++) {
676 unsigned long curr_pfn, last_pfn, size;
678 * Reserve usable low memory
680 if (e820.map[i].type != E820_RAM)
683 * We are rounding up the start address of usable memory:
685 curr_pfn = PFN_UP(e820.map[i].addr);
686 if (curr_pfn >= max_low_pfn)
689 * ... and at the end of the usable range downwards:
691 last_pfn = PFN_DOWN(e820.map[i].addr + e820.map[i].size);
693 if (last_pfn > max_low_pfn)
694 last_pfn = max_low_pfn;
697 * .. finally, did all the rounding and playing
698 * around just make the area go away?
700 if (last_pfn <= curr_pfn)
703 size = last_pfn - curr_pfn;
704 free_bootmem(PFN_PHYS(curr_pfn), PFN_PHYS(size));
708 static unsigned long __init setup_memory(void)
710 unsigned long bootmap_size, start_pfn, max_low_pfn;
713 * partially used pages are not usable - thus
714 * we are rounding upwards:
716 start_pfn = PFN_UP(__pa(_end));
720 max_low_pfn = find_max_low_pfn();
722 #ifdef CONFIG_HIGHMEM
723 highstart_pfn = highend_pfn = max_pfn;
724 if (max_pfn > max_low_pfn) {
725 highstart_pfn = max_low_pfn;
727 printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
728 pages_to_mb(highend_pfn - highstart_pfn));
730 printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
731 pages_to_mb(max_low_pfn));
733 * Initialize the boot-time allocator (with low memory only):
735 bootmap_size = init_bootmem(start_pfn, max_low_pfn);
737 register_bootmem_low_pages(max_low_pfn);
740 * Reserve the bootmem bitmap itself as well. We do this in two
741 * steps (first step was init_bootmem()) because this catches
742 * the (very unlikely) case of us accidentally initializing the
743 * bootmem allocator with an invalid RAM area.
745 reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) +
746 bootmap_size + PAGE_SIZE-1) - (HIGH_MEMORY));
749 * reserve physical page 0 - it's a special BIOS page on many boxes,
750 * enabling clean reboots, SMP operation, laptop functions.
752 reserve_bootmem(0, PAGE_SIZE);
756 * But first pinch a few for the stack/trampoline stuff
757 * FIXME: Don't need the extra page at 4K, but need to fix
758 * trampoline before removing it. (see the GDT stuff)
760 reserve_bootmem(PAGE_SIZE, PAGE_SIZE);
762 #ifdef CONFIG_ACPI_SLEEP
764 * Reserve low memory region for sleep support.
766 acpi_reserve_bootmem();
768 #ifdef CONFIG_X86_FIND_SMP_CONFIG
770 * Find and reserve possible boot-time SMP configuration:
775 #ifdef CONFIG_BLK_DEV_INITRD
776 if (LOADER_TYPE && INITRD_START) {
777 if (INITRD_START + INITRD_SIZE <= (max_low_pfn << PAGE_SHIFT)) {
778 reserve_bootmem(INITRD_START, INITRD_SIZE);
780 INITRD_START ? INITRD_START + PAGE_OFFSET : 0;
781 initrd_end = initrd_start+INITRD_SIZE;
784 printk(KERN_ERR "initrd extends beyond end of memory "
785 "(0x%08lx > 0x%08lx)\ndisabling initrd\n",
786 INITRD_START + INITRD_SIZE,
787 max_low_pfn << PAGE_SHIFT);
795 extern unsigned long setup_memory(void);
796 #endif /* !CONFIG_DISCONTIGMEM */
799 * Request address space for all standard RAM and ROM resources
800 * and also for regions reported as reserved by the e820.
802 static void __init register_memory(unsigned long max_low_pfn)
804 unsigned long low_mem_size;
808 for (i = 0; i < e820.nr_map; i++) {
809 struct resource *res;
810 if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL)
812 res = alloc_bootmem_low(sizeof(struct resource));
813 switch (e820.map[i].type) {
814 case E820_RAM: res->name = "System RAM"; break;
815 case E820_ACPI: res->name = "ACPI Tables"; break;
816 case E820_NVS: res->name = "ACPI Non-volatile Storage"; break;
817 default: res->name = "reserved";
819 res->start = e820.map[i].addr;
820 res->end = res->start + e820.map[i].size - 1;
821 res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
822 request_resource(&iomem_resource, res);
823 if (e820.map[i].type == E820_RAM) {
825 * We don't know which RAM region contains kernel data,
826 * so we try it repeatedly and let the resource manager
829 request_resource(res, &code_resource);
830 request_resource(res, &data_resource);
834 request_graphics_resource();
836 /* request I/O space for devices used on all i[345]86 PCs */
837 for (i = 0; i < STANDARD_IO_RESOURCES; i++)
838 request_resource(&ioport_resource, standard_io_resources+i);
840 /* Tell the PCI layer not to allocate too close to the RAM area.. */
841 low_mem_size = ((max_low_pfn << PAGE_SHIFT) + 0xfffff) & ~0xfffff;
842 if (low_mem_size > pci_mem_start)
843 pci_mem_start = low_mem_size;
846 /* Use inline assembly to define this because the nops are defined
847 as inline assembly strings in the include files and we cannot
848 get them easily into strings. */
849 asm("\t.data\nintelnops: "
850 GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
851 GENERIC_NOP7 GENERIC_NOP8);
852 asm("\t.data\nk8nops: "
853 K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
855 asm("\t.data\nk7nops: "
856 K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
859 extern unsigned char intelnops[], k8nops[], k7nops[];
860 static unsigned char *intel_nops[ASM_NOP_MAX+1] = {
865 intelnops + 1 + 2 + 3,
866 intelnops + 1 + 2 + 3 + 4,
867 intelnops + 1 + 2 + 3 + 4 + 5,
868 intelnops + 1 + 2 + 3 + 4 + 5 + 6,
869 intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
871 static unsigned char *k8_nops[ASM_NOP_MAX+1] = {
877 k8nops + 1 + 2 + 3 + 4,
878 k8nops + 1 + 2 + 3 + 4 + 5,
879 k8nops + 1 + 2 + 3 + 4 + 5 + 6,
880 k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
882 static unsigned char *k7_nops[ASM_NOP_MAX+1] = {
888 k7nops + 1 + 2 + 3 + 4,
889 k7nops + 1 + 2 + 3 + 4 + 5,
890 k7nops + 1 + 2 + 3 + 4 + 5 + 6,
891 k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7,
895 unsigned char **noptable;
897 { X86_FEATURE_K8, k8_nops },
898 { X86_FEATURE_K7, k7_nops },
902 /* Replace instructions with better alternatives for this CPU type.
904 This runs before SMP is initialized to avoid SMP problems with
905 self modifying code. This implies that assymetric systems where
906 APs have less capabilities than the boot processor are not handled.
907 In this case boot with "noreplacement". */
908 void apply_alternatives(void *start, void *end)
912 unsigned char **noptable = intel_nops;
913 for (i = 0; noptypes[i].cpuid >= 0; i++) {
914 if (boot_cpu_has(noptypes[i].cpuid)) {
915 noptable = noptypes[i].noptable;
919 for (a = start; (void *)a < end; a++) {
920 if (!boot_cpu_has(a->cpuid))
922 BUG_ON(a->replacementlen > a->instrlen);
923 memcpy(a->instr, a->replacement, a->replacementlen);
924 diff = a->instrlen - a->replacementlen;
925 /* Pad the rest with nops */
926 for (i = a->replacementlen; diff > 0; diff -= k, i += k) {
930 memcpy(a->instr + i, noptable[k], k);
935 static int no_replacement __initdata = 0;
937 void __init alternative_instructions(void)
939 extern struct alt_instr __alt_instructions[], __alt_instructions_end[];
942 apply_alternatives(__alt_instructions, __alt_instructions_end);
945 static int __init noreplacement_setup(char *s)
951 __setup("noreplacement", noreplacement_setup);
953 void __init setup_arch(char **cmdline_p)
955 unsigned long max_low_pfn;
957 memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data));
958 pre_setup_arch_hook();
961 ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
962 drive_info = DRIVE_INFO;
963 screen_info = SCREEN_INFO;
964 edid_info = EDID_INFO;
965 apm_info.bios = APM_BIOS_INFO;
967 saved_videomode = VIDEO_MODE;
968 if( SYS_DESC_TABLE.length != 0 ) {
969 MCA_bus = SYS_DESC_TABLE.table[3] &0x2;
970 machine_id = SYS_DESC_TABLE.table[0];
971 machine_submodel_id = SYS_DESC_TABLE.table[1];
972 BIOS_revision = SYS_DESC_TABLE.table[2];
974 aux_device_present = AUX_DEVICE_INFO;
976 #ifdef CONFIG_BLK_DEV_RAM
977 rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
978 rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
979 rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
982 setup_memory_region();
985 if (!MOUNT_ROOT_RDONLY)
986 root_mountflags &= ~MS_RDONLY;
987 init_mm.start_code = (unsigned long) _text;
988 init_mm.end_code = (unsigned long) _etext;
989 init_mm.end_data = (unsigned long) _edata;
990 init_mm.brk = (unsigned long) _end;
992 code_resource.start = virt_to_phys(_text);
993 code_resource.end = virt_to_phys(_etext)-1;
994 data_resource.start = virt_to_phys(_etext);
995 data_resource.end = virt_to_phys(_edata)-1;
997 parse_cmdline_early(cmdline_p);
999 max_low_pfn = setup_memory();
1002 * NOTE: before this point _nobody_ is allowed to allocate
1003 * any memory using the bootmem allocator.
1007 smp_alloc_memory(); /* AP processor realmode stacks in low memory*/
1013 #ifdef CONFIG_X86_GENERICARCH
1014 generic_apic_probe(*cmdline_p);
1018 * Parse the ACPI tables for possible boot-time SMP configuration.
1022 #ifdef CONFIG_X86_LOCAL_APIC
1023 if (smp_found_config)
1027 register_memory(max_low_pfn);
1030 #if defined(CONFIG_VGA_CONSOLE)
1031 conswitchp = &vga_con;
1032 #elif defined(CONFIG_DUMMY_CONSOLE)
1033 conswitchp = &dummy_con;
1038 #include "setup_arch_post.h"
1042 * c-file-style:"k&r"