diff options
Diffstat (limited to 'arch/x86/lguest/boot.c')
-rw-r--r-- | arch/x86/lguest/boot.c | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 5c7e2fd52075..65f0b8a47bed 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/lguest_launcher.h> | 55 | #include <linux/lguest_launcher.h> |
56 | #include <linux/virtio_console.h> | 56 | #include <linux/virtio_console.h> |
57 | #include <linux/pm.h> | 57 | #include <linux/pm.h> |
58 | #include <asm/apic.h> | ||
58 | #include <asm/lguest.h> | 59 | #include <asm/lguest.h> |
59 | #include <asm/paravirt.h> | 60 | #include <asm/paravirt.h> |
60 | #include <asm/param.h> | 61 | #include <asm/param.h> |
@@ -607,7 +608,7 @@ static unsigned long lguest_get_wallclock(void) | |||
607 | * what speed it runs at, or 0 if it's unusable as a reliable clock source. | 608 | * what speed it runs at, or 0 if it's unusable as a reliable clock source. |
608 | * This matches what we want here: if we return 0 from this function, the x86 | 609 | * This matches what we want here: if we return 0 from this function, the x86 |
609 | * TSC clock will give up and not register itself. */ | 610 | * TSC clock will give up and not register itself. */ |
610 | static unsigned long lguest_cpu_khz(void) | 611 | static unsigned long lguest_tsc_khz(void) |
611 | { | 612 | { |
612 | return lguest_data.tsc_khz; | 613 | return lguest_data.tsc_khz; |
613 | } | 614 | } |
@@ -783,14 +784,44 @@ static void lguest_wbinvd(void) | |||
783 | * code qualifies for Advanced. It will also never interrupt anything. It | 784 | * code qualifies for Advanced. It will also never interrupt anything. It |
784 | * does, however, allow us to get through the Linux boot code. */ | 785 | * does, however, allow us to get through the Linux boot code. */ |
785 | #ifdef CONFIG_X86_LOCAL_APIC | 786 | #ifdef CONFIG_X86_LOCAL_APIC |
786 | static void lguest_apic_write(unsigned long reg, u32 v) | 787 | static void lguest_apic_write(u32 reg, u32 v) |
787 | { | 788 | { |
788 | } | 789 | } |
789 | 790 | ||
790 | static u32 lguest_apic_read(unsigned long reg) | 791 | static u32 lguest_apic_read(u32 reg) |
791 | { | 792 | { |
792 | return 0; | 793 | return 0; |
793 | } | 794 | } |
795 | |||
796 | static u64 lguest_apic_icr_read(void) | ||
797 | { | ||
798 | return 0; | ||
799 | } | ||
800 | |||
801 | static void lguest_apic_icr_write(u32 low, u32 id) | ||
802 | { | ||
803 | /* Warn to see if there's any stray references */ | ||
804 | WARN_ON(1); | ||
805 | } | ||
806 | |||
807 | static void lguest_apic_wait_icr_idle(void) | ||
808 | { | ||
809 | return; | ||
810 | } | ||
811 | |||
812 | static u32 lguest_apic_safe_wait_icr_idle(void) | ||
813 | { | ||
814 | return 0; | ||
815 | } | ||
816 | |||
817 | static struct apic_ops lguest_basic_apic_ops = { | ||
818 | .read = lguest_apic_read, | ||
819 | .write = lguest_apic_write, | ||
820 | .icr_read = lguest_apic_icr_read, | ||
821 | .icr_write = lguest_apic_icr_write, | ||
822 | .wait_icr_idle = lguest_apic_wait_icr_idle, | ||
823 | .safe_wait_icr_idle = lguest_apic_safe_wait_icr_idle, | ||
824 | }; | ||
794 | #endif | 825 | #endif |
795 | 826 | ||
796 | /* STOP! Until an interrupt comes in. */ | 827 | /* STOP! Until an interrupt comes in. */ |
@@ -835,7 +866,7 @@ static __init char *lguest_memory_setup(void) | |||
835 | 866 | ||
836 | /* The Linux bootloader header contains an "e820" memory map: the | 867 | /* The Linux bootloader header contains an "e820" memory map: the |
837 | * Launcher populated the first entry with our memory limit. */ | 868 | * Launcher populated the first entry with our memory limit. */ |
838 | add_memory_region(boot_params.e820_map[0].addr, | 869 | e820_add_region(boot_params.e820_map[0].addr, |
839 | boot_params.e820_map[0].size, | 870 | boot_params.e820_map[0].size, |
840 | boot_params.e820_map[0].type); | 871 | boot_params.e820_map[0].type); |
841 | 872 | ||
@@ -990,15 +1021,13 @@ __init void lguest_init(void) | |||
990 | 1021 | ||
991 | #ifdef CONFIG_X86_LOCAL_APIC | 1022 | #ifdef CONFIG_X86_LOCAL_APIC |
992 | /* apic read/write intercepts */ | 1023 | /* apic read/write intercepts */ |
993 | pv_apic_ops.apic_write = lguest_apic_write; | 1024 | apic_ops = &lguest_basic_apic_ops; |
994 | pv_apic_ops.apic_write_atomic = lguest_apic_write; | ||
995 | pv_apic_ops.apic_read = lguest_apic_read; | ||
996 | #endif | 1025 | #endif |
997 | 1026 | ||
998 | /* time operations */ | 1027 | /* time operations */ |
999 | pv_time_ops.get_wallclock = lguest_get_wallclock; | 1028 | pv_time_ops.get_wallclock = lguest_get_wallclock; |
1000 | pv_time_ops.time_init = lguest_time_init; | 1029 | pv_time_ops.time_init = lguest_time_init; |
1001 | pv_time_ops.get_cpu_khz = lguest_cpu_khz; | 1030 | pv_time_ops.get_tsc_khz = lguest_tsc_khz; |
1002 | 1031 | ||
1003 | /* Now is a good time to look at the implementations of these functions | 1032 | /* Now is a good time to look at the implementations of these functions |
1004 | * before returning to the rest of lguest_init(). */ | 1033 | * before returning to the rest of lguest_init(). */ |
@@ -1012,8 +1041,12 @@ __init void lguest_init(void) | |||
1012 | * clobbered. The Launcher places our initial pagetables somewhere at | 1041 | * clobbered. The Launcher places our initial pagetables somewhere at |
1013 | * the top of our physical memory, so we don't need extra space: set | 1042 | * the top of our physical memory, so we don't need extra space: set |
1014 | * init_pg_tables_end to the end of the kernel. */ | 1043 | * init_pg_tables_end to the end of the kernel. */ |
1044 | init_pg_tables_start = __pa(pg0); | ||
1015 | init_pg_tables_end = __pa(pg0); | 1045 | init_pg_tables_end = __pa(pg0); |
1016 | 1046 | ||
1047 | /* As described in head_32.S, we map the first 128M of memory. */ | ||
1048 | max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; | ||
1049 | |||
1017 | /* Load the %fs segment register (the per-cpu segment register) with | 1050 | /* Load the %fs segment register (the per-cpu segment register) with |
1018 | * the normal data segment to get through booting. */ | 1051 | * the normal data segment to get through booting. */ |
1019 | asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); | 1052 | asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory"); |
@@ -1065,9 +1098,9 @@ __init void lguest_init(void) | |||
1065 | pm_power_off = lguest_power_off; | 1098 | pm_power_off = lguest_power_off; |
1066 | machine_ops.restart = lguest_restart; | 1099 | machine_ops.restart = lguest_restart; |
1067 | 1100 | ||
1068 | /* Now we're set up, call start_kernel() in init/main.c and we proceed | 1101 | /* Now we're set up, call i386_start_kernel() in head32.c and we proceed |
1069 | * to boot as normal. It never returns. */ | 1102 | * to boot as normal. It never returns. */ |
1070 | start_kernel(); | 1103 | i386_start_kernel(); |
1071 | } | 1104 | } |
1072 | /* | 1105 | /* |
1073 | * This marks the end of stage II of our journey, The Guest. | 1106 | * This marks the end of stage II of our journey, The Guest. |