diff options
Diffstat (limited to 'arch/i386/kernel/setup.c')
| -rw-r--r-- | arch/i386/kernel/setup.c | 140 |
1 files changed, 27 insertions, 113 deletions
diff --git a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c index ab62a9f4701e..d313a11acafa 100644 --- a/arch/i386/kernel/setup.c +++ b/arch/i386/kernel/setup.c | |||
| @@ -1288,7 +1288,7 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
| 1288 | struct resource *res; | 1288 | struct resource *res; |
| 1289 | if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) | 1289 | if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) |
| 1290 | continue; | 1290 | continue; |
| 1291 | res = alloc_bootmem_low(sizeof(struct resource)); | 1291 | res = kzalloc(sizeof(struct resource), GFP_ATOMIC); |
| 1292 | switch (e820.map[i].type) { | 1292 | switch (e820.map[i].type) { |
| 1293 | case E820_RAM: res->name = "System RAM"; break; | 1293 | case E820_RAM: res->name = "System RAM"; break; |
| 1294 | case E820_ACPI: res->name = "ACPI Tables"; break; | 1294 | case E820_ACPI: res->name = "ACPI Tables"; break; |
| @@ -1316,13 +1316,15 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat | |||
| 1316 | 1316 | ||
| 1317 | /* | 1317 | /* |
| 1318 | * Request address space for all standard resources | 1318 | * Request address space for all standard resources |
| 1319 | * | ||
| 1320 | * This is called just before pcibios_assign_resources(), which is also | ||
| 1321 | * an fs_initcall, but is linked in later (in arch/i386/pci/i386.c). | ||
| 1319 | */ | 1322 | */ |
| 1320 | static void __init register_memory(void) | 1323 | static int __init request_standard_resources(void) |
| 1321 | { | 1324 | { |
| 1322 | unsigned long gapstart, gapsize, round; | 1325 | int i; |
| 1323 | unsigned long long last; | ||
| 1324 | int i; | ||
| 1325 | 1326 | ||
| 1327 | printk("Setting up standard PCI resources\n"); | ||
| 1326 | if (efi_enabled) | 1328 | if (efi_enabled) |
| 1327 | efi_initialize_iomem_resources(&code_resource, &data_resource); | 1329 | efi_initialize_iomem_resources(&code_resource, &data_resource); |
| 1328 | else | 1330 | else |
| @@ -1334,6 +1336,16 @@ static void __init register_memory(void) | |||
| 1334 | /* request I/O space for devices used on all i[345]86 PCs */ | 1336 | /* request I/O space for devices used on all i[345]86 PCs */ |
| 1335 | for (i = 0; i < STANDARD_IO_RESOURCES; i++) | 1337 | for (i = 0; i < STANDARD_IO_RESOURCES; i++) |
| 1336 | request_resource(&ioport_resource, &standard_io_resources[i]); | 1338 | request_resource(&ioport_resource, &standard_io_resources[i]); |
| 1339 | return 0; | ||
| 1340 | } | ||
| 1341 | |||
| 1342 | fs_initcall(request_standard_resources); | ||
| 1343 | |||
| 1344 | static void __init register_memory(void) | ||
| 1345 | { | ||
| 1346 | unsigned long gapstart, gapsize, round; | ||
| 1347 | unsigned long long last; | ||
| 1348 | int i; | ||
| 1337 | 1349 | ||
| 1338 | /* | 1350 | /* |
| 1339 | * Search for the bigest gap in the low 32 bits of the e820 | 1351 | * Search for the bigest gap in the low 32 bits of the e820 |
| @@ -1377,101 +1389,6 @@ static void __init register_memory(void) | |||
| 1377 | pci_mem_start, gapstart, gapsize); | 1389 | pci_mem_start, gapstart, gapsize); |
| 1378 | } | 1390 | } |
| 1379 | 1391 | ||
| 1380 | /* Use inline assembly to define this because the nops are defined | ||
| 1381 | as inline assembly strings in the include files and we cannot | ||
| 1382 | get them easily into strings. */ | ||
| 1383 | asm("\t.data\nintelnops: " | ||
| 1384 | GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6 | ||
| 1385 | GENERIC_NOP7 GENERIC_NOP8); | ||
| 1386 | asm("\t.data\nk8nops: " | ||
| 1387 | K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6 | ||
| 1388 | K8_NOP7 K8_NOP8); | ||
| 1389 | asm("\t.data\nk7nops: " | ||
| 1390 | K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6 | ||
| 1391 | K7_NOP7 K7_NOP8); | ||
| 1392 | |||
| 1393 | extern unsigned char intelnops[], k8nops[], k7nops[]; | ||
| 1394 | static unsigned char *intel_nops[ASM_NOP_MAX+1] = { | ||
| 1395 | NULL, | ||
| 1396 | intelnops, | ||
| 1397 | intelnops + 1, | ||
| 1398 | intelnops + 1 + 2, | ||
| 1399 | intelnops + 1 + 2 + 3, | ||
| 1400 | intelnops + 1 + 2 + 3 + 4, | ||
| 1401 | intelnops + 1 + 2 + 3 + 4 + 5, | ||
| 1402 | intelnops + 1 + 2 + 3 + 4 + 5 + 6, | ||
| 1403 | intelnops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
| 1404 | }; | ||
| 1405 | static unsigned char *k8_nops[ASM_NOP_MAX+1] = { | ||
| 1406 | NULL, | ||
| 1407 | k8nops, | ||
| 1408 | k8nops + 1, | ||
| 1409 | k8nops + 1 + 2, | ||
| 1410 | k8nops + 1 + 2 + 3, | ||
| 1411 | k8nops + 1 + 2 + 3 + 4, | ||
| 1412 | k8nops + 1 + 2 + 3 + 4 + 5, | ||
| 1413 | k8nops + 1 + 2 + 3 + 4 + 5 + 6, | ||
| 1414 | k8nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
| 1415 | }; | ||
| 1416 | static unsigned char *k7_nops[ASM_NOP_MAX+1] = { | ||
| 1417 | NULL, | ||
| 1418 | k7nops, | ||
| 1419 | k7nops + 1, | ||
| 1420 | k7nops + 1 + 2, | ||
| 1421 | k7nops + 1 + 2 + 3, | ||
| 1422 | k7nops + 1 + 2 + 3 + 4, | ||
| 1423 | k7nops + 1 + 2 + 3 + 4 + 5, | ||
| 1424 | k7nops + 1 + 2 + 3 + 4 + 5 + 6, | ||
| 1425 | k7nops + 1 + 2 + 3 + 4 + 5 + 6 + 7, | ||
| 1426 | }; | ||
| 1427 | static struct nop { | ||
| 1428 | int cpuid; | ||
| 1429 | unsigned char **noptable; | ||
| 1430 | } noptypes[] = { | ||
| 1431 | { X86_FEATURE_K8, k8_nops }, | ||
| 1432 | { X86_FEATURE_K7, k7_nops }, | ||
| 1433 | { -1, NULL } | ||
| 1434 | }; | ||
| 1435 | |||
| 1436 | /* Replace instructions with better alternatives for this CPU type. | ||
| 1437 | |||
| 1438 | This runs before SMP is initialized to avoid SMP problems with | ||
| 1439 | self modifying code. This implies that assymetric systems where | ||
| 1440 | APs have less capabilities than the boot processor are not handled. | ||
| 1441 | Tough. Make sure you disable such features by hand. */ | ||
| 1442 | void apply_alternatives(void *start, void *end) | ||
| 1443 | { | ||
| 1444 | struct alt_instr *a; | ||
| 1445 | int diff, i, k; | ||
| 1446 | unsigned char **noptable = intel_nops; | ||
| 1447 | for (i = 0; noptypes[i].cpuid >= 0; i++) { | ||
| 1448 | if (boot_cpu_has(noptypes[i].cpuid)) { | ||
| 1449 | noptable = noptypes[i].noptable; | ||
| 1450 | break; | ||
| 1451 | } | ||
| 1452 | } | ||
| 1453 | for (a = start; (void *)a < end; a++) { | ||
| 1454 | if (!boot_cpu_has(a->cpuid)) | ||
| 1455 | continue; | ||
| 1456 | BUG_ON(a->replacementlen > a->instrlen); | ||
| 1457 | memcpy(a->instr, a->replacement, a->replacementlen); | ||
| 1458 | diff = a->instrlen - a->replacementlen; | ||
| 1459 | /* Pad the rest with nops */ | ||
| 1460 | for (i = a->replacementlen; diff > 0; diff -= k, i += k) { | ||
| 1461 | k = diff; | ||
| 1462 | if (k > ASM_NOP_MAX) | ||
| 1463 | k = ASM_NOP_MAX; | ||
| 1464 | memcpy(a->instr + i, noptable[k], k); | ||
| 1465 | } | ||
| 1466 | } | ||
| 1467 | } | ||
| 1468 | |||
| 1469 | void __init alternative_instructions(void) | ||
| 1470 | { | ||
| 1471 | extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; | ||
| 1472 | apply_alternatives(__alt_instructions, __alt_instructions_end); | ||
| 1473 | } | ||
| 1474 | |||
| 1475 | static char * __init machine_specific_memory_setup(void); | 1392 | static char * __init machine_specific_memory_setup(void); |
| 1476 | 1393 | ||
| 1477 | #ifdef CONFIG_MCA | 1394 | #ifdef CONFIG_MCA |
| @@ -1554,6 +1471,16 @@ void __init setup_arch(char **cmdline_p) | |||
| 1554 | 1471 | ||
| 1555 | parse_cmdline_early(cmdline_p); | 1472 | parse_cmdline_early(cmdline_p); |
| 1556 | 1473 | ||
| 1474 | #ifdef CONFIG_EARLY_PRINTK | ||
| 1475 | { | ||
| 1476 | char *s = strstr(*cmdline_p, "earlyprintk="); | ||
| 1477 | if (s) { | ||
| 1478 | setup_early_printk(strchr(s, '=') + 1); | ||
| 1479 | printk("early console enabled\n"); | ||
| 1480 | } | ||
| 1481 | } | ||
| 1482 | #endif | ||
| 1483 | |||
| 1557 | max_low_pfn = setup_memory(); | 1484 | max_low_pfn = setup_memory(); |
| 1558 | 1485 | ||
| 1559 | /* | 1486 | /* |
| @@ -1578,19 +1505,6 @@ void __init setup_arch(char **cmdline_p) | |||
| 1578 | * NOTE: at this point the bootmem allocator is fully available. | 1505 | * NOTE: at this point the bootmem allocator is fully available. |
| 1579 | */ | 1506 | */ |
| 1580 | 1507 | ||
| 1581 | #ifdef CONFIG_EARLY_PRINTK | ||
| 1582 | { | ||
| 1583 | char *s = strstr(*cmdline_p, "earlyprintk="); | ||
| 1584 | if (s) { | ||
| 1585 | extern void setup_early_printk(char *); | ||
| 1586 | |||
| 1587 | setup_early_printk(strchr(s, '=') + 1); | ||
| 1588 | printk("early console enabled\n"); | ||
| 1589 | } | ||
| 1590 | } | ||
| 1591 | #endif | ||
| 1592 | |||
| 1593 | |||
| 1594 | dmi_scan_machine(); | 1508 | dmi_scan_machine(); |
| 1595 | 1509 | ||
| 1596 | #ifdef CONFIG_X86_GENERICARCH | 1510 | #ifdef CONFIG_X86_GENERICARCH |
