diff options
author | Yinghai Lu <yhlu.kernel@gmail.com> | 2008-06-16 16:03:31 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-08 04:38:14 -0400 |
commit | 41c094fd3ca54f1a71233049cf136ff94c91f4ae (patch) | |
tree | 9ce8de894276e69d30c893700a9b70fb4e176511 /arch/x86/kernel/setup_32.c | |
parent | 8c5beb50d3ec915d15c4d38aa37282309a65f14e (diff) |
x86: move e820_resource_resources to e820.c
and make 32-bit resource registration more like 64 bit.
also move probe_roms back to setup_32.c
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/setup_32.c')
-rw-r--r-- | arch/x86/kernel/setup_32.c | 208 |
1 files changed, 175 insertions, 33 deletions
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 72b11d4557b7..f3ddba5ed9a7 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -445,25 +445,28 @@ static void __init reserve_crashkernel(void) | |||
445 | ret = parse_crashkernel(boot_command_line, total_mem, | 445 | ret = parse_crashkernel(boot_command_line, total_mem, |
446 | &crash_size, &crash_base); | 446 | &crash_size, &crash_base); |
447 | if (ret == 0 && crash_size > 0) { | 447 | if (ret == 0 && crash_size > 0) { |
448 | if (crash_base > 0) { | 448 | if (crash_base <= 0) { |
449 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | ||
450 | "for crashkernel (System RAM: %ldMB)\n", | ||
451 | (unsigned long)(crash_size >> 20), | ||
452 | (unsigned long)(crash_base >> 20), | ||
453 | (unsigned long)(total_mem >> 20)); | ||
454 | |||
455 | if (reserve_bootmem(crash_base, crash_size, | ||
456 | BOOTMEM_EXCLUSIVE) < 0) { | ||
457 | printk(KERN_INFO "crashkernel reservation " | ||
458 | "failed - memory is in use\n"); | ||
459 | return; | ||
460 | } | ||
461 | |||
462 | crashk_res.start = crash_base; | ||
463 | crashk_res.end = crash_base + crash_size - 1; | ||
464 | } else | ||
465 | printk(KERN_INFO "crashkernel reservation failed - " | 449 | printk(KERN_INFO "crashkernel reservation failed - " |
466 | "you have to specify a base address\n"); | 450 | "you have to specify a base address\n"); |
451 | return; | ||
452 | } | ||
453 | |||
454 | if (reserve_bootmem_generic(crash_base, crash_size, | ||
455 | BOOTMEM_EXCLUSIVE) < 0) { | ||
456 | printk(KERN_INFO "crashkernel reservation failed - " | ||
457 | "memory is in use\n"); | ||
458 | return; | ||
459 | } | ||
460 | |||
461 | printk(KERN_INFO "Reserving %ldMB of memory at %ldMB " | ||
462 | "for crashkernel (System RAM: %ldMB)\n", | ||
463 | (unsigned long)(crash_size >> 20), | ||
464 | (unsigned long)(crash_base >> 20), | ||
465 | (unsigned long)(total_mem >> 20)); | ||
466 | |||
467 | crashk_res.start = crash_base; | ||
468 | crashk_res.end = crash_base + crash_size - 1; | ||
469 | insert_resource(&iomem_resource, &crashk_res); | ||
467 | } | 470 | } |
468 | } | 471 | } |
469 | #else | 472 | #else |
@@ -675,6 +678,8 @@ int x86_cpu_to_node_map_init[NR_CPUS] = { | |||
675 | DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; | 678 | DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; |
676 | #endif | 679 | #endif |
677 | 680 | ||
681 | static void probe_roms(void); | ||
682 | |||
678 | /* | 683 | /* |
679 | * Determine if we were loaded by an EFI loader. If so, then we have also been | 684 | * Determine if we were loaded by an EFI loader. If so, then we have also been |
680 | * passed the efi memmap, systab, etc., so we should use these data structures | 685 | * passed the efi memmap, systab, etc., so we should use these data structures |
@@ -684,6 +689,7 @@ DEFINE_PER_CPU(int, x86_cpu_to_node_map) = NUMA_NO_NODE; | |||
684 | */ | 689 | */ |
685 | void __init setup_arch(char **cmdline_p) | 690 | void __init setup_arch(char **cmdline_p) |
686 | { | 691 | { |
692 | int i; | ||
687 | unsigned long max_low_pfn; | 693 | unsigned long max_low_pfn; |
688 | 694 | ||
689 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); | 695 | memcpy(&boot_cpu_data, &new_cpu_data, sizeof(new_cpu_data)); |
@@ -745,6 +751,13 @@ void __init setup_arch(char **cmdline_p) | |||
745 | 751 | ||
746 | finish_e820_parsing(); | 752 | finish_e820_parsing(); |
747 | 753 | ||
754 | probe_roms(); | ||
755 | |||
756 | /* after parse_early_param, so could debug it */ | ||
757 | insert_resource(&iomem_resource, &code_resource); | ||
758 | insert_resource(&iomem_resource, &data_resource); | ||
759 | insert_resource(&iomem_resource, &bss_resource); | ||
760 | |||
748 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); | 761 | strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE); |
749 | *cmdline_p = command_line; | 762 | *cmdline_p = command_line; |
750 | 763 | ||
@@ -861,9 +874,16 @@ void __init setup_arch(char **cmdline_p) | |||
861 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); | 874 | "CONFIG_X86_GENERICARCH or CONFIG_X86_BIGSMP.\n"); |
862 | #endif | 875 | #endif |
863 | 876 | ||
864 | e820_setup_gap(); | 877 | e820_reserve_resources(); |
865 | e820_mark_nosave_regions(max_low_pfn); | 878 | e820_mark_nosave_regions(max_low_pfn); |
866 | 879 | ||
880 | request_resource(&iomem_resource, &video_ram_resource); | ||
881 | /* request I/O space for devices used on all i[345]86 PCs */ | ||
882 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | ||
883 | request_resource(&ioport_resource, &standard_io_resources[i]); | ||
884 | |||
885 | e820_setup_gap(); | ||
886 | |||
867 | #ifdef CONFIG_VT | 887 | #ifdef CONFIG_VT |
868 | #if defined(CONFIG_VGA_CONSOLE) | 888 | #if defined(CONFIG_VGA_CONSOLE) |
869 | if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) | 889 | if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY)) |
@@ -874,25 +894,147 @@ void __init setup_arch(char **cmdline_p) | |||
874 | #endif | 894 | #endif |
875 | } | 895 | } |
876 | 896 | ||
877 | /* | 897 | static struct resource system_rom_resource = { |
878 | * Request address space for all standard resources | 898 | .name = "System ROM", |
879 | * | 899 | .start = 0xf0000, |
880 | * This is called just before pcibios_init(), which is also a | 900 | .end = 0xfffff, |
881 | * subsys_initcall, but is linked in later (in arch/i386/pci/common.c). | 901 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM |
882 | */ | 902 | }; |
883 | static int __init request_standard_resources(void) | 903 | |
904 | static struct resource extension_rom_resource = { | ||
905 | .name = "Extension ROM", | ||
906 | .start = 0xe0000, | ||
907 | .end = 0xeffff, | ||
908 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
909 | }; | ||
910 | |||
911 | static struct resource adapter_rom_resources[] = { { | ||
912 | .name = "Adapter ROM", | ||
913 | .start = 0xc8000, | ||
914 | .end = 0, | ||
915 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
916 | }, { | ||
917 | .name = "Adapter ROM", | ||
918 | .start = 0, | ||
919 | .end = 0, | ||
920 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
921 | }, { | ||
922 | .name = "Adapter ROM", | ||
923 | .start = 0, | ||
924 | .end = 0, | ||
925 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
926 | }, { | ||
927 | .name = "Adapter ROM", | ||
928 | .start = 0, | ||
929 | .end = 0, | ||
930 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
931 | }, { | ||
932 | .name = "Adapter ROM", | ||
933 | .start = 0, | ||
934 | .end = 0, | ||
935 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
936 | }, { | ||
937 | .name = "Adapter ROM", | ||
938 | .start = 0, | ||
939 | .end = 0, | ||
940 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
941 | } }; | ||
942 | |||
943 | static struct resource video_rom_resource = { | ||
944 | .name = "Video ROM", | ||
945 | .start = 0xc0000, | ||
946 | .end = 0xc7fff, | ||
947 | .flags = IORESOURCE_BUSY | IORESOURCE_READONLY | IORESOURCE_MEM | ||
948 | }; | ||
949 | |||
950 | #define ROMSIGNATURE 0xaa55 | ||
951 | |||
952 | static int __init romsignature(const unsigned char *rom) | ||
953 | { | ||
954 | const unsigned short * const ptr = (const unsigned short *)rom; | ||
955 | unsigned short sig; | ||
956 | |||
957 | return probe_kernel_address(ptr, sig) == 0 && sig == ROMSIGNATURE; | ||
958 | } | ||
959 | |||
960 | static int __init romchecksum(const unsigned char *rom, unsigned long length) | ||
961 | { | ||
962 | unsigned char sum, c; | ||
963 | |||
964 | for (sum = 0; length && probe_kernel_address(rom++, c) == 0; length--) | ||
965 | sum += c; | ||
966 | return !length && !sum; | ||
967 | } | ||
968 | |||
969 | static void __init probe_roms(void) | ||
884 | { | 970 | { |
971 | const unsigned char *rom; | ||
972 | unsigned long start, length, upper; | ||
973 | unsigned char c; | ||
885 | int i; | 974 | int i; |
886 | 975 | ||
887 | printk(KERN_INFO "Setting up standard PCI resources\n"); | 976 | /* video rom */ |
888 | init_iomem_resources(&code_resource, &data_resource, &bss_resource); | 977 | upper = adapter_rom_resources[0].start; |
978 | for (start = video_rom_resource.start; start < upper; start += 2048) { | ||
979 | rom = isa_bus_to_virt(start); | ||
980 | if (!romsignature(rom)) | ||
981 | continue; | ||
889 | 982 | ||
890 | request_resource(&iomem_resource, &video_ram_resource); | 983 | video_rom_resource.start = start; |
891 | 984 | ||
892 | /* request I/O space for devices used on all i[345]86 PCs */ | 985 | if (probe_kernel_address(rom + 2, c) != 0) |
893 | for (i = 0; i < ARRAY_SIZE(standard_io_resources); i++) | 986 | continue; |
894 | request_resource(&ioport_resource, &standard_io_resources[i]); | 987 | |
895 | return 0; | 988 | /* 0 < length <= 0x7f * 512, historically */ |
989 | length = c * 512; | ||
990 | |||
991 | /* if checksum okay, trust length byte */ | ||
992 | if (length && romchecksum(rom, length)) | ||
993 | video_rom_resource.end = start + length - 1; | ||
994 | |||
995 | request_resource(&iomem_resource, &video_rom_resource); | ||
996 | break; | ||
997 | } | ||
998 | |||
999 | start = (video_rom_resource.end + 1 + 2047) & ~2047UL; | ||
1000 | if (start < upper) | ||
1001 | start = upper; | ||
1002 | |||
1003 | /* system rom */ | ||
1004 | request_resource(&iomem_resource, &system_rom_resource); | ||
1005 | upper = system_rom_resource.start; | ||
1006 | |||
1007 | /* check for extension rom (ignore length byte!) */ | ||
1008 | rom = isa_bus_to_virt(extension_rom_resource.start); | ||
1009 | if (romsignature(rom)) { | ||
1010 | length = extension_rom_resource.end - extension_rom_resource.start + 1; | ||
1011 | if (romchecksum(rom, length)) { | ||
1012 | request_resource(&iomem_resource, &extension_rom_resource); | ||
1013 | upper = extension_rom_resource.start; | ||
1014 | } | ||
1015 | } | ||
1016 | |||
1017 | /* check for adapter roms on 2k boundaries */ | ||
1018 | for (i = 0; i < ARRAY_SIZE(adapter_rom_resources) && start < upper; start += 2048) { | ||
1019 | rom = isa_bus_to_virt(start); | ||
1020 | if (!romsignature(rom)) | ||
1021 | continue; | ||
1022 | |||
1023 | if (probe_kernel_address(rom + 2, c) != 0) | ||
1024 | continue; | ||
1025 | |||
1026 | /* 0 < length <= 0x7f * 512, historically */ | ||
1027 | length = c * 512; | ||
1028 | |||
1029 | /* but accept any length that fits if checksum okay */ | ||
1030 | if (!length || start + length > upper || !romchecksum(rom, length)) | ||
1031 | continue; | ||
1032 | |||
1033 | adapter_rom_resources[i].start = start; | ||
1034 | adapter_rom_resources[i].end = start + length - 1; | ||
1035 | request_resource(&iomem_resource, &adapter_rom_resources[i]); | ||
1036 | |||
1037 | start = adapter_rom_resources[i++].end & ~2047UL; | ||
1038 | } | ||
896 | } | 1039 | } |
897 | 1040 | ||
898 | subsys_initcall(request_standard_resources); | ||