mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 12:42:02 +00:00
Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: (38 commits) x86: Move get/set_wallclock to x86_platform_ops x86: platform: Fix section annotations x86: apic namespace cleanup x86: Distangle ioapic and i8259 x86: Add Moorestown early detection x86: Add hardware_subarch ID for Moorestown x86: Add early platform detection x86: Move tsc_init to late_time_init x86: Move tsc_calibration to x86_init_ops x86: Replace the now identical time_32/64.c by time.c x86: time_32/64.c unify profile_pc x86: Move calibrate_cpu to tsc.c x86: Make timer setup and global variables the same in time_32/64.c x86: Remove mca bus ifdef from timer interrupt x86: Simplify timer_ack magic in time_32.c x86: Prepare unification of time_32/64.c x86: Remove do_timer hook x86: Add timer_init to x86_init_ops x86: Move percpu clockevents setup to x86_init_ops x86: Move xen_post_allocator_init into xen_pagetable_setup_done ... Fix up conflicts in arch/x86/include/asm/io_apic.h
This commit is contained in:
commit
78f28b7c55
@ -599,6 +599,7 @@ Protocol: 2.07+
|
||||
0x00000000 The default x86/PC environment
|
||||
0x00000001 lguest
|
||||
0x00000002 Xen
|
||||
0x00000003 Moorestown MID
|
||||
|
||||
Field name: hardware_subarch_data
|
||||
Type: write (subarch-dependent)
|
||||
|
@ -325,6 +325,7 @@ config X86_EXTENDED_PLATFORM
|
||||
SGI 320/540 (Visual Workstation)
|
||||
Summit/EXA (IBM x440)
|
||||
Unisys ES7000 IA32 series
|
||||
Moorestown MID devices
|
||||
|
||||
If you have one of these systems, or if you want to build a
|
||||
generic distribution kernel, say Y here - otherwise say N.
|
||||
@ -384,6 +385,18 @@ config X86_ELAN
|
||||
|
||||
If unsure, choose "PC-compatible" instead.
|
||||
|
||||
config X86_MRST
|
||||
bool "Moorestown MID platform"
|
||||
depends on X86_32
|
||||
depends on X86_EXTENDED_PLATFORM
|
||||
---help---
|
||||
Moorestown is Intel's Low Power Intel Architecture (LPIA) based Moblin
|
||||
Internet Device(MID) platform. Moorestown consists of two chips:
|
||||
Lincroft (CPU core, graphics, and memory controller) and Langwell IOH.
|
||||
Unlike standard x86 PCs, Moorestown does not have many legacy devices
|
||||
nor standard legacy replacement devices/features. e.g. Moorestown does
|
||||
not contain i8259, i8254, HPET, legacy BIOS, most of the io ports.
|
||||
|
||||
config X86_RDC321X
|
||||
bool "RDC R-321x SoC"
|
||||
depends on X86_32
|
||||
|
@ -70,9 +70,6 @@ static inline void default_inquire_remote_apic(int apicid)
|
||||
*/
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
#include <asm/paravirt.h>
|
||||
#else
|
||||
#define setup_boot_clock setup_boot_APIC_clock
|
||||
#define setup_secondary_clock setup_secondary_APIC_clock
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
@ -252,6 +249,8 @@ static inline void lapic_shutdown(void) { }
|
||||
static inline void init_apic_mappings(void) { }
|
||||
static inline void disable_local_APIC(void) { }
|
||||
static inline void apic_disable(void) { }
|
||||
# define setup_boot_APIC_clock x86_init_noop
|
||||
# define setup_secondary_APIC_clock x86_init_noop
|
||||
#endif /* !CONFIG_X86_LOCAL_APIC */
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
@ -300,7 +299,7 @@ struct apic {
|
||||
int (*cpu_present_to_apicid)(int mps_cpu);
|
||||
physid_mask_t (*apicid_to_cpu_present)(int phys_apicid);
|
||||
void (*setup_portio_remap)(void);
|
||||
int (*check_phys_apicid_present)(int boot_cpu_physical_apicid);
|
||||
int (*check_phys_apicid_present)(int phys_apicid);
|
||||
void (*enable_apic_mode)(void);
|
||||
int (*phys_pkg_id)(int cpuid_apic, int index_msb);
|
||||
|
||||
@ -434,7 +433,7 @@ extern struct apic apic_x2apic_uv_x;
|
||||
DECLARE_PER_CPU(int, x2apic_extra_bits);
|
||||
|
||||
extern int default_cpu_present_to_apicid(int mps_cpu);
|
||||
extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
|
||||
extern int default_check_phys_apicid_present(int phys_apicid);
|
||||
#endif
|
||||
|
||||
static inline void default_wait_for_init_deassert(atomic_t *deassert)
|
||||
@ -550,9 +549,9 @@ static inline int __default_cpu_present_to_apicid(int mps_cpu)
|
||||
}
|
||||
|
||||
static inline int
|
||||
__default_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||
__default_check_phys_apicid_present(int phys_apicid)
|
||||
{
|
||||
return physid_isset(boot_cpu_physical_apicid, phys_cpu_present_map);
|
||||
return physid_isset(phys_apicid, phys_cpu_present_map);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
@ -562,13 +561,13 @@ static inline int default_cpu_present_to_apicid(int mps_cpu)
|
||||
}
|
||||
|
||||
static inline int
|
||||
default_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||
default_check_phys_apicid_present(int phys_apicid)
|
||||
{
|
||||
return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
|
||||
return __default_check_phys_apicid_present(phys_apicid);
|
||||
}
|
||||
#else
|
||||
extern int default_cpu_present_to_apicid(int mps_cpu);
|
||||
extern int default_check_phys_apicid_present(int boot_cpu_physical_apicid);
|
||||
extern int default_check_phys_apicid_present(int phys_apicid);
|
||||
#endif
|
||||
|
||||
static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid)
|
||||
|
@ -110,4 +110,14 @@ struct boot_params {
|
||||
__u8 _pad9[276]; /* 0xeec */
|
||||
} __attribute__((packed));
|
||||
|
||||
enum {
|
||||
X86_SUBARCH_PC = 0,
|
||||
X86_SUBARCH_LGUEST,
|
||||
X86_SUBARCH_XEN,
|
||||
X86_SUBARCH_MRST,
|
||||
X86_NR_SUBARCHS,
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif /* _ASM_X86_BOOTPARAM_H */
|
||||
|
@ -1,16 +0,0 @@
|
||||
/* defines for inline arch setup functions */
|
||||
#include <linux/clockchips.h>
|
||||
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/i8253.h>
|
||||
|
||||
/**
|
||||
* do_timer_interrupt_hook - hook into timer tick
|
||||
*
|
||||
* Call the pit clock event handler. see asm/i8253.h
|
||||
**/
|
||||
|
||||
static inline void do_timer_interrupt_hook(void)
|
||||
{
|
||||
global_clock_event->event_handler(global_clock_event);
|
||||
}
|
@ -126,8 +126,6 @@ extern void e820_reserve_resources(void);
|
||||
extern void e820_reserve_resources_late(void);
|
||||
extern void setup_memory_map(void);
|
||||
extern char *default_machine_specific_memory_setup(void);
|
||||
extern char *machine_specific_memory_setup(void);
|
||||
extern char *memory_setup(void);
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef ASM_X86__HYPERVISOR_H
|
||||
#define ASM_X86__HYPERVISOR_H
|
||||
|
||||
extern unsigned long get_hypervisor_tsc_freq(void);
|
||||
extern void init_hypervisor(struct cpuinfo_x86 *c);
|
||||
extern void init_hypervisor_platform(void);
|
||||
|
||||
#endif
|
||||
|
@ -143,6 +143,8 @@ extern int noioapicreroute;
|
||||
/* 1 if the timer IRQ uses the '8259A Virtual Wire' mode */
|
||||
extern int timer_through_8259;
|
||||
|
||||
extern void io_apic_disable_legacy(void);
|
||||
|
||||
/*
|
||||
* If we use the IO-APIC for IRQ routing, disable automatic
|
||||
* assignment of PCI IRQ's.
|
||||
@ -176,6 +178,7 @@ extern int setup_ioapic_entry(int apic, int irq,
|
||||
int polarity, int vector, int pin);
|
||||
extern void ioapic_write_entry(int apic, int pin,
|
||||
struct IO_APIC_route_entry e);
|
||||
extern void setup_ioapic_ids_from_mpc(void);
|
||||
|
||||
struct mp_ioapic_gsi{
|
||||
int gsi_base;
|
||||
@ -187,12 +190,14 @@ int mp_find_ioapic_pin(int ioapic, int gsi);
|
||||
void __init mp_register_ioapic(int id, u32 address, u32 gsi_base);
|
||||
|
||||
#else /* !CONFIG_X86_IO_APIC */
|
||||
|
||||
#define io_apic_assign_pci_irqs 0
|
||||
#define setup_ioapic_ids_from_mpc x86_init_noop
|
||||
static const int timer_through_8259 = 0;
|
||||
static inline void ioapic_init_mappings(void) { }
|
||||
static inline void ioapic_insert_resources(void) { }
|
||||
|
||||
static inline void probe_nr_irqs_gsi(void) { }
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_IO_APIC_H */
|
||||
|
@ -37,7 +37,6 @@ extern void fixup_irqs(void);
|
||||
#endif
|
||||
|
||||
extern void (*generic_interrupt_extension)(void);
|
||||
extern void init_IRQ(void);
|
||||
extern void native_init_IRQ(void);
|
||||
extern bool handle_irq(unsigned irq, struct pt_regs *regs);
|
||||
|
||||
@ -47,4 +46,6 @@ extern unsigned int do_IRQ(struct pt_regs *regs);
|
||||
extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
|
||||
extern int vector_used_by_percpu_irq(unsigned int vector);
|
||||
|
||||
extern void init_ISA_irqs(void);
|
||||
|
||||
#endif /* _ASM_X86_IRQ_H */
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/mpspec_def.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
extern int apic_version[MAX_APICS];
|
||||
extern int pic_mode;
|
||||
@ -41,9 +42,6 @@ extern int quad_local_to_mp_bus_id [NR_CPUS/4][4];
|
||||
|
||||
#endif /* CONFIG_X86_64 */
|
||||
|
||||
extern void early_find_smp_config(void);
|
||||
extern void early_get_smp_config(void);
|
||||
|
||||
#if defined(CONFIG_MCA) || defined(CONFIG_EISA)
|
||||
extern int mp_bus_id_to_type[MAX_MP_BUSSES];
|
||||
#endif
|
||||
@ -52,20 +50,55 @@ extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
|
||||
|
||||
extern unsigned int boot_cpu_physical_apicid;
|
||||
extern unsigned int max_physical_apicid;
|
||||
extern int smp_found_config;
|
||||
extern int mpc_default_type;
|
||||
extern unsigned long mp_lapic_addr;
|
||||
|
||||
extern void get_smp_config(void);
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
extern int smp_found_config;
|
||||
#else
|
||||
# define smp_found_config 0
|
||||
#endif
|
||||
|
||||
static inline void get_smp_config(void)
|
||||
{
|
||||
x86_init.mpparse.get_smp_config(0);
|
||||
}
|
||||
|
||||
static inline void early_get_smp_config(void)
|
||||
{
|
||||
x86_init.mpparse.get_smp_config(1);
|
||||
}
|
||||
|
||||
static inline void find_smp_config(void)
|
||||
{
|
||||
x86_init.mpparse.find_smp_config(1);
|
||||
}
|
||||
|
||||
static inline void early_find_smp_config(void)
|
||||
{
|
||||
x86_init.mpparse.find_smp_config(0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_MPPARSE
|
||||
extern void find_smp_config(void);
|
||||
extern void early_reserve_e820_mpc_new(void);
|
||||
extern int enable_update_mptable;
|
||||
extern int default_mpc_apic_id(struct mpc_cpu *m);
|
||||
extern void default_smp_read_mpc_oem(struct mpc_table *mpc);
|
||||
# ifdef CONFIG_X86_IO_APIC
|
||||
extern void default_mpc_oem_bus_info(struct mpc_bus *m, char *str);
|
||||
# else
|
||||
# define default_mpc_oem_bus_info NULL
|
||||
# endif
|
||||
extern void default_find_smp_config(unsigned int reserve);
|
||||
extern void default_get_smp_config(unsigned int early);
|
||||
#else
|
||||
static inline void find_smp_config(void) { }
|
||||
static inline void early_reserve_e820_mpc_new(void) { }
|
||||
#define enable_update_mptable 0
|
||||
#define default_mpc_apic_id NULL
|
||||
#define default_smp_read_mpc_oem NULL
|
||||
#define default_mpc_oem_bus_info NULL
|
||||
#define default_find_smp_config x86_init_uint_noop
|
||||
#define default_get_smp_config x86_init_uint_noop
|
||||
#endif
|
||||
|
||||
void __cpuinit generic_processor_info(int apicid, int version);
|
||||
|
@ -24,22 +24,6 @@ static inline void load_sp0(struct tss_struct *tss,
|
||||
PVOP_VCALL2(pv_cpu_ops.load_sp0, tss, thread);
|
||||
}
|
||||
|
||||
#define ARCH_SETUP pv_init_ops.arch_setup();
|
||||
static inline unsigned long get_wallclock(void)
|
||||
{
|
||||
return PVOP_CALL0(unsigned long, pv_time_ops.get_wallclock);
|
||||
}
|
||||
|
||||
static inline int set_wallclock(unsigned long nowtime)
|
||||
{
|
||||
return PVOP_CALL1(int, pv_time_ops.set_wallclock, nowtime);
|
||||
}
|
||||
|
||||
static inline void (*choose_time_init(void))(void)
|
||||
{
|
||||
return pv_time_ops.time_init;
|
||||
}
|
||||
|
||||
/* The paravirtualized CPUID instruction. */
|
||||
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
|
||||
unsigned int *ecx, unsigned int *edx)
|
||||
@ -245,7 +229,6 @@ static inline unsigned long long paravirt_sched_clock(void)
|
||||
{
|
||||
return PVOP_CALL0(unsigned long long, pv_time_ops.sched_clock);
|
||||
}
|
||||
#define calibrate_tsc() (pv_time_ops.get_tsc_khz())
|
||||
|
||||
static inline unsigned long long paravirt_read_pmc(int counter)
|
||||
{
|
||||
@ -363,34 +346,6 @@ static inline void slow_down_io(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
static inline void setup_boot_clock(void)
|
||||
{
|
||||
PVOP_VCALL0(pv_apic_ops.setup_boot_clock);
|
||||
}
|
||||
|
||||
static inline void setup_secondary_clock(void)
|
||||
{
|
||||
PVOP_VCALL0(pv_apic_ops.setup_secondary_clock);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void paravirt_post_allocator_init(void)
|
||||
{
|
||||
if (pv_init_ops.post_allocator_init)
|
||||
(*pv_init_ops.post_allocator_init)();
|
||||
}
|
||||
|
||||
static inline void paravirt_pagetable_setup_start(pgd_t *base)
|
||||
{
|
||||
(*pv_mmu_ops.pagetable_setup_start)(base);
|
||||
}
|
||||
|
||||
static inline void paravirt_pagetable_setup_done(pgd_t *base)
|
||||
{
|
||||
(*pv_mmu_ops.pagetable_setup_done)(base);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static inline void startup_ipi_hook(int phys_apicid, unsigned long start_eip,
|
||||
unsigned long start_esp)
|
||||
@ -948,6 +903,8 @@ static inline unsigned long __raw_local_irq_save(void)
|
||||
#undef PVOP_VCALL4
|
||||
#undef PVOP_CALL4
|
||||
|
||||
extern void default_banner(void);
|
||||
|
||||
#else /* __ASSEMBLY__ */
|
||||
|
||||
#define _PVSITE(ptype, clobbers, ops, word, algn) \
|
||||
@ -1088,5 +1045,7 @@ static inline unsigned long __raw_local_irq_save(void)
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
#else /* CONFIG_PARAVIRT */
|
||||
# define default_banner x86_init_noop
|
||||
#endif /* !CONFIG_PARAVIRT */
|
||||
#endif /* _ASM_X86_PARAVIRT_H */
|
||||
|
@ -78,14 +78,6 @@ struct pv_init_ops {
|
||||
*/
|
||||
unsigned (*patch)(u8 type, u16 clobber, void *insnbuf,
|
||||
unsigned long addr, unsigned len);
|
||||
|
||||
/* Basic arch-specific setup */
|
||||
void (*arch_setup)(void);
|
||||
char *(*memory_setup)(void);
|
||||
void (*post_allocator_init)(void);
|
||||
|
||||
/* Print a banner to identify the environment */
|
||||
void (*banner)(void);
|
||||
};
|
||||
|
||||
|
||||
@ -96,12 +88,6 @@ struct pv_lazy_ops {
|
||||
};
|
||||
|
||||
struct pv_time_ops {
|
||||
void (*time_init)(void);
|
||||
|
||||
/* Set and set time of day */
|
||||
unsigned long (*get_wallclock)(void);
|
||||
int (*set_wallclock)(unsigned long);
|
||||
|
||||
unsigned long long (*sched_clock)(void);
|
||||
unsigned long (*get_tsc_khz)(void);
|
||||
};
|
||||
@ -203,8 +189,6 @@ struct pv_cpu_ops {
|
||||
};
|
||||
|
||||
struct pv_irq_ops {
|
||||
void (*init_IRQ)(void);
|
||||
|
||||
/*
|
||||
* Get/set interrupt state. save_fl and restore_fl are only
|
||||
* expected to use X86_EFLAGS_IF; all other bits
|
||||
@ -229,9 +213,6 @@ struct pv_irq_ops {
|
||||
|
||||
struct pv_apic_ops {
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
void (*setup_boot_clock)(void);
|
||||
void (*setup_secondary_clock)(void);
|
||||
|
||||
void (*startup_ipi_hook)(int phys_apicid,
|
||||
unsigned long start_eip,
|
||||
unsigned long start_esp);
|
||||
@ -239,15 +220,6 @@ struct pv_apic_ops {
|
||||
};
|
||||
|
||||
struct pv_mmu_ops {
|
||||
/*
|
||||
* Called before/after init_mm pagetable setup. setup_start
|
||||
* may reset %cr3, and may pre-install parts of the pagetable;
|
||||
* pagetable setup is expected to preserve any existing
|
||||
* mapping.
|
||||
*/
|
||||
void (*pagetable_setup_start)(pgd_t *pgd_base);
|
||||
void (*pagetable_setup_done)(pgd_t *pgd_base);
|
||||
|
||||
unsigned long (*read_cr2)(void);
|
||||
void (*write_cr2)(unsigned long);
|
||||
|
||||
|
@ -56,16 +56,6 @@ extern struct list_head pgd_list;
|
||||
#define pte_update(mm, addr, ptep) do { } while (0)
|
||||
#define pte_update_defer(mm, addr, ptep) do { } while (0)
|
||||
|
||||
static inline void __init paravirt_pagetable_setup_start(pgd_t *base)
|
||||
{
|
||||
native_pagetable_setup_start(base);
|
||||
}
|
||||
|
||||
static inline void __init paravirt_pagetable_setup_done(pgd_t *base)
|
||||
{
|
||||
native_pagetable_setup_done(base);
|
||||
}
|
||||
|
||||
#define pgd_val(x) native_pgd_val(x)
|
||||
#define __pgd(x) native_make_pgd(x)
|
||||
|
||||
|
@ -299,8 +299,8 @@ void set_pte_vaddr(unsigned long vaddr, pte_t pte);
|
||||
extern void native_pagetable_setup_start(pgd_t *base);
|
||||
extern void native_pagetable_setup_done(pgd_t *base);
|
||||
#else
|
||||
static inline void native_pagetable_setup_start(pgd_t *base) {}
|
||||
static inline void native_pagetable_setup_done(pgd_t *base) {}
|
||||
#define native_pagetable_setup_start x86_init_pgd_noop
|
||||
#define native_pagetable_setup_done x86_init_pgd_noop
|
||||
#endif
|
||||
|
||||
struct seq_file;
|
||||
|
@ -5,43 +5,6 @@
|
||||
|
||||
#define COMMAND_LINE_SIZE 2048
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
/*
|
||||
* Any setup quirks to be performed?
|
||||
*/
|
||||
struct mpc_cpu;
|
||||
struct mpc_bus;
|
||||
struct mpc_oemtable;
|
||||
|
||||
struct x86_quirks {
|
||||
int (*arch_pre_time_init)(void);
|
||||
int (*arch_time_init)(void);
|
||||
int (*arch_pre_intr_init)(void);
|
||||
int (*arch_intr_init)(void);
|
||||
int (*arch_trap_init)(void);
|
||||
char * (*arch_memory_setup)(void);
|
||||
int (*mach_get_smp_config)(unsigned int early);
|
||||
int (*mach_find_smp_config)(unsigned int reserve);
|
||||
|
||||
int *mpc_record;
|
||||
int (*mpc_apic_id)(struct mpc_cpu *m);
|
||||
void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
|
||||
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
|
||||
void (*smp_read_mpc_oem)(struct mpc_oemtable *oemtable,
|
||||
unsigned short oemsize);
|
||||
int (*setup_ioapic_ids)(void);
|
||||
};
|
||||
|
||||
extern void x86_quirk_intr_init(void);
|
||||
|
||||
extern void x86_quirk_trap_init(void);
|
||||
|
||||
extern void x86_quirk_pre_time_init(void);
|
||||
extern void x86_quirk_time_init(void);
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#ifdef __i386__
|
||||
|
||||
#include <linux/pfn.h>
|
||||
@ -61,6 +24,7 @@ extern void x86_quirk_time_init(void);
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
#include <asm/bootparam.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
/* Interrupt control for vSMPowered x86_64 systems */
|
||||
#ifdef CONFIG_X86_64
|
||||
@ -79,11 +43,16 @@ static inline void visws_early_detect(void) { }
|
||||
static inline int is_visws_box(void) { return 0; }
|
||||
#endif
|
||||
|
||||
extern struct x86_quirks *x86_quirks;
|
||||
extern unsigned long saved_video_mode;
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
#define paravirt_post_allocator_init() do {} while (0)
|
||||
extern void reserve_standard_io_resources(void);
|
||||
extern void i386_reserve_resources(void);
|
||||
extern void setup_default_timer_irq(void);
|
||||
|
||||
#ifdef CONFIG_X86_MRST
|
||||
extern void x86_mrst_early_setup(void);
|
||||
#else
|
||||
static inline void x86_mrst_early_setup(void) { }
|
||||
#endif
|
||||
|
||||
#ifndef _SETUP
|
||||
|
@ -4,60 +4,7 @@
|
||||
extern void hpet_time_init(void);
|
||||
|
||||
#include <asm/mc146818rtc.h>
|
||||
#ifdef CONFIG_X86_32
|
||||
#include <linux/efi.h>
|
||||
|
||||
static inline unsigned long native_get_wallclock(void)
|
||||
{
|
||||
unsigned long retval;
|
||||
|
||||
if (efi_enabled)
|
||||
retval = efi_get_time();
|
||||
else
|
||||
retval = mach_get_cmos_time();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static inline int native_set_wallclock(unsigned long nowtime)
|
||||
{
|
||||
int retval;
|
||||
|
||||
if (efi_enabled)
|
||||
retval = efi_set_rtc_mmss(nowtime);
|
||||
else
|
||||
retval = mach_set_rtc_mmss(nowtime);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#else
|
||||
extern void native_time_init_hook(void);
|
||||
|
||||
static inline unsigned long native_get_wallclock(void)
|
||||
{
|
||||
return mach_get_cmos_time();
|
||||
}
|
||||
|
||||
static inline int native_set_wallclock(unsigned long nowtime)
|
||||
{
|
||||
return mach_set_rtc_mmss(nowtime);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern void time_init(void);
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
#include <asm/paravirt.h>
|
||||
#else /* !CONFIG_PARAVIRT */
|
||||
|
||||
#define get_wallclock() native_get_wallclock()
|
||||
#define set_wallclock(x) native_set_wallclock(x)
|
||||
#define choose_time_init() hpet_time_init
|
||||
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
|
||||
extern unsigned long __init calibrate_cpu(void);
|
||||
|
||||
#endif /* _ASM_X86_TIME_H */
|
||||
|
@ -8,20 +8,16 @@
|
||||
#define TICK_SIZE (tick_nsec / 1000)
|
||||
|
||||
unsigned long long native_sched_clock(void);
|
||||
unsigned long native_calibrate_tsc(void);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
extern int timer_ack;
|
||||
extern irqreturn_t timer_interrupt(int irq, void *dev_id);
|
||||
#endif /* CONFIG_X86_32 */
|
||||
extern int recalibrate_cpu_khz(void);
|
||||
|
||||
extern int no_timer_check;
|
||||
|
||||
#ifndef CONFIG_PARAVIRT
|
||||
#define calibrate_tsc() native_calibrate_tsc()
|
||||
#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
|
||||
extern int timer_ack;
|
||||
#else
|
||||
# define timer_ack (0)
|
||||
#endif
|
||||
|
||||
extern int no_timer_check;
|
||||
|
||||
/* Accelerators for sched_clock()
|
||||
* convert from cycles(64bits) => nanoseconds (64bits)
|
||||
* basic equation:
|
||||
|
@ -48,7 +48,8 @@ static __always_inline cycles_t vget_cycles(void)
|
||||
extern void tsc_init(void);
|
||||
extern void mark_tsc_unstable(char *reason);
|
||||
extern int unsynchronized_tsc(void);
|
||||
int check_tsc_unstable(void);
|
||||
extern int check_tsc_unstable(void);
|
||||
extern unsigned long native_calibrate_tsc(void);
|
||||
|
||||
/*
|
||||
* Boot-time check whether the TSCs are synchronized across
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef ASM_X86__VMWARE_H
|
||||
#define ASM_X86__VMWARE_H
|
||||
|
||||
extern unsigned long vmware_get_tsc_khz(void);
|
||||
extern void vmware_platform_setup(void);
|
||||
extern int vmware_platform(void);
|
||||
extern void vmware_set_feature_bits(struct cpuinfo_x86 *c);
|
||||
|
||||
|
133
arch/x86/include/asm/x86_init.h
Normal file
133
arch/x86/include/asm/x86_init.h
Normal file
@ -0,0 +1,133 @@
|
||||
#ifndef _ASM_X86_PLATFORM_H
|
||||
#define _ASM_X86_PLATFORM_H
|
||||
|
||||
#include <asm/pgtable_types.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
||||
struct mpc_bus;
|
||||
struct mpc_cpu;
|
||||
struct mpc_table;
|
||||
|
||||
/**
|
||||
* struct x86_init_mpparse - platform specific mpparse ops
|
||||
* @mpc_record: platform specific mpc record accounting
|
||||
* @setup_ioapic_ids: platform specific ioapic id override
|
||||
* @mpc_apic_id: platform specific mpc apic id assignment
|
||||
* @smp_read_mpc_oem: platform specific oem mpc table setup
|
||||
* @mpc_oem_pci_bus: platform specific pci bus setup (default NULL)
|
||||
* @mpc_oem_bus_info: platform specific mpc bus info
|
||||
* @find_smp_config: find the smp configuration
|
||||
* @get_smp_config: get the smp configuration
|
||||
*/
|
||||
struct x86_init_mpparse {
|
||||
void (*mpc_record)(unsigned int mode);
|
||||
void (*setup_ioapic_ids)(void);
|
||||
int (*mpc_apic_id)(struct mpc_cpu *m);
|
||||
void (*smp_read_mpc_oem)(struct mpc_table *mpc);
|
||||
void (*mpc_oem_pci_bus)(struct mpc_bus *m);
|
||||
void (*mpc_oem_bus_info)(struct mpc_bus *m, char *name);
|
||||
void (*find_smp_config)(unsigned int reserve);
|
||||
void (*get_smp_config)(unsigned int early);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_resources - platform specific resource related ops
|
||||
* @probe_roms: probe BIOS roms
|
||||
* @reserve_resources: reserve the standard resources for the
|
||||
* platform
|
||||
* @memory_setup: platform specific memory setup
|
||||
*
|
||||
*/
|
||||
struct x86_init_resources {
|
||||
void (*probe_roms)(void);
|
||||
void (*reserve_resources)(void);
|
||||
char *(*memory_setup)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_irqs - platform specific interrupt setup
|
||||
* @pre_vector_init: init code to run before interrupt vectors
|
||||
* are set up.
|
||||
* @intr_init: interrupt init code
|
||||
* @trap_init: platform specific trap setup
|
||||
*/
|
||||
struct x86_init_irqs {
|
||||
void (*pre_vector_init)(void);
|
||||
void (*intr_init)(void);
|
||||
void (*trap_init)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_oem - oem platform specific customizing functions
|
||||
* @arch_setup: platform specific architecure setup
|
||||
* @banner: print a platform specific banner
|
||||
*/
|
||||
struct x86_init_oem {
|
||||
void (*arch_setup)(void);
|
||||
void (*banner)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_paging - platform specific paging functions
|
||||
* @pagetable_setup_start: platform specific pre paging_init() call
|
||||
* @pagetable_setup_done: platform specific post paging_init() call
|
||||
*/
|
||||
struct x86_init_paging {
|
||||
void (*pagetable_setup_start)(pgd_t *base);
|
||||
void (*pagetable_setup_done)(pgd_t *base);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_timers - platform specific timer setup
|
||||
* @setup_perpcu_clockev: set up the per cpu clock event device for the
|
||||
* boot cpu
|
||||
* @tsc_pre_init: platform function called before TSC init
|
||||
* @timer_init: initialize the platform timer (default PIT/HPET)
|
||||
*/
|
||||
struct x86_init_timers {
|
||||
void (*setup_percpu_clockev)(void);
|
||||
void (*tsc_pre_init)(void);
|
||||
void (*timer_init)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_ops - functions for platform specific setup
|
||||
*
|
||||
*/
|
||||
struct x86_init_ops {
|
||||
struct x86_init_resources resources;
|
||||
struct x86_init_mpparse mpparse;
|
||||
struct x86_init_irqs irqs;
|
||||
struct x86_init_oem oem;
|
||||
struct x86_init_paging paging;
|
||||
struct x86_init_timers timers;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_cpuinit_ops - platform specific cpu hotplug setups
|
||||
* @setup_percpu_clockev: set up the per cpu clock event device
|
||||
*/
|
||||
struct x86_cpuinit_ops {
|
||||
void (*setup_percpu_clockev)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_platform_ops - platform specific runtime functions
|
||||
* @calibrate_tsc: calibrate TSC
|
||||
* @get_wallclock: get time from HW clock like RTC etc.
|
||||
* @set_wallclock: set time back to HW clock
|
||||
*/
|
||||
struct x86_platform_ops {
|
||||
unsigned long (*calibrate_tsc)(void);
|
||||
unsigned long (*get_wallclock)(void);
|
||||
int (*set_wallclock)(unsigned long nowtime);
|
||||
};
|
||||
|
||||
extern struct x86_init_ops x86_init;
|
||||
extern struct x86_cpuinit_ops x86_cpuinit;
|
||||
extern struct x86_platform_ops x86_platform;
|
||||
|
||||
extern void x86_init_noop(void);
|
||||
extern void x86_init_uint_noop(unsigned int unused);
|
||||
|
||||
#endif
|
@ -31,8 +31,8 @@ GCOV_PROFILE_paravirt.o := n
|
||||
|
||||
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
|
||||
obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
|
||||
obj-y += time_$(BITS).o ioport.o ldt.o dumpstack.o
|
||||
obj-y += setup.o i8259.o irqinit.o
|
||||
obj-y += time.o ioport.o ldt.o dumpstack.o
|
||||
obj-y += setup.o x86_init.o i8259.o irqinit.o
|
||||
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
|
||||
obj-$(CONFIG_X86_32) += probe_roms_32.o
|
||||
obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
|
||||
@ -105,6 +105,7 @@ obj-$(CONFIG_SCx200) += scx200.o
|
||||
scx200-y += scx200_32.o
|
||||
|
||||
obj-$(CONFIG_OLPC) += olpc.o
|
||||
obj-$(CONFIG_X86_MRST) += mrst.o
|
||||
|
||||
microcode-y := microcode_core.o
|
||||
microcode-$(CONFIG_MICROCODE_INTEL) += microcode_intel.o
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <linux/mm.h>
|
||||
|
||||
#include <asm/perf_counter.h>
|
||||
#include <asm/x86_init.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/atomic.h>
|
||||
#include <asm/mpspec.h>
|
||||
@ -1709,7 +1710,7 @@ int __init APIC_init_uniprocessor(void)
|
||||
localise_nmi_watchdog();
|
||||
#endif
|
||||
|
||||
setup_boot_clock();
|
||||
x86_init.timers.setup_percpu_clockev();
|
||||
#ifdef CONFIG_X86_64
|
||||
check_nmi_watchdog();
|
||||
#endif
|
||||
|
@ -112,7 +112,7 @@ static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map)
|
||||
return physids_promote(0xFFL);
|
||||
}
|
||||
|
||||
static int bigsmp_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||
static int bigsmp_check_phys_apicid_present(int phys_apicid)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -96,6 +96,11 @@ struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
|
||||
/* # of MP IRQ source entries */
|
||||
int mp_irq_entries;
|
||||
|
||||
/* Number of legacy interrupts */
|
||||
static int nr_legacy_irqs __read_mostly = NR_IRQS_LEGACY;
|
||||
/* GSI interrupts */
|
||||
static int nr_irqs_gsi = NR_IRQS_LEGACY;
|
||||
|
||||
#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
|
||||
int mp_bus_id_to_type[MAX_MP_BUSSES];
|
||||
#endif
|
||||
@ -173,6 +178,12 @@ static struct irq_cfg irq_cfgx[NR_IRQS] = {
|
||||
[15] = { .vector = IRQ15_VECTOR, },
|
||||
};
|
||||
|
||||
void __init io_apic_disable_legacy(void)
|
||||
{
|
||||
nr_legacy_irqs = 0;
|
||||
nr_irqs_gsi = 0;
|
||||
}
|
||||
|
||||
int __init arch_early_irq_init(void)
|
||||
{
|
||||
struct irq_cfg *cfg;
|
||||
@ -190,7 +201,7 @@ int __init arch_early_irq_init(void)
|
||||
desc->chip_data = &cfg[i];
|
||||
zalloc_cpumask_var_node(&cfg[i].domain, GFP_NOWAIT, node);
|
||||
zalloc_cpumask_var_node(&cfg[i].old_domain, GFP_NOWAIT, node);
|
||||
if (i < NR_IRQS_LEGACY)
|
||||
if (i < nr_legacy_irqs)
|
||||
cpumask_setall(cfg[i].domain);
|
||||
}
|
||||
|
||||
@ -867,7 +878,7 @@ static int __init find_isa_irq_apic(int irq, int type)
|
||||
*/
|
||||
static int EISA_ELCR(unsigned int irq)
|
||||
{
|
||||
if (irq < NR_IRQS_LEGACY) {
|
||||
if (irq < nr_legacy_irqs) {
|
||||
unsigned int port = 0x4d0 + (irq >> 3);
|
||||
return (inb(port) >> (irq & 7)) & 1;
|
||||
}
|
||||
@ -1464,7 +1475,7 @@ static void setup_IO_APIC_irq(int apic_id, int pin, unsigned int irq, struct irq
|
||||
}
|
||||
|
||||
ioapic_register_intr(irq, desc, trigger);
|
||||
if (irq < NR_IRQS_LEGACY)
|
||||
if (irq < nr_legacy_irqs)
|
||||
disable_8259A_irq(irq);
|
||||
|
||||
ioapic_write_entry(apic_id, pin, entry);
|
||||
@ -1831,7 +1842,7 @@ __apicdebuginit(void) print_PIC(void)
|
||||
unsigned int v;
|
||||
unsigned long flags;
|
||||
|
||||
if (apic_verbosity == APIC_QUIET)
|
||||
if (apic_verbosity == APIC_QUIET || !nr_legacy_irqs)
|
||||
return;
|
||||
|
||||
printk(KERN_DEBUG "\nprinting PIC contents\n");
|
||||
@ -1894,6 +1905,10 @@ void __init enable_IO_APIC(void)
|
||||
spin_unlock_irqrestore(&ioapic_lock, flags);
|
||||
nr_ioapic_registers[apic] = reg_01.bits.entries+1;
|
||||
}
|
||||
|
||||
if (!nr_legacy_irqs)
|
||||
return;
|
||||
|
||||
for(apic = 0; apic < nr_ioapics; apic++) {
|
||||
int pin;
|
||||
/* See if any of the pins is in ExtINT mode */
|
||||
@ -1948,6 +1963,9 @@ void disable_IO_APIC(void)
|
||||
*/
|
||||
clear_IO_APIC();
|
||||
|
||||
if (!nr_legacy_irqs)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If the i8259 is routed through an IOAPIC
|
||||
* Put that IOAPIC in virtual wire mode
|
||||
@ -1994,7 +2012,7 @@ void disable_IO_APIC(void)
|
||||
* by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
|
||||
*/
|
||||
|
||||
static void __init setup_ioapic_ids_from_mpc(void)
|
||||
void __init setup_ioapic_ids_from_mpc(void)
|
||||
{
|
||||
union IO_APIC_reg_00 reg_00;
|
||||
physid_mask_t phys_id_present_map;
|
||||
@ -2003,9 +2021,8 @@ static void __init setup_ioapic_ids_from_mpc(void)
|
||||
unsigned char old_id;
|
||||
unsigned long flags;
|
||||
|
||||
if (x86_quirks->setup_ioapic_ids && x86_quirks->setup_ioapic_ids())
|
||||
if (acpi_ioapic)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Don't check I/O APIC IDs for xAPIC systems. They have
|
||||
* no meaning without the serial APIC bus.
|
||||
@ -2179,7 +2196,7 @@ static unsigned int startup_ioapic_irq(unsigned int irq)
|
||||
struct irq_cfg *cfg;
|
||||
|
||||
spin_lock_irqsave(&ioapic_lock, flags);
|
||||
if (irq < NR_IRQS_LEGACY) {
|
||||
if (irq < nr_legacy_irqs) {
|
||||
disable_8259A_irq(irq);
|
||||
if (i8259A_irq_pending(irq))
|
||||
was_pending = 1;
|
||||
@ -2657,7 +2674,7 @@ static inline void init_IO_APIC_traps(void)
|
||||
* so default to an old-fashioned 8259
|
||||
* interrupt if we can..
|
||||
*/
|
||||
if (irq < NR_IRQS_LEGACY)
|
||||
if (irq < nr_legacy_irqs)
|
||||
make_8259A_irq(irq);
|
||||
else
|
||||
/* Strange. Oh, well.. */
|
||||
@ -2993,7 +3010,7 @@ out:
|
||||
* the I/O APIC in all cases now. No actual device should request
|
||||
* it anyway. --macro
|
||||
*/
|
||||
#define PIC_IRQS (1 << PIC_CASCADE_IR)
|
||||
#define PIC_IRQS (1UL << PIC_CASCADE_IR)
|
||||
|
||||
void __init setup_IO_APIC(void)
|
||||
{
|
||||
@ -3001,21 +3018,19 @@ void __init setup_IO_APIC(void)
|
||||
/*
|
||||
* calling enable_IO_APIC() is moved to setup_local_APIC for BP
|
||||
*/
|
||||
|
||||
io_apic_irqs = ~PIC_IRQS;
|
||||
io_apic_irqs = nr_legacy_irqs ? ~PIC_IRQS : ~0UL;
|
||||
|
||||
apic_printk(APIC_VERBOSE, "ENABLING IO-APIC IRQs\n");
|
||||
/*
|
||||
* Set up IO-APIC IRQ routing.
|
||||
*/
|
||||
#ifdef CONFIG_X86_32
|
||||
if (!acpi_ioapic)
|
||||
setup_ioapic_ids_from_mpc();
|
||||
#endif
|
||||
x86_init.mpparse.setup_ioapic_ids();
|
||||
|
||||
sync_Arb_IDs();
|
||||
setup_IO_APIC_irqs();
|
||||
init_IO_APIC_traps();
|
||||
check_timer();
|
||||
if (nr_legacy_irqs)
|
||||
check_timer();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3116,7 +3131,6 @@ static int __init ioapic_init_sysfs(void)
|
||||
|
||||
device_initcall(ioapic_init_sysfs);
|
||||
|
||||
static int nr_irqs_gsi = NR_IRQS_LEGACY;
|
||||
/*
|
||||
* Dynamic irq allocate and deallocation
|
||||
*/
|
||||
@ -3856,7 +3870,7 @@ static int __io_apic_set_pci_routing(struct device *dev, int irq,
|
||||
/*
|
||||
* IRQs < 16 are already in the irq_2_pin[] map
|
||||
*/
|
||||
if (irq >= NR_IRQS_LEGACY) {
|
||||
if (irq >= nr_legacy_irqs) {
|
||||
cfg = desc->chip_data;
|
||||
if (add_pin_to_irq_node_nopanic(cfg, node, ioapic, pin)) {
|
||||
printk(KERN_INFO "can not add pin %d for irq %d\n",
|
||||
|
@ -66,7 +66,6 @@ struct mpc_trans {
|
||||
unsigned short trans_reserved;
|
||||
};
|
||||
|
||||
/* x86_quirks member */
|
||||
static int mpc_record;
|
||||
|
||||
static struct mpc_trans *translation_table[MAX_MPC_ENTRY];
|
||||
@ -130,10 +129,9 @@ void __cpuinit numaq_tsc_disable(void)
|
||||
}
|
||||
}
|
||||
|
||||
static int __init numaq_pre_time_init(void)
|
||||
static void __init numaq_tsc_init(void)
|
||||
{
|
||||
numaq_tsc_disable();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int generate_logical_apicid(int quad, int phys_apicid)
|
||||
@ -177,6 +175,19 @@ static void mpc_oem_pci_bus(struct mpc_bus *m)
|
||||
quad_local_to_mp_bus_id[quad][local] = m->busid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from mpparse code.
|
||||
* mode = 0: prescan
|
||||
* mode = 1: one mpc entry scanned
|
||||
*/
|
||||
static void numaq_mpc_record(unsigned int mode)
|
||||
{
|
||||
if (!mode)
|
||||
mpc_record = 0;
|
||||
else
|
||||
mpc_record++;
|
||||
}
|
||||
|
||||
static void __init MP_translation_info(struct mpc_trans *m)
|
||||
{
|
||||
printk(KERN_INFO
|
||||
@ -206,9 +217,9 @@ static int __init mpf_checksum(unsigned char *mp, int len)
|
||||
/*
|
||||
* Read/parse the MPC oem tables
|
||||
*/
|
||||
static void __init
|
||||
smp_read_mpc_oem(struct mpc_oemtable *oemtable, unsigned short oemsize)
|
||||
static void __init smp_read_mpc_oem(struct mpc_table *mpc)
|
||||
{
|
||||
struct mpc_oemtable *oemtable = (void *)(long)mpc->oemptr;
|
||||
int count = sizeof(*oemtable); /* the header size */
|
||||
unsigned char *oemptr = ((unsigned char *)oemtable) + count;
|
||||
|
||||
@ -250,29 +261,6 @@ static void __init
|
||||
}
|
||||
}
|
||||
|
||||
static int __init numaq_setup_ioapic_ids(void)
|
||||
{
|
||||
/* so can skip it */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct x86_quirks numaq_x86_quirks __initdata = {
|
||||
.arch_pre_time_init = numaq_pre_time_init,
|
||||
.arch_time_init = NULL,
|
||||
.arch_pre_intr_init = NULL,
|
||||
.arch_memory_setup = NULL,
|
||||
.arch_intr_init = NULL,
|
||||
.arch_trap_init = NULL,
|
||||
.mach_get_smp_config = NULL,
|
||||
.mach_find_smp_config = NULL,
|
||||
.mpc_record = &mpc_record,
|
||||
.mpc_apic_id = mpc_apic_id,
|
||||
.mpc_oem_bus_info = mpc_oem_bus_info,
|
||||
.mpc_oem_pci_bus = mpc_oem_pci_bus,
|
||||
.smp_read_mpc_oem = smp_read_mpc_oem,
|
||||
.setup_ioapic_ids = numaq_setup_ioapic_ids,
|
||||
};
|
||||
|
||||
static __init void early_check_numaq(void)
|
||||
{
|
||||
/*
|
||||
@ -286,8 +274,15 @@ static __init void early_check_numaq(void)
|
||||
if (smp_found_config)
|
||||
early_get_smp_config();
|
||||
|
||||
if (found_numaq)
|
||||
x86_quirks = &numaq_x86_quirks;
|
||||
if (found_numaq) {
|
||||
x86_init.mpparse.mpc_record = numaq_mpc_record;
|
||||
x86_init.mpparse.setup_ioapic_ids = x86_init_noop;
|
||||
x86_init.mpparse.mpc_apic_id = mpc_apic_id;
|
||||
x86_init.mpparse.smp_read_mpc_oem = smp_read_mpc_oem;
|
||||
x86_init.mpparse.mpc_oem_pci_bus = mpc_oem_pci_bus;
|
||||
x86_init.mpparse.mpc_oem_bus_info = mpc_oem_bus_info;
|
||||
x86_init.timers.tsc_pre_init = numaq_tsc_init;
|
||||
}
|
||||
}
|
||||
|
||||
int __init get_memcfg_numaq(void)
|
||||
@ -418,7 +413,7 @@ static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid)
|
||||
/* Where the IO area was mapped on multiquad, always 0 otherwise */
|
||||
void *xquad_portio;
|
||||
|
||||
static inline int numaq_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||
static inline int numaq_check_phys_apicid_present(int phys_apicid)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -272,7 +272,7 @@ static physid_mask_t summit_apicid_to_cpu_present(int apicid)
|
||||
return physid_mask_of_physid(0);
|
||||
}
|
||||
|
||||
static int summit_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||
static int summit_check_phys_apicid_present(int physical_apicid)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
@ -34,13 +34,6 @@ detect_hypervisor_vendor(struct cpuinfo_x86 *c)
|
||||
c->x86_hyper_vendor = X86_HYPER_VENDOR_NONE;
|
||||
}
|
||||
|
||||
unsigned long get_hypervisor_tsc_freq(void)
|
||||
{
|
||||
if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
|
||||
return vmware_get_tsc_khz();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void __cpuinit
|
||||
hypervisor_set_feature_bits(struct cpuinfo_x86 *c)
|
||||
{
|
||||
@ -55,3 +48,10 @@ void __cpuinit init_hypervisor(struct cpuinfo_x86 *c)
|
||||
detect_hypervisor_vendor(c);
|
||||
hypervisor_set_feature_bits(c);
|
||||
}
|
||||
|
||||
void __init init_hypervisor_platform(void)
|
||||
{
|
||||
init_hypervisor(&boot_cpu_data);
|
||||
if (boot_cpu_data.x86_hyper_vendor == X86_HYPER_VENDOR_VMWARE)
|
||||
vmware_platform_setup();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/dmi.h>
|
||||
#include <asm/div64.h>
|
||||
#include <asm/vmware.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
#define CPUID_VMWARE_INFO_LEAF 0x40000000
|
||||
#define VMWARE_HYPERVISOR_MAGIC 0x564D5868
|
||||
@ -47,21 +48,29 @@ static inline int __vmware_platform(void)
|
||||
return eax != (uint32_t)-1 && ebx == VMWARE_HYPERVISOR_MAGIC;
|
||||
}
|
||||
|
||||
static unsigned long __vmware_get_tsc_khz(void)
|
||||
static unsigned long vmware_get_tsc_khz(void)
|
||||
{
|
||||
uint64_t tsc_hz;
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
|
||||
|
||||
if (ebx == UINT_MAX)
|
||||
return 0;
|
||||
tsc_hz = eax | (((uint64_t)ebx) << 32);
|
||||
do_div(tsc_hz, 1000);
|
||||
BUG_ON(tsc_hz >> 32);
|
||||
return tsc_hz;
|
||||
}
|
||||
|
||||
void __init vmware_platform_setup(void)
|
||||
{
|
||||
uint32_t eax, ebx, ecx, edx;
|
||||
|
||||
VMWARE_PORT(GETHZ, eax, ebx, ecx, edx);
|
||||
|
||||
if (ebx != UINT_MAX)
|
||||
x86_platform.calibrate_tsc = vmware_get_tsc_khz;
|
||||
}
|
||||
|
||||
/*
|
||||
* While checking the dmi string infomation, just checking the product
|
||||
* serial key should be enough, as this will always have a VMware
|
||||
@ -87,12 +96,6 @@ int vmware_platform(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned long vmware_get_tsc_khz(void)
|
||||
{
|
||||
BUG_ON(!vmware_platform());
|
||||
return __vmware_get_tsc_khz();
|
||||
}
|
||||
|
||||
/*
|
||||
* VMware hypervisor takes care of exporting a reliable TSC to the guest.
|
||||
* Still, due to timing difference when running on virtual cpus, the TSC can
|
||||
|
@ -1455,28 +1455,11 @@ char *__init default_machine_specific_memory_setup(void)
|
||||
return who;
|
||||
}
|
||||
|
||||
char *__init __attribute__((weak)) machine_specific_memory_setup(void)
|
||||
{
|
||||
if (x86_quirks->arch_memory_setup) {
|
||||
char *who = x86_quirks->arch_memory_setup();
|
||||
|
||||
if (who)
|
||||
return who;
|
||||
}
|
||||
return default_machine_specific_memory_setup();
|
||||
}
|
||||
|
||||
/* Overridden in paravirt.c if CONFIG_PARAVIRT */
|
||||
char * __init __attribute__((weak)) memory_setup(void)
|
||||
{
|
||||
return machine_specific_memory_setup();
|
||||
}
|
||||
|
||||
void __init setup_memory_map(void)
|
||||
{
|
||||
char *who;
|
||||
|
||||
who = memory_setup();
|
||||
who = x86_init.resources.memory_setup();
|
||||
memcpy(&e820_saved, &e820, sizeof(struct e820map));
|
||||
printk(KERN_INFO "BIOS-provided physical RAM map:\n");
|
||||
e820_print_map(who);
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
#define EFI_DEBUG 1
|
||||
#define PFX "EFI: "
|
||||
@ -453,6 +454,9 @@ void __init efi_init(void)
|
||||
if (add_efi_memmap)
|
||||
do_add_efi_memmap();
|
||||
|
||||
x86_platform.get_wallclock = efi_get_time;
|
||||
x86_platform.set_wallclock = efi_set_rtc_mmss;
|
||||
|
||||
/* Setup for EFI runtime service */
|
||||
reboot_type = BOOT_EFI;
|
||||
|
||||
|
@ -11,8 +11,21 @@
|
||||
#include <asm/setup.h>
|
||||
#include <asm/sections.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/bios_ebda.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/trampoline.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/io_apic.h>
|
||||
#include <asm/bios_ebda.h>
|
||||
|
||||
static void __init i386_default_early_setup(void)
|
||||
{
|
||||
/* Initilize 32bit specific setup functions */
|
||||
x86_init.resources.probe_roms = probe_roms;
|
||||
x86_init.resources.reserve_resources = i386_reserve_resources;
|
||||
x86_init.mpparse.setup_ioapic_ids = setup_ioapic_ids_from_mpc;
|
||||
|
||||
reserve_ebda_region();
|
||||
}
|
||||
|
||||
void __init i386_start_kernel(void)
|
||||
{
|
||||
@ -29,7 +42,16 @@ void __init i386_start_kernel(void)
|
||||
reserve_early(ramdisk_image, ramdisk_end, "RAMDISK");
|
||||
}
|
||||
#endif
|
||||
reserve_ebda_region();
|
||||
|
||||
/* Call the subarch specific early setup function */
|
||||
switch (boot_params.hdr.hardware_subarch) {
|
||||
case X86_SUBARCH_MRST:
|
||||
x86_mrst_early_setup();
|
||||
break;
|
||||
default:
|
||||
i386_default_early_setup();
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* At this point everything still needed from the boot loader
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include <asm/sections.h>
|
||||
#include <asm/kdebug.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/bios_ebda.h>
|
||||
#include <asm/trampoline.h>
|
||||
#include <asm/bios_ebda.h>
|
||||
|
||||
static void __init zap_identity_mappings(void)
|
||||
{
|
||||
|
@ -157,6 +157,7 @@ subarch_entries:
|
||||
.long default_entry /* normal x86/PC */
|
||||
.long lguest_entry /* lguest hypervisor */
|
||||
.long xen_entry /* Xen hypervisor */
|
||||
.long default_entry /* Moorestown MID */
|
||||
num_subarch_entries = (. - subarch_entries) / 4
|
||||
.previous
|
||||
#endif /* CONFIG_PARAVIRT */
|
||||
|
@ -116,7 +116,7 @@ int vector_used_by_percpu_irq(unsigned int vector)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init init_ISA_irqs(void)
|
||||
void __init init_ISA_irqs(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -140,8 +140,10 @@ static void __init init_ISA_irqs(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Overridden in paravirt.c */
|
||||
void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
|
||||
void __init init_IRQ(void)
|
||||
{
|
||||
x86_init.irqs.intr_init();
|
||||
}
|
||||
|
||||
static void __init smp_intr_init(void)
|
||||
{
|
||||
@ -213,32 +215,12 @@ static void __init apic_intr_init(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors
|
||||
*
|
||||
* Description:
|
||||
* Perform any necessary interrupt initialisation prior to setting up
|
||||
* the "ordinary" interrupt call gates. For legacy reasons, the ISA
|
||||
* interrupts should be initialised here if the machine emulates a PC
|
||||
* in any way.
|
||||
**/
|
||||
static void __init x86_quirk_pre_intr_init(void)
|
||||
{
|
||||
#ifdef CONFIG_X86_32
|
||||
if (x86_quirks->arch_pre_intr_init) {
|
||||
if (x86_quirks->arch_pre_intr_init())
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
init_ISA_irqs();
|
||||
}
|
||||
|
||||
void __init native_init_IRQ(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Execute any quirks before the call gates are initialised: */
|
||||
x86_quirk_pre_intr_init();
|
||||
x86_init.irqs.pre_vector_init();
|
||||
|
||||
apic_intr_init();
|
||||
|
||||
@ -257,12 +239,6 @@ void __init native_init_IRQ(void)
|
||||
setup_irq(2, &irq2);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
/*
|
||||
* Call quirks after call gates are initialised (usually add in
|
||||
* the architecture specific gates):
|
||||
*/
|
||||
x86_quirk_intr_init();
|
||||
|
||||
/*
|
||||
* External FPU? Set up irq13 if so, for
|
||||
* original braindamaged IBM FERR coupling.
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <asm/msr.h>
|
||||
#include <asm/apic.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include <asm/x86_init.h>
|
||||
#include <asm/reboot.h>
|
||||
|
||||
#define KVM_SCALE 22
|
||||
@ -182,12 +184,13 @@ void __init kvmclock_init(void)
|
||||
if (kvmclock && kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE)) {
|
||||
if (kvm_register_clock("boot clock"))
|
||||
return;
|
||||
pv_time_ops.get_wallclock = kvm_get_wallclock;
|
||||
pv_time_ops.set_wallclock = kvm_set_wallclock;
|
||||
pv_time_ops.sched_clock = kvm_clock_read;
|
||||
pv_time_ops.get_tsc_khz = kvm_get_tsc_khz;
|
||||
x86_platform.calibrate_tsc = kvm_get_tsc_khz;
|
||||
x86_platform.get_wallclock = kvm_get_wallclock;
|
||||
x86_platform.set_wallclock = kvm_set_wallclock;
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
pv_apic_ops.setup_secondary_clock = kvm_setup_secondary_clock;
|
||||
x86_cpuinit.setup_percpu_clockev =
|
||||
kvm_setup_secondary_clock;
|
||||
#endif
|
||||
#ifdef CONFIG_SMP
|
||||
smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
|
||||
|
@ -45,6 +45,11 @@ static int __init mpf_checksum(unsigned char *mp, int len)
|
||||
return sum & 0xFF;
|
||||
}
|
||||
|
||||
int __init default_mpc_apic_id(struct mpc_cpu *m)
|
||||
{
|
||||
return m->apicid;
|
||||
}
|
||||
|
||||
static void __init MP_processor_info(struct mpc_cpu *m)
|
||||
{
|
||||
int apicid;
|
||||
@ -55,10 +60,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
|
||||
return;
|
||||
}
|
||||
|
||||
if (x86_quirks->mpc_apic_id)
|
||||
apicid = x86_quirks->mpc_apic_id(m);
|
||||
else
|
||||
apicid = m->apicid;
|
||||
apicid = x86_init.mpparse.mpc_apic_id(m);
|
||||
|
||||
if (m->cpuflag & CPU_BOOTPROCESSOR) {
|
||||
bootup_cpu = " (Bootup-CPU)";
|
||||
@ -70,16 +72,18 @@ static void __init MP_processor_info(struct mpc_cpu *m)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
void __init default_mpc_oem_bus_info(struct mpc_bus *m, char *str)
|
||||
{
|
||||
memcpy(str, m->bustype, 6);
|
||||
str[6] = 0;
|
||||
apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
|
||||
}
|
||||
|
||||
static void __init MP_bus_info(struct mpc_bus *m)
|
||||
{
|
||||
char str[7];
|
||||
memcpy(str, m->bustype, 6);
|
||||
str[6] = 0;
|
||||
|
||||
if (x86_quirks->mpc_oem_bus_info)
|
||||
x86_quirks->mpc_oem_bus_info(m, str);
|
||||
else
|
||||
apic_printk(APIC_VERBOSE, "Bus #%d is %s\n", m->busid, str);
|
||||
x86_init.mpparse.mpc_oem_bus_info(m, str);
|
||||
|
||||
#if MAX_MP_BUSSES < 256
|
||||
if (m->busid >= MAX_MP_BUSSES) {
|
||||
@ -96,8 +100,8 @@ static void __init MP_bus_info(struct mpc_bus *m)
|
||||
mp_bus_id_to_type[m->busid] = MP_BUS_ISA;
|
||||
#endif
|
||||
} else if (strncmp(str, BUSTYPE_PCI, sizeof(BUSTYPE_PCI) - 1) == 0) {
|
||||
if (x86_quirks->mpc_oem_pci_bus)
|
||||
x86_quirks->mpc_oem_pci_bus(m);
|
||||
if (x86_init.mpparse.mpc_oem_pci_bus)
|
||||
x86_init.mpparse.mpc_oem_pci_bus(m);
|
||||
|
||||
clear_bit(m->busid, mp_bus_not_pci);
|
||||
#if defined(CONFIG_EISA) || defined(CONFIG_MCA)
|
||||
@ -291,6 +295,8 @@ static void __init smp_dump_mptable(struct mpc_table *mpc, unsigned char *mpt)
|
||||
1, mpc, mpc->length, 1);
|
||||
}
|
||||
|
||||
void __init default_smp_read_mpc_oem(struct mpc_table *mpc) { }
|
||||
|
||||
static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
|
||||
{
|
||||
char str[16];
|
||||
@ -312,16 +318,13 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
|
||||
if (early)
|
||||
return 1;
|
||||
|
||||
if (mpc->oemptr && x86_quirks->smp_read_mpc_oem) {
|
||||
struct mpc_oemtable *oem_table = (void *)(long)mpc->oemptr;
|
||||
x86_quirks->smp_read_mpc_oem(oem_table, mpc->oemsize);
|
||||
}
|
||||
if (mpc->oemptr)
|
||||
x86_init.mpparse.smp_read_mpc_oem(mpc);
|
||||
|
||||
/*
|
||||
* Now process the configuration blocks.
|
||||
*/
|
||||
if (x86_quirks->mpc_record)
|
||||
*x86_quirks->mpc_record = 0;
|
||||
x86_init.mpparse.mpc_record(0);
|
||||
|
||||
while (count < mpc->length) {
|
||||
switch (*mpt) {
|
||||
@ -353,8 +356,7 @@ static int __init smp_read_mpc(struct mpc_table *mpc, unsigned early)
|
||||
count = mpc->length;
|
||||
break;
|
||||
}
|
||||
if (x86_quirks->mpc_record)
|
||||
(*x86_quirks->mpc_record)++;
|
||||
x86_init.mpparse.mpc_record(1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_BIGSMP
|
||||
@ -608,7 +610,7 @@ static int __init check_physptr(struct mpf_intel *mpf, unsigned int early)
|
||||
/*
|
||||
* Scan the memory blocks for an SMP configuration block.
|
||||
*/
|
||||
static void __init __get_smp_config(unsigned int early)
|
||||
void __init default_get_smp_config(unsigned int early)
|
||||
{
|
||||
struct mpf_intel *mpf = mpf_found;
|
||||
|
||||
@ -625,11 +627,6 @@ static void __init __get_smp_config(unsigned int early)
|
||||
if (acpi_lapic && acpi_ioapic)
|
||||
return;
|
||||
|
||||
if (x86_quirks->mach_get_smp_config) {
|
||||
if (x86_quirks->mach_get_smp_config(early))
|
||||
return;
|
||||
}
|
||||
|
||||
printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
|
||||
mpf->specification);
|
||||
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
|
||||
@ -670,16 +667,6 @@ static void __init __get_smp_config(unsigned int early)
|
||||
*/
|
||||
}
|
||||
|
||||
void __init early_get_smp_config(void)
|
||||
{
|
||||
__get_smp_config(1);
|
||||
}
|
||||
|
||||
void __init get_smp_config(void)
|
||||
{
|
||||
__get_smp_config(0);
|
||||
}
|
||||
|
||||
static void __init smp_reserve_bootmem(struct mpf_intel *mpf)
|
||||
{
|
||||
unsigned long size = get_mpc_size(mpf->physptr);
|
||||
@ -745,14 +732,10 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init __find_smp_config(unsigned int reserve)
|
||||
void __init default_find_smp_config(unsigned int reserve)
|
||||
{
|
||||
unsigned int address;
|
||||
|
||||
if (x86_quirks->mach_find_smp_config) {
|
||||
if (x86_quirks->mach_find_smp_config(reserve))
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* FIXME: Linux assumes you have 640K of base ram..
|
||||
* this continues the error...
|
||||
@ -787,16 +770,6 @@ static void __init __find_smp_config(unsigned int reserve)
|
||||
smp_scan_config(address, 0x400, reserve);
|
||||
}
|
||||
|
||||
void __init early_find_smp_config(void)
|
||||
{
|
||||
__find_smp_config(0);
|
||||
}
|
||||
|
||||
void __init find_smp_config(void)
|
||||
{
|
||||
__find_smp_config(1);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
static u8 __initdata irq_used[MAX_IRQ_SOURCES];
|
||||
|
||||
|
24
arch/x86/kernel/mrst.c
Normal file
24
arch/x86/kernel/mrst.c
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* mrst.c: Intel Moorestown platform specific setup code
|
||||
*
|
||||
* (C) Copyright 2008 Intel Corporation
|
||||
* Author: Jacob Pan (jacob.jun.pan@intel.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; version 2
|
||||
* of the License.
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
|
||||
/*
|
||||
* Moorestown specific x86_init function overrides and early setup
|
||||
* calls.
|
||||
*/
|
||||
void __init x86_mrst_early_setup(void)
|
||||
{
|
||||
x86_init.resources.probe_roms = x86_init_noop;
|
||||
x86_init.resources.reserve_resources = x86_init_noop;
|
||||
}
|
@ -54,17 +54,12 @@ u64 _paravirt_ident_64(u64 x)
|
||||
return x;
|
||||
}
|
||||
|
||||
static void __init default_banner(void)
|
||||
void __init default_banner(void)
|
||||
{
|
||||
printk(KERN_INFO "Booting paravirtualized kernel on %s\n",
|
||||
pv_info.name);
|
||||
}
|
||||
|
||||
char *memory_setup(void)
|
||||
{
|
||||
return pv_init_ops.memory_setup();
|
||||
}
|
||||
|
||||
/* Simple instruction patching code. */
|
||||
#define DEF_NATIVE(ops, name, code) \
|
||||
extern const char start_##ops##_##name[], end_##ops##_##name[]; \
|
||||
@ -188,11 +183,6 @@ unsigned paravirt_patch_insns(void *insnbuf, unsigned len,
|
||||
return insn_len;
|
||||
}
|
||||
|
||||
void init_IRQ(void)
|
||||
{
|
||||
pv_irq_ops.init_IRQ();
|
||||
}
|
||||
|
||||
static void native_flush_tlb(void)
|
||||
{
|
||||
__native_flush_tlb();
|
||||
@ -218,13 +208,6 @@ extern void native_irq_enable_sysexit(void);
|
||||
extern void native_usergs_sysret32(void);
|
||||
extern void native_usergs_sysret64(void);
|
||||
|
||||
static int __init print_banner(void)
|
||||
{
|
||||
pv_init_ops.banner();
|
||||
return 0;
|
||||
}
|
||||
core_initcall(print_banner);
|
||||
|
||||
static struct resource reserve_ioports = {
|
||||
.start = 0,
|
||||
.end = IO_SPACE_LIMIT,
|
||||
@ -320,21 +303,13 @@ struct pv_info pv_info = {
|
||||
|
||||
struct pv_init_ops pv_init_ops = {
|
||||
.patch = native_patch,
|
||||
.banner = default_banner,
|
||||
.arch_setup = paravirt_nop,
|
||||
.memory_setup = machine_specific_memory_setup,
|
||||
};
|
||||
|
||||
struct pv_time_ops pv_time_ops = {
|
||||
.time_init = hpet_time_init,
|
||||
.get_wallclock = native_get_wallclock,
|
||||
.set_wallclock = native_set_wallclock,
|
||||
.sched_clock = native_sched_clock,
|
||||
.get_tsc_khz = native_calibrate_tsc,
|
||||
};
|
||||
|
||||
struct pv_irq_ops pv_irq_ops = {
|
||||
.init_IRQ = native_init_IRQ,
|
||||
.save_fl = __PV_IS_CALLEE_SAVE(native_save_fl),
|
||||
.restore_fl = __PV_IS_CALLEE_SAVE(native_restore_fl),
|
||||
.irq_disable = __PV_IS_CALLEE_SAVE(native_irq_disable),
|
||||
@ -409,8 +384,6 @@ struct pv_cpu_ops pv_cpu_ops = {
|
||||
|
||||
struct pv_apic_ops pv_apic_ops = {
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
.setup_boot_clock = setup_boot_APIC_clock,
|
||||
.setup_secondary_clock = setup_secondary_APIC_clock,
|
||||
.startup_ipi_hook = paravirt_nop,
|
||||
#endif
|
||||
};
|
||||
@ -424,13 +397,6 @@ struct pv_apic_ops pv_apic_ops = {
|
||||
#endif
|
||||
|
||||
struct pv_mmu_ops pv_mmu_ops = {
|
||||
#ifndef CONFIG_X86_64
|
||||
.pagetable_setup_start = native_pagetable_setup_start,
|
||||
.pagetable_setup_done = native_pagetable_setup_done,
|
||||
#else
|
||||
.pagetable_setup_start = paravirt_nop,
|
||||
.pagetable_setup_done = paravirt_nop,
|
||||
#endif
|
||||
|
||||
.read_cr2 = native_read_cr2,
|
||||
.write_cr2 = native_write_cr2,
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <linux/pnp.h>
|
||||
|
||||
#include <asm/vsyscall.h>
|
||||
#include <asm/x86_init.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
@ -165,13 +166,13 @@ void rtc_cmos_write(unsigned char val, unsigned char addr)
|
||||
}
|
||||
EXPORT_SYMBOL(rtc_cmos_write);
|
||||
|
||||
static int set_rtc_mmss(unsigned long nowtime)
|
||||
int update_persistent_clock(struct timespec now)
|
||||
{
|
||||
unsigned long flags;
|
||||
int retval;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
retval = set_wallclock(nowtime);
|
||||
retval = x86_platform.set_wallclock(now.tv_sec);
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
return retval;
|
||||
@ -183,18 +184,13 @@ void read_persistent_clock(struct timespec *ts)
|
||||
unsigned long retval, flags;
|
||||
|
||||
spin_lock_irqsave(&rtc_lock, flags);
|
||||
retval = get_wallclock();
|
||||
retval = x86_platform.get_wallclock();
|
||||
spin_unlock_irqrestore(&rtc_lock, flags);
|
||||
|
||||
ts->tv_sec = retval;
|
||||
ts->tv_nsec = 0;
|
||||
}
|
||||
|
||||
int update_persistent_clock(struct timespec now)
|
||||
{
|
||||
return set_rtc_mmss(now.tv_sec);
|
||||
}
|
||||
|
||||
unsigned long long native_read_tsc(void)
|
||||
{
|
||||
return __native_read_tsc();
|
||||
|
@ -109,10 +109,6 @@
|
||||
#include <asm/numa_64.h>
|
||||
#endif
|
||||
|
||||
#ifndef ARCH_SETUP
|
||||
#define ARCH_SETUP
|
||||
#endif
|
||||
|
||||
/*
|
||||
* end_pfn only includes RAM, while max_pfn_mapped includes all e820 entries.
|
||||
* The direct mapping extends to max_pfn_mapped, so that we can directly access
|
||||
@ -134,9 +130,9 @@ int default_cpu_present_to_apicid(int mps_cpu)
|
||||
return __default_cpu_present_to_apicid(mps_cpu);
|
||||
}
|
||||
|
||||
int default_check_phys_apicid_present(int boot_cpu_physical_apicid)
|
||||
int default_check_phys_apicid_present(int phys_apicid)
|
||||
{
|
||||
return __default_check_phys_apicid_present(boot_cpu_physical_apicid);
|
||||
return __default_check_phys_apicid_present(phys_apicid);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -172,13 +168,6 @@ static struct resource bss_resource = {
|
||||
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
static struct resource video_ram_resource = {
|
||||
.name = "Video RAM area",
|
||||
.start = 0xa0000,
|
||||
.end = 0xbffff,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
|
||||
};
|
||||
|
||||
/* cpu data as detected by the assembly code in head.S */
|
||||
struct cpuinfo_x86 new_cpu_data __cpuinitdata = {0, 0, 0, 0, -1, 1, 0, 0, -1};
|
||||
/* common cpu data for all cpus */
|
||||
@ -606,7 +595,7 @@ static struct resource standard_io_resources[] = {
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_IO }
|
||||
};
|
||||
|
||||
static void __init reserve_standard_io_resources(void)
|
||||
void __init reserve_standard_io_resources(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -638,10 +627,6 @@ static int __init setup_elfcorehdr(char *arg)
|
||||
early_param("elfcorehdr", setup_elfcorehdr);
|
||||
#endif
|
||||
|
||||
static struct x86_quirks default_x86_quirks __initdata;
|
||||
|
||||
struct x86_quirks *x86_quirks __initdata = &default_x86_quirks;
|
||||
|
||||
#ifdef CONFIG_X86_RESERVE_LOW_64K
|
||||
static int __init dmi_low_memory_corruption(const struct dmi_system_id *d)
|
||||
{
|
||||
@ -773,7 +758,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
}
|
||||
#endif
|
||||
|
||||
ARCH_SETUP
|
||||
x86_init.oem.arch_setup();
|
||||
|
||||
setup_memory_map();
|
||||
parse_setup_data();
|
||||
@ -844,11 +829,9 @@ void __init setup_arch(char **cmdline_p)
|
||||
* VMware detection requires dmi to be available, so this
|
||||
* needs to be done after dmi_scan_machine, for the BP.
|
||||
*/
|
||||
init_hypervisor(&boot_cpu_data);
|
||||
init_hypervisor_platform();
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
probe_roms();
|
||||
#endif
|
||||
x86_init.resources.probe_roms();
|
||||
|
||||
/* after parse_early_param, so could debug it */
|
||||
insert_resource(&iomem_resource, &code_resource);
|
||||
@ -983,10 +966,9 @@ void __init setup_arch(char **cmdline_p)
|
||||
kvmclock_init();
|
||||
#endif
|
||||
|
||||
paravirt_pagetable_setup_start(swapper_pg_dir);
|
||||
x86_init.paging.pagetable_setup_start(swapper_pg_dir);
|
||||
paging_init();
|
||||
paravirt_pagetable_setup_done(swapper_pg_dir);
|
||||
paravirt_post_allocator_init();
|
||||
x86_init.paging.pagetable_setup_done(swapper_pg_dir);
|
||||
|
||||
tboot_probe();
|
||||
|
||||
@ -1003,13 +985,11 @@ void __init setup_arch(char **cmdline_p)
|
||||
*/
|
||||
acpi_boot_init();
|
||||
|
||||
#if defined(CONFIG_X86_MPPARSE) || defined(CONFIG_X86_VISWS)
|
||||
/*
|
||||
* get boot-time SMP configuration:
|
||||
*/
|
||||
if (smp_found_config)
|
||||
get_smp_config();
|
||||
#endif
|
||||
|
||||
prefill_possible_map();
|
||||
|
||||
@ -1028,10 +1008,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
e820_reserve_resources();
|
||||
e820_mark_nosave_regions(max_low_pfn);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
request_resource(&iomem_resource, &video_ram_resource);
|
||||
#endif
|
||||
reserve_standard_io_resources();
|
||||
x86_init.resources.reserve_resources();
|
||||
|
||||
e820_setup_gap();
|
||||
|
||||
@ -1043,78 +1020,22 @@ void __init setup_arch(char **cmdline_p)
|
||||
conswitchp = &dummy_con;
|
||||
#endif
|
||||
#endif
|
||||
x86_init.oem.banner();
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
||||
/**
|
||||
* x86_quirk_intr_init - post gate setup interrupt initialisation
|
||||
*
|
||||
* Description:
|
||||
* Fill in any interrupts that may have been left out by the general
|
||||
* init_IRQ() routine. interrupts having to do with the machine rather
|
||||
* than the devices on the I/O bus (like APIC interrupts in intel MP
|
||||
* systems) are started here.
|
||||
**/
|
||||
void __init x86_quirk_intr_init(void)
|
||||
{
|
||||
if (x86_quirks->arch_intr_init) {
|
||||
if (x86_quirks->arch_intr_init())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* x86_quirk_trap_init - initialise system specific traps
|
||||
*
|
||||
* Description:
|
||||
* Called as the final act of trap_init(). Used in VISWS to initialise
|
||||
* the various board specific APIC traps.
|
||||
**/
|
||||
void __init x86_quirk_trap_init(void)
|
||||
{
|
||||
if (x86_quirks->arch_trap_init) {
|
||||
if (x86_quirks->arch_trap_init())
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static struct irqaction irq0 = {
|
||||
.handler = timer_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
|
||||
.name = "timer"
|
||||
static struct resource video_ram_resource = {
|
||||
.name = "Video RAM area",
|
||||
.start = 0xa0000,
|
||||
.end = 0xbffff,
|
||||
.flags = IORESOURCE_BUSY | IORESOURCE_MEM
|
||||
};
|
||||
|
||||
/**
|
||||
* x86_quirk_pre_time_init - do any specific initialisations before.
|
||||
*
|
||||
**/
|
||||
void __init x86_quirk_pre_time_init(void)
|
||||
void __init i386_reserve_resources(void)
|
||||
{
|
||||
if (x86_quirks->arch_pre_time_init)
|
||||
x86_quirks->arch_pre_time_init();
|
||||
request_resource(&iomem_resource, &video_ram_resource);
|
||||
reserve_standard_io_resources();
|
||||
}
|
||||
|
||||
/**
|
||||
* x86_quirk_time_init - do any specific initialisations for the system timer.
|
||||
*
|
||||
* Description:
|
||||
* Must plug the system timer interrupt source at HZ into the IRQ listed
|
||||
* in irq_vectors.h:TIMER_IRQ
|
||||
**/
|
||||
void __init x86_quirk_time_init(void)
|
||||
{
|
||||
if (x86_quirks->arch_time_init) {
|
||||
/*
|
||||
* A nonzero return code does not mean failure, it means
|
||||
* that the architecture quirk does not want any
|
||||
* generic (timer) setup to be performed after this:
|
||||
*/
|
||||
if (x86_quirks->arch_time_init())
|
||||
return;
|
||||
}
|
||||
|
||||
irq0.mask = cpumask_of_cpu(0);
|
||||
setup_irq(0, &irq0);
|
||||
}
|
||||
#endif /* CONFIG_X86_32 */
|
||||
|
@ -324,7 +324,7 @@ notrace static void __cpuinit start_secondary(void *unused)
|
||||
/* enable local interrupts */
|
||||
local_irq_enable();
|
||||
|
||||
setup_secondary_clock();
|
||||
x86_cpuinit.setup_percpu_clockev();
|
||||
|
||||
wmb();
|
||||
cpu_idle();
|
||||
@ -1114,7 +1114,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
|
||||
|
||||
printk(KERN_INFO "CPU%d: ", 0);
|
||||
print_cpu_info(&cpu_data(0));
|
||||
setup_boot_clock();
|
||||
x86_init.timers.setup_percpu_clockev();
|
||||
|
||||
if (is_uv_system())
|
||||
uv_system_init();
|
||||
|
121
arch/x86/kernel/time.c
Normal file
121
arch/x86/kernel/time.c
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 1991,1992,1995 Linus Torvalds
|
||||
* Copyright (c) 1994 Alan Modra
|
||||
* Copyright (c) 1995 Markus Kuhn
|
||||
* Copyright (c) 1996 Ingo Molnar
|
||||
* Copyright (c) 1998 Andrea Arcangeli
|
||||
* Copyright (c) 2002,2006 Vojtech Pavlik
|
||||
* Copyright (c) 2003 Andi Kleen
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mca.h>
|
||||
|
||||
#include <asm/vsyscall.h>
|
||||
#include <asm/x86_init.h>
|
||||
#include <asm/i8259.h>
|
||||
#include <asm/i8253.h>
|
||||
#include <asm/timer.h>
|
||||
#include <asm/hpet.h>
|
||||
#include <asm/time.h>
|
||||
|
||||
#if defined(CONFIG_X86_32) && defined(CONFIG_X86_IO_APIC)
|
||||
int timer_ack;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
|
||||
#endif
|
||||
|
||||
unsigned long profile_pc(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long pc = instruction_pointer(regs);
|
||||
|
||||
if (!user_mode_vm(regs) && in_lock_functions(pc)) {
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
return *(unsigned long *)(regs->bp + sizeof(long));
|
||||
#else
|
||||
unsigned long *sp = (unsigned long *)regs->sp;
|
||||
/*
|
||||
* Return address is either directly at stack pointer
|
||||
* or above a saved flags. Eflags has bits 22-31 zero,
|
||||
* kernel addresses don't.
|
||||
*/
|
||||
if (sp[0] >> 22)
|
||||
return sp[0];
|
||||
if (sp[1] >> 22)
|
||||
return sp[1];
|
||||
#endif
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
EXPORT_SYMBOL(profile_pc);
|
||||
|
||||
/*
|
||||
* Default timer interrupt handler for PIT/HPET
|
||||
*/
|
||||
static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
/* Keep nmi watchdog up to date */
|
||||
inc_irq_stat(irq0_irqs);
|
||||
|
||||
/* Optimized out for !IO_APIC and x86_64 */
|
||||
if (timer_ack) {
|
||||
/*
|
||||
* Subtle, when I/O APICs are used we have to ack timer IRQ
|
||||
* manually to deassert NMI lines for the watchdog if run
|
||||
* on an 82489DX-based system.
|
||||
*/
|
||||
spin_lock(&i8259A_lock);
|
||||
outb(0x0c, PIC_MASTER_OCW3);
|
||||
/* Ack the IRQ; AEOI will end it automatically. */
|
||||
inb(PIC_MASTER_POLL);
|
||||
spin_unlock(&i8259A_lock);
|
||||
}
|
||||
|
||||
global_clock_event->event_handler(global_clock_event);
|
||||
|
||||
/* MCA bus quirk: Acknowledge irq0 by setting bit 7 in port 0x61 */
|
||||
if (MCA_bus)
|
||||
outb_p(inb_p(0x61)| 0x80, 0x61);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static struct irqaction irq0 = {
|
||||
.handler = timer_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_NOBALANCING | IRQF_IRQPOLL | IRQF_TIMER,
|
||||
.name = "timer"
|
||||
};
|
||||
|
||||
void __init setup_default_timer_irq(void)
|
||||
{
|
||||
irq0.mask = cpumask_of_cpu(0);
|
||||
setup_irq(0, &irq0);
|
||||
}
|
||||
|
||||
/* Default timer init function */
|
||||
void __init hpet_time_init(void)
|
||||
{
|
||||
if (!hpet_enable())
|
||||
setup_pit_timer();
|
||||
setup_default_timer_irq();
|
||||
}
|
||||
|
||||
static __init void x86_late_time_init(void)
|
||||
{
|
||||
x86_init.timers.timer_init();
|
||||
tsc_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize TSC and delay the periodic timer init to
|
||||
* late x86_late_time_init() so ioremap works.
|
||||
*/
|
||||
void __init time_init(void)
|
||||
{
|
||||
late_time_init = x86_late_time_init;
|
||||
}
|
@ -1,137 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
|
||||
*
|
||||
* This file contains the PC-specific time handling details:
|
||||
* reading the RTC at bootup, etc..
|
||||
* 1994-07-02 Alan Modra
|
||||
* fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime
|
||||
* 1995-03-26 Markus Kuhn
|
||||
* fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887
|
||||
* precision CMOS clock update
|
||||
* 1996-05-03 Ingo Molnar
|
||||
* fixed time warps in do_[slow|fast]_gettimeoffset()
|
||||
* 1997-09-10 Updated NTP code according to technical memorandum Jan '96
|
||||
* "A Kernel Model for Precision Timekeeping" by Dave Mills
|
||||
* 1998-09-05 (Various)
|
||||
* More robust do_fast_gettimeoffset() algorithm implemented
|
||||
* (works with APM, Cyrix 6x86MX and Centaur C6),
|
||||
* monotonic gettimeofday() with fast_get_timeoffset(),
|
||||
* drift-proof precision TSC calibration on boot
|
||||
* (C. Scott Ananian <cananian@alumni.princeton.edu>, Andrew D.
|
||||
* Balsa <andrebalsa@altern.org>, Philip Gladstone <philip@raptor.com>;
|
||||
* ported from 2.0.35 Jumbo-9 by Michael Krause <m.krause@tu-harburg.de>).
|
||||
* 1998-12-16 Andrea Arcangeli
|
||||
* Fixed Jumbo-9 code in 2.1.131: do_gettimeofday was missing 1 jiffy
|
||||
* because was not accounting lost_ticks.
|
||||
* 1998-12-24 Copyright (C) 1998 Andrea Arcangeli
|
||||
* Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
|
||||
* serialize accesses to xtime/lost_ticks).
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mca.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <asm/hpet.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/timer.h>
|
||||
|
||||
#include <asm/do_timer.h>
|
||||
|
||||
int timer_ack;
|
||||
|
||||
unsigned long profile_pc(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long pc = instruction_pointer(regs);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (!user_mode_vm(regs) && in_lock_functions(pc)) {
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
return *(unsigned long *)(regs->bp + sizeof(long));
|
||||
#else
|
||||
unsigned long *sp = (unsigned long *)®s->sp;
|
||||
|
||||
/* Return address is either directly at stack pointer
|
||||
or above a saved flags. Eflags has bits 22-31 zero,
|
||||
kernel addresses don't. */
|
||||
if (sp[0] >> 22)
|
||||
return sp[0];
|
||||
if (sp[1] >> 22)
|
||||
return sp[1];
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return pc;
|
||||
}
|
||||
EXPORT_SYMBOL(profile_pc);
|
||||
|
||||
/*
|
||||
* This is the same as the above, except we _also_ save the current
|
||||
* Time Stamp Counter value at the time of the timer interrupt, so that
|
||||
* we later on can estimate the time of day more exactly.
|
||||
*/
|
||||
irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
/* Keep nmi watchdog up to date */
|
||||
inc_irq_stat(irq0_irqs);
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
if (timer_ack) {
|
||||
/*
|
||||
* Subtle, when I/O APICs are used we have to ack timer IRQ
|
||||
* manually to deassert NMI lines for the watchdog if run
|
||||
* on an 82489DX-based system.
|
||||
*/
|
||||
spin_lock(&i8259A_lock);
|
||||
outb(0x0c, PIC_MASTER_OCW3);
|
||||
/* Ack the IRQ; AEOI will end it automatically. */
|
||||
inb(PIC_MASTER_POLL);
|
||||
spin_unlock(&i8259A_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
do_timer_interrupt_hook();
|
||||
|
||||
#ifdef CONFIG_MCA
|
||||
if (MCA_bus) {
|
||||
/* The PS/2 uses level-triggered interrupts. You can't
|
||||
turn them off, nor would you want to (any attempt to
|
||||
enable edge-triggered interrupts usually gets intercepted by a
|
||||
special hardware circuit). Hence we have to acknowledge
|
||||
the timer interrupt. Through some incredibly stupid
|
||||
design idea, the reset for IRQ 0 is done by setting the
|
||||
high bit of the PPI port B (0x61). Note that some PS/2s,
|
||||
notably the 55SX, work fine if this is removed. */
|
||||
|
||||
u8 irq_v = inb_p(0x61); /* read the current state */
|
||||
outb_p(irq_v | 0x80, 0x61); /* reset the IRQ */
|
||||
}
|
||||
#endif
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Duplicate of time_init() below, with hpet_enable part added */
|
||||
void __init hpet_time_init(void)
|
||||
{
|
||||
if (!hpet_enable())
|
||||
setup_pit_timer();
|
||||
x86_quirk_time_init();
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called directly from init code; we must delay timer setup in the
|
||||
* HPET case as we can't make the decision to turn on HPET this early in the
|
||||
* boot process.
|
||||
*
|
||||
* The chosen time_init function will usually be hpet_time_init, above, but
|
||||
* in the case of virtual hardware, an alternative function may be substituted.
|
||||
*/
|
||||
void __init time_init(void)
|
||||
{
|
||||
x86_quirk_pre_time_init();
|
||||
tsc_init();
|
||||
late_time_init = choose_time_init();
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* "High Precision Event Timer" based timekeeping.
|
||||
*
|
||||
* Copyright (c) 1991,1992,1995 Linus Torvalds
|
||||
* Copyright (c) 1994 Alan Modra
|
||||
* Copyright (c) 1995 Markus Kuhn
|
||||
* Copyright (c) 1996 Ingo Molnar
|
||||
* Copyright (c) 1998 Andrea Arcangeli
|
||||
* Copyright (c) 2002,2006 Vojtech Pavlik
|
||||
* Copyright (c) 2003 Andi Kleen
|
||||
* RTC support code taken from arch/i386/kernel/timers/time_hpet.c
|
||||
*/
|
||||
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mca.h>
|
||||
#include <linux/nmi.h>
|
||||
|
||||
#include <asm/i8253.h>
|
||||
#include <asm/hpet.h>
|
||||
#include <asm/vgtod.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/timer.h>
|
||||
|
||||
volatile unsigned long __jiffies __section_jiffies = INITIAL_JIFFIES;
|
||||
|
||||
unsigned long profile_pc(struct pt_regs *regs)
|
||||
{
|
||||
unsigned long pc = instruction_pointer(regs);
|
||||
|
||||
/* Assume the lock function has either no stack frame or a copy
|
||||
of flags from PUSHF
|
||||
Eflags always has bits 22 and up cleared unlike kernel addresses. */
|
||||
if (!user_mode_vm(regs) && in_lock_functions(pc)) {
|
||||
#ifdef CONFIG_FRAME_POINTER
|
||||
return *(unsigned long *)(regs->bp + sizeof(long));
|
||||
#else
|
||||
unsigned long *sp = (unsigned long *)regs->sp;
|
||||
if (sp[0] >> 22)
|
||||
return sp[0];
|
||||
if (sp[1] >> 22)
|
||||
return sp[1];
|
||||
#endif
|
||||
}
|
||||
return pc;
|
||||
}
|
||||
EXPORT_SYMBOL(profile_pc);
|
||||
|
||||
static irqreturn_t timer_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
inc_irq_stat(irq0_irqs);
|
||||
|
||||
global_clock_event->event_handler(global_clock_event);
|
||||
|
||||
#ifdef CONFIG_MCA
|
||||
if (MCA_bus) {
|
||||
u8 irq_v = inb_p(0x61); /* read the current state */
|
||||
outb_p(irq_v|0x80, 0x61); /* reset the IRQ */
|
||||
}
|
||||
#endif
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* calibrate_cpu is used on systems with fixed rate TSCs to determine
|
||||
* processor frequency */
|
||||
#define TICK_COUNT 100000000
|
||||
unsigned long __init calibrate_cpu(void)
|
||||
{
|
||||
int tsc_start, tsc_now;
|
||||
int i, no_ctr_free;
|
||||
unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if (avail_to_resrv_perfctr_nmi_bit(i))
|
||||
break;
|
||||
no_ctr_free = (i == 4);
|
||||
if (no_ctr_free) {
|
||||
WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... "
|
||||
"cpu_khz value may be incorrect.\n");
|
||||
i = 3;
|
||||
rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
|
||||
wrmsrl(MSR_K7_EVNTSEL3, 0);
|
||||
rdmsrl(MSR_K7_PERFCTR3, pmc3);
|
||||
} else {
|
||||
reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
|
||||
reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
|
||||
}
|
||||
local_irq_save(flags);
|
||||
/* start measuring cycles, incrementing from 0 */
|
||||
wrmsrl(MSR_K7_PERFCTR0 + i, 0);
|
||||
wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
|
||||
rdtscl(tsc_start);
|
||||
do {
|
||||
rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
|
||||
tsc_now = get_cycles();
|
||||
} while ((tsc_now - tsc_start) < TICK_COUNT);
|
||||
|
||||
local_irq_restore(flags);
|
||||
if (no_ctr_free) {
|
||||
wrmsrl(MSR_K7_EVNTSEL3, 0);
|
||||
wrmsrl(MSR_K7_PERFCTR3, pmc3);
|
||||
wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
|
||||
} else {
|
||||
release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
|
||||
release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
|
||||
}
|
||||
|
||||
return pmc_now * tsc_khz / (tsc_now - tsc_start);
|
||||
}
|
||||
|
||||
static struct irqaction irq0 = {
|
||||
.handler = timer_interrupt,
|
||||
.flags = IRQF_DISABLED | IRQF_IRQPOLL | IRQF_NOBALANCING | IRQF_TIMER,
|
||||
.name = "timer"
|
||||
};
|
||||
|
||||
void __init hpet_time_init(void)
|
||||
{
|
||||
if (!hpet_enable())
|
||||
setup_pit_timer();
|
||||
|
||||
setup_irq(0, &irq0);
|
||||
}
|
||||
|
||||
void __init time_init(void)
|
||||
{
|
||||
tsc_init();
|
||||
|
||||
late_time_init = choose_time_init();
|
||||
}
|
@ -59,6 +59,7 @@
|
||||
#include <asm/mach_traps.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#include <asm/x86_init.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/proto.h>
|
||||
#else
|
||||
@ -972,7 +973,5 @@ void __init trap_init(void)
|
||||
*/
|
||||
cpu_init();
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
x86_quirk_trap_init();
|
||||
#endif
|
||||
x86_init.irqs.trap_init();
|
||||
}
|
||||
|
@ -17,6 +17,8 @@
|
||||
#include <asm/time.h>
|
||||
#include <asm/delay.h>
|
||||
#include <asm/hypervisor.h>
|
||||
#include <asm/nmi.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
unsigned int __read_mostly cpu_khz; /* TSC clocks / usec, not used here */
|
||||
EXPORT_SYMBOL(cpu_khz);
|
||||
@ -400,15 +402,9 @@ unsigned long native_calibrate_tsc(void)
|
||||
{
|
||||
u64 tsc1, tsc2, delta, ref1, ref2;
|
||||
unsigned long tsc_pit_min = ULONG_MAX, tsc_ref_min = ULONG_MAX;
|
||||
unsigned long flags, latch, ms, fast_calibrate, hv_tsc_khz;
|
||||
unsigned long flags, latch, ms, fast_calibrate;
|
||||
int hpet = is_hpet_enabled(), i, loopmin;
|
||||
|
||||
hv_tsc_khz = get_hypervisor_tsc_freq();
|
||||
if (hv_tsc_khz) {
|
||||
printk(KERN_INFO "TSC: Frequency read from the hypervisor\n");
|
||||
return hv_tsc_khz;
|
||||
}
|
||||
|
||||
local_irq_save(flags);
|
||||
fast_calibrate = quick_pit_calibrate();
|
||||
local_irq_restore(flags);
|
||||
@ -566,7 +562,7 @@ int recalibrate_cpu_khz(void)
|
||||
unsigned long cpu_khz_old = cpu_khz;
|
||||
|
||||
if (cpu_has_tsc) {
|
||||
tsc_khz = calibrate_tsc();
|
||||
tsc_khz = x86_platform.calibrate_tsc();
|
||||
cpu_khz = tsc_khz;
|
||||
cpu_data(0).loops_per_jiffy =
|
||||
cpufreq_scale(cpu_data(0).loops_per_jiffy,
|
||||
@ -860,15 +856,71 @@ static void __init init_tsc_clocksource(void)
|
||||
clocksource_register(&clocksource_tsc);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/*
|
||||
* calibrate_cpu is used on systems with fixed rate TSCs to determine
|
||||
* processor frequency
|
||||
*/
|
||||
#define TICK_COUNT 100000000
|
||||
static unsigned long __init calibrate_cpu(void)
|
||||
{
|
||||
int tsc_start, tsc_now;
|
||||
int i, no_ctr_free;
|
||||
unsigned long evntsel3 = 0, pmc3 = 0, pmc_now = 0;
|
||||
unsigned long flags;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
if (avail_to_resrv_perfctr_nmi_bit(i))
|
||||
break;
|
||||
no_ctr_free = (i == 4);
|
||||
if (no_ctr_free) {
|
||||
WARN(1, KERN_WARNING "Warning: AMD perfctrs busy ... "
|
||||
"cpu_khz value may be incorrect.\n");
|
||||
i = 3;
|
||||
rdmsrl(MSR_K7_EVNTSEL3, evntsel3);
|
||||
wrmsrl(MSR_K7_EVNTSEL3, 0);
|
||||
rdmsrl(MSR_K7_PERFCTR3, pmc3);
|
||||
} else {
|
||||
reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i);
|
||||
reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
|
||||
}
|
||||
local_irq_save(flags);
|
||||
/* start measuring cycles, incrementing from 0 */
|
||||
wrmsrl(MSR_K7_PERFCTR0 + i, 0);
|
||||
wrmsrl(MSR_K7_EVNTSEL0 + i, 1 << 22 | 3 << 16 | 0x76);
|
||||
rdtscl(tsc_start);
|
||||
do {
|
||||
rdmsrl(MSR_K7_PERFCTR0 + i, pmc_now);
|
||||
tsc_now = get_cycles();
|
||||
} while ((tsc_now - tsc_start) < TICK_COUNT);
|
||||
|
||||
local_irq_restore(flags);
|
||||
if (no_ctr_free) {
|
||||
wrmsrl(MSR_K7_EVNTSEL3, 0);
|
||||
wrmsrl(MSR_K7_PERFCTR3, pmc3);
|
||||
wrmsrl(MSR_K7_EVNTSEL3, evntsel3);
|
||||
} else {
|
||||
release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
|
||||
release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
|
||||
}
|
||||
|
||||
return pmc_now * tsc_khz / (tsc_now - tsc_start);
|
||||
}
|
||||
#else
|
||||
static inline unsigned long calibrate_cpu(void) { return cpu_khz; }
|
||||
#endif
|
||||
|
||||
void __init tsc_init(void)
|
||||
{
|
||||
u64 lpj;
|
||||
int cpu;
|
||||
|
||||
x86_init.timers.tsc_pre_init();
|
||||
|
||||
if (!cpu_has_tsc)
|
||||
return;
|
||||
|
||||
tsc_khz = calibrate_tsc();
|
||||
tsc_khz = x86_platform.calibrate_tsc();
|
||||
cpu_khz = tsc_khz;
|
||||
|
||||
if (!tsc_khz) {
|
||||
@ -876,11 +928,9 @@ void __init tsc_init(void)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) &&
|
||||
(boot_cpu_data.x86_vendor == X86_VENDOR_AMD))
|
||||
cpu_khz = calibrate_cpu();
|
||||
#endif
|
||||
|
||||
printk("Detected %lu.%03lu MHz processor.\n",
|
||||
(unsigned long)cpu_khz / 1000,
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <asm/setup.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <linux/kernel_stat.h>
|
||||
@ -53,7 +54,7 @@ int is_visws_box(void)
|
||||
return visws_board_type >= 0;
|
||||
}
|
||||
|
||||
static int __init visws_time_init(void)
|
||||
static void __init visws_time_init(void)
|
||||
{
|
||||
printk(KERN_INFO "Starting Cobalt Timer system clock\n");
|
||||
|
||||
@ -66,21 +67,13 @@ static int __init visws_time_init(void)
|
||||
/* Enable (unmask) the timer interrupt */
|
||||
co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
|
||||
|
||||
/*
|
||||
* Zero return means the generic timer setup code will set up
|
||||
* the standard vector:
|
||||
*/
|
||||
return 0;
|
||||
setup_default_timer_irq();
|
||||
}
|
||||
|
||||
static int __init visws_pre_intr_init(void)
|
||||
/* Replaces the default init_ISA_irqs in the generic setup */
|
||||
static void __init visws_pre_intr_init(void)
|
||||
{
|
||||
init_VISWS_APIC_irqs();
|
||||
|
||||
/*
|
||||
* We dont want ISA irqs to be set up by the generic code:
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Quirk for machine specific memory setup. */
|
||||
@ -156,12 +149,8 @@ static void visws_machine_power_off(void)
|
||||
outl(PIIX_SPECIAL_STOP, 0xCFC);
|
||||
}
|
||||
|
||||
static int __init visws_get_smp_config(unsigned int early)
|
||||
static void __init visws_get_smp_config(unsigned int early)
|
||||
{
|
||||
/*
|
||||
* Prevent MP-table parsing by the generic code:
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -208,7 +197,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
|
||||
apic_version[m->apicid] = ver;
|
||||
}
|
||||
|
||||
static int __init visws_find_smp_config(unsigned int reserve)
|
||||
static void __init visws_find_smp_config(unsigned int reserve)
|
||||
{
|
||||
struct mpc_cpu *mp = phys_to_virt(CO_CPU_TAB_PHYS);
|
||||
unsigned short ncpus = readw(phys_to_virt(CO_CPU_NUM_PHYS));
|
||||
@ -230,21 +219,9 @@ static int __init visws_find_smp_config(unsigned int reserve)
|
||||
MP_processor_info(mp++);
|
||||
|
||||
mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int visws_trap_init(void);
|
||||
|
||||
static struct x86_quirks visws_x86_quirks __initdata = {
|
||||
.arch_time_init = visws_time_init,
|
||||
.arch_pre_intr_init = visws_pre_intr_init,
|
||||
.arch_memory_setup = visws_memory_setup,
|
||||
.arch_intr_init = NULL,
|
||||
.arch_trap_init = visws_trap_init,
|
||||
.mach_get_smp_config = visws_get_smp_config,
|
||||
.mach_find_smp_config = visws_find_smp_config,
|
||||
};
|
||||
static void visws_trap_init(void);
|
||||
|
||||
void __init visws_early_detect(void)
|
||||
{
|
||||
@ -257,11 +234,14 @@ void __init visws_early_detect(void)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Install special quirks for timer, interrupt and memory setup:
|
||||
* Fall back to generic behavior for traps:
|
||||
* Override generic MP-table parsing:
|
||||
* Override the default platform setup functions
|
||||
*/
|
||||
x86_quirks = &visws_x86_quirks;
|
||||
x86_init.resources.memory_setup = visws_memory_setup;
|
||||
x86_init.mpparse.get_smp_config = visws_get_smp_config;
|
||||
x86_init.mpparse.find_smp_config = visws_find_smp_config;
|
||||
x86_init.irqs.pre_vector_init = visws_pre_intr_init;
|
||||
x86_init.irqs.trap_init = visws_trap_init;
|
||||
x86_init.timers.timer_init = visws_time_init;
|
||||
|
||||
/*
|
||||
* Install reboot quirks:
|
||||
@ -400,12 +380,10 @@ static __init void cobalt_init(void)
|
||||
co_apic_read(CO_APIC_ID));
|
||||
}
|
||||
|
||||
static int __init visws_trap_init(void)
|
||||
static void __init visws_trap_init(void)
|
||||
{
|
||||
lithium_init();
|
||||
cobalt_init();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -817,15 +817,15 @@ static inline int __init activate_vmi(void)
|
||||
vmi_timer_ops.set_alarm = vmi_get_function(VMI_CALL_SetAlarm);
|
||||
vmi_timer_ops.cancel_alarm =
|
||||
vmi_get_function(VMI_CALL_CancelAlarm);
|
||||
pv_time_ops.time_init = vmi_time_init;
|
||||
pv_time_ops.get_wallclock = vmi_get_wallclock;
|
||||
pv_time_ops.set_wallclock = vmi_set_wallclock;
|
||||
x86_init.timers.timer_init = vmi_time_init;
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
pv_apic_ops.setup_boot_clock = vmi_time_bsp_init;
|
||||
pv_apic_ops.setup_secondary_clock = vmi_time_ap_init;
|
||||
x86_init.timers.setup_percpu_clockev = vmi_time_bsp_init;
|
||||
x86_cpuinit.setup_percpu_clockev = vmi_time_ap_init;
|
||||
#endif
|
||||
pv_time_ops.sched_clock = vmi_sched_clock;
|
||||
pv_time_ops.get_tsc_khz = vmi_tsc_khz;
|
||||
x86_platform.calibrate_tsc = vmi_tsc_khz;
|
||||
x86_platform.get_wallclock = vmi_get_wallclock;
|
||||
x86_platform.set_wallclock = vmi_set_wallclock;
|
||||
|
||||
/* We have true wallclock functions; disable CMOS clock sync */
|
||||
no_sync_cmos_clock = 1;
|
||||
|
@ -68,7 +68,7 @@ unsigned long long vmi_sched_clock(void)
|
||||
return cycles_2_ns(vmi_timer_ops.get_cycle_counter(VMI_CYCLES_AVAILABLE));
|
||||
}
|
||||
|
||||
/* paravirt_ops.get_tsc_khz = vmi_tsc_khz */
|
||||
/* x86_platform.calibrate_tsc = vmi_tsc_khz */
|
||||
unsigned long vmi_tsc_khz(void)
|
||||
{
|
||||
unsigned long long khz;
|
||||
|
75
arch/x86/kernel/x86_init.c
Normal file
75
arch/x86/kernel/x86_init.c
Normal file
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 2009 Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* For licencing details see kernel-base/COPYING
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
|
||||
#include <asm/bios_ebda.h>
|
||||
#include <asm/paravirt.h>
|
||||
#include <asm/mpspec.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/apic.h>
|
||||
#include <asm/e820.h>
|
||||
#include <asm/time.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/tsc.h>
|
||||
|
||||
void __cpuinit x86_init_noop(void) { }
|
||||
void __init x86_init_uint_noop(unsigned int unused) { }
|
||||
void __init x86_init_pgd_noop(pgd_t *unused) { }
|
||||
|
||||
/*
|
||||
* The platform setup functions are preset with the default functions
|
||||
* for standard PC hardware.
|
||||
*/
|
||||
struct x86_init_ops x86_init __initdata = {
|
||||
|
||||
.resources = {
|
||||
.probe_roms = x86_init_noop,
|
||||
.reserve_resources = reserve_standard_io_resources,
|
||||
.memory_setup = default_machine_specific_memory_setup,
|
||||
},
|
||||
|
||||
.mpparse = {
|
||||
.mpc_record = x86_init_uint_noop,
|
||||
.setup_ioapic_ids = x86_init_noop,
|
||||
.mpc_apic_id = default_mpc_apic_id,
|
||||
.smp_read_mpc_oem = default_smp_read_mpc_oem,
|
||||
.mpc_oem_bus_info = default_mpc_oem_bus_info,
|
||||
.find_smp_config = default_find_smp_config,
|
||||
.get_smp_config = default_get_smp_config,
|
||||
},
|
||||
|
||||
.irqs = {
|
||||
.pre_vector_init = init_ISA_irqs,
|
||||
.intr_init = native_init_IRQ,
|
||||
.trap_init = x86_init_noop,
|
||||
},
|
||||
|
||||
.oem = {
|
||||
.arch_setup = x86_init_noop,
|
||||
.banner = default_banner,
|
||||
},
|
||||
|
||||
.paging = {
|
||||
.pagetable_setup_start = native_pagetable_setup_start,
|
||||
.pagetable_setup_done = native_pagetable_setup_done,
|
||||
},
|
||||
|
||||
.timers = {
|
||||
.setup_percpu_clockev = setup_boot_APIC_clock,
|
||||
.tsc_pre_init = x86_init_noop,
|
||||
.timer_init = hpet_time_init,
|
||||
},
|
||||
};
|
||||
|
||||
struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
|
||||
.setup_percpu_clockev = setup_secondary_APIC_clock,
|
||||
};
|
||||
|
||||
struct x86_platform_ops x86_platform = {
|
||||
.calibrate_tsc = native_calibrate_tsc,
|
||||
.get_wallclock = mach_get_cmos_time,
|
||||
.set_wallclock = mach_set_rtc_mmss,
|
||||
};
|
@ -1262,7 +1262,6 @@ __init void lguest_init(void)
|
||||
*/
|
||||
|
||||
/* Interrupt-related operations */
|
||||
pv_irq_ops.init_IRQ = lguest_init_IRQ;
|
||||
pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl);
|
||||
pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(lg_restore_fl);
|
||||
pv_irq_ops.irq_disable = PV_CALLEE_SAVE(irq_disable);
|
||||
@ -1270,7 +1269,6 @@ __init void lguest_init(void)
|
||||
pv_irq_ops.safe_halt = lguest_safe_halt;
|
||||
|
||||
/* Setup operations */
|
||||
pv_init_ops.memory_setup = lguest_memory_setup;
|
||||
pv_init_ops.patch = lguest_patch;
|
||||
|
||||
/* Intercepts of various CPU instructions */
|
||||
@ -1320,10 +1318,11 @@ __init void lguest_init(void)
|
||||
set_lguest_basic_apic_ops();
|
||||
#endif
|
||||
|
||||
/* Time operations */
|
||||
pv_time_ops.get_wallclock = lguest_get_wallclock;
|
||||
pv_time_ops.time_init = lguest_time_init;
|
||||
pv_time_ops.get_tsc_khz = lguest_tsc_khz;
|
||||
x86_init.resources.memory_setup = lguest_memory_setup;
|
||||
x86_init.irqs.intr_init = lguest_init_IRQ;
|
||||
x86_init.timers.timer_init = lguest_time_init;
|
||||
x86_platform.calibrate_tsc = lguest_tsc_khz;
|
||||
x86_platform.get_wallclock = lguest_get_wallclock;
|
||||
|
||||
/*
|
||||
* Now is a good time to look at the implementations of these functions
|
||||
|
@ -912,19 +912,9 @@ static const struct pv_info xen_info __initdata = {
|
||||
|
||||
static const struct pv_init_ops xen_init_ops __initdata = {
|
||||
.patch = xen_patch,
|
||||
|
||||
.banner = xen_banner,
|
||||
.memory_setup = xen_memory_setup,
|
||||
.arch_setup = xen_arch_setup,
|
||||
.post_allocator_init = xen_post_allocator_init,
|
||||
};
|
||||
|
||||
static const struct pv_time_ops xen_time_ops __initdata = {
|
||||
.time_init = xen_time_init,
|
||||
|
||||
.set_wallclock = xen_set_wallclock,
|
||||
.get_wallclock = xen_get_wallclock,
|
||||
.get_tsc_khz = xen_tsc_khz,
|
||||
.sched_clock = xen_sched_clock,
|
||||
};
|
||||
|
||||
@ -990,8 +980,6 @@ static const struct pv_cpu_ops xen_cpu_ops __initdata = {
|
||||
|
||||
static const struct pv_apic_ops xen_apic_ops __initdata = {
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
.setup_boot_clock = paravirt_nop,
|
||||
.setup_secondary_clock = paravirt_nop,
|
||||
.startup_ipi_hook = paravirt_nop,
|
||||
#endif
|
||||
};
|
||||
@ -1070,7 +1058,18 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
pv_time_ops = xen_time_ops;
|
||||
pv_cpu_ops = xen_cpu_ops;
|
||||
pv_apic_ops = xen_apic_ops;
|
||||
pv_mmu_ops = xen_mmu_ops;
|
||||
|
||||
x86_init.resources.memory_setup = xen_memory_setup;
|
||||
x86_init.oem.arch_setup = xen_arch_setup;
|
||||
x86_init.oem.banner = xen_banner;
|
||||
|
||||
x86_init.timers.timer_init = xen_time_init;
|
||||
x86_init.timers.setup_percpu_clockev = x86_init_noop;
|
||||
x86_cpuinit.setup_percpu_clockev = x86_init_noop;
|
||||
|
||||
x86_platform.calibrate_tsc = xen_tsc_khz;
|
||||
x86_platform.get_wallclock = xen_get_wallclock;
|
||||
x86_platform.set_wallclock = xen_set_wallclock;
|
||||
|
||||
/*
|
||||
* Set up some pagetable state before starting to set any ptes.
|
||||
@ -1095,6 +1094,7 @@ asmlinkage void __init xen_start_kernel(void)
|
||||
*/
|
||||
xen_setup_stackprotector();
|
||||
|
||||
xen_init_mmu_ops();
|
||||
xen_init_irq_ops();
|
||||
xen_init_cpuid_mask();
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
#include <xen/interface/xen.h>
|
||||
#include <xen/interface/sched.h>
|
||||
#include <xen/interface/vcpu.h>
|
||||
@ -112,8 +114,6 @@ static void xen_halt(void)
|
||||
}
|
||||
|
||||
static const struct pv_irq_ops xen_irq_ops __initdata = {
|
||||
.init_IRQ = xen_init_IRQ,
|
||||
|
||||
.save_fl = PV_CALLEE_SAVE(xen_save_fl),
|
||||
.restore_fl = PV_CALLEE_SAVE(xen_restore_fl),
|
||||
.irq_disable = PV_CALLEE_SAVE(xen_irq_disable),
|
||||
@ -129,4 +129,5 @@ static const struct pv_irq_ops xen_irq_ops __initdata = {
|
||||
void __init xen_init_irq_ops()
|
||||
{
|
||||
pv_irq_ops = xen_irq_ops;
|
||||
x86_init.irqs.intr_init = xen_init_IRQ;
|
||||
}
|
||||
|
@ -1229,9 +1229,12 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
|
||||
{
|
||||
}
|
||||
|
||||
static void xen_post_allocator_init(void);
|
||||
|
||||
static __init void xen_pagetable_setup_done(pgd_t *base)
|
||||
{
|
||||
xen_setup_shared_info();
|
||||
xen_post_allocator_init();
|
||||
}
|
||||
|
||||
static void xen_write_cr2(unsigned long cr2)
|
||||
@ -1841,7 +1844,7 @@ static void xen_set_fixmap(unsigned idx, phys_addr_t phys, pgprot_t prot)
|
||||
#endif
|
||||
}
|
||||
|
||||
__init void xen_post_allocator_init(void)
|
||||
static __init void xen_post_allocator_init(void)
|
||||
{
|
||||
pv_mmu_ops.set_pte = xen_set_pte;
|
||||
pv_mmu_ops.set_pmd = xen_set_pmd;
|
||||
@ -1875,10 +1878,7 @@ static void xen_leave_lazy_mmu(void)
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
const struct pv_mmu_ops xen_mmu_ops __initdata = {
|
||||
.pagetable_setup_start = xen_pagetable_setup_start,
|
||||
.pagetable_setup_done = xen_pagetable_setup_done,
|
||||
|
||||
static const struct pv_mmu_ops xen_mmu_ops __initdata = {
|
||||
.read_cr2 = xen_read_cr2,
|
||||
.write_cr2 = xen_write_cr2,
|
||||
|
||||
@ -1954,6 +1954,12 @@ const struct pv_mmu_ops xen_mmu_ops __initdata = {
|
||||
.set_fixmap = xen_set_fixmap,
|
||||
};
|
||||
|
||||
void __init xen_init_mmu_ops(void)
|
||||
{
|
||||
x86_init.paging.pagetable_setup_start = xen_pagetable_setup_start;
|
||||
x86_init.paging.pagetable_setup_done = xen_pagetable_setup_done;
|
||||
pv_mmu_ops = xen_mmu_ops;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_XEN_DEBUG_FS
|
||||
|
||||
|
@ -59,5 +59,5 @@ void xen_ptep_modify_prot_commit(struct mm_struct *mm, unsigned long addr,
|
||||
|
||||
unsigned long xen_read_cr2_direct(void);
|
||||
|
||||
extern const struct pv_mmu_ops xen_mmu_ops;
|
||||
extern void xen_init_mmu_ops(void);
|
||||
#endif /* _XEN_MMU_H */
|
||||
|
@ -30,8 +30,6 @@ pgd_t *xen_setup_kernel_pagetable(pgd_t *pgd, unsigned long max_pfn);
|
||||
void xen_ident_map_ISA(void);
|
||||
void xen_reserve_top(void);
|
||||
|
||||
void xen_post_allocator_init(void);
|
||||
|
||||
char * __init xen_memory_setup(void);
|
||||
void __init xen_arch_setup(void);
|
||||
void __init xen_init_IRQ(void);
|
||||
|
Loading…
Reference in New Issue
Block a user