[IA64] pvops: add hooks, pv_iosapic_ops, to paravirtualize iosapic.

add hooks to paravirtualize iosapic which is a real hardware resource.
On virtualized environment it may be replaced something virtualized
friendly.
Define pv_iosapic_ops and add the hooks.

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: Tony Luck <tony.luck@intel.com>
This commit is contained in:
Isaku Yamahata 2008-05-19 22:13:42 +09:00 committed by Tony Luck
parent e51835d58a
commit 33b39e8420
4 changed files with 110 additions and 18 deletions

View file

@ -587,6 +587,15 @@ static inline int irq_is_shared (int irq)
return (iosapic_intr_info[irq].count > 1); return (iosapic_intr_info[irq].count > 1);
} }
struct irq_chip*
ia64_native_iosapic_get_irq_chip(unsigned long trigger)
{
if (trigger == IOSAPIC_EDGE)
return &irq_type_iosapic_edge;
else
return &irq_type_iosapic_level;
}
static int static int
register_intr (unsigned int gsi, int irq, unsigned char delivery, register_intr (unsigned int gsi, int irq, unsigned char delivery,
unsigned long polarity, unsigned long trigger) unsigned long polarity, unsigned long trigger)
@ -637,13 +646,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery,
iosapic_intr_info[irq].dmode = delivery; iosapic_intr_info[irq].dmode = delivery;
iosapic_intr_info[irq].trigger = trigger; iosapic_intr_info[irq].trigger = trigger;
if (trigger == IOSAPIC_EDGE) irq_type = iosapic_get_irq_chip(trigger);
irq_type = &irq_type_iosapic_edge;
else
irq_type = &irq_type_iosapic_level;
idesc = irq_desc + irq; idesc = irq_desc + irq;
if (idesc->chip != irq_type) { if (irq_type != NULL && idesc->chip != irq_type) {
if (idesc->chip != &no_irq_type) if (idesc->chip != &no_irq_type)
printk(KERN_WARNING printk(KERN_WARNING
"%s: changing vector %d from %s to %s\n", "%s: changing vector %d from %s to %s\n",
@ -975,6 +981,22 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi,
set_rte(gsi, irq, dest, 1); set_rte(gsi, irq, dest, 1);
} }
void __init
ia64_native_iosapic_pcat_compat_init(void)
{
if (pcat_compat) {
/*
* Disable the compatibility mode interrupts (8259 style),
* needs IN/OUT support enabled.
*/
printk(KERN_INFO
"%s: Disabling PC-AT compatible 8259 interrupts\n",
__func__);
outb(0xff, 0xA1);
outb(0xff, 0x21);
}
}
void __init void __init
iosapic_system_init (int system_pcat_compat) iosapic_system_init (int system_pcat_compat)
{ {
@ -989,17 +1011,8 @@ iosapic_system_init (int system_pcat_compat)
} }
pcat_compat = system_pcat_compat; pcat_compat = system_pcat_compat;
if (pcat_compat) { if (pcat_compat)
/* iosapic_pcat_compat_init();
* Disable the compatibility mode interrupts (8259 style),
* needs IN/OUT support enabled.
*/
printk(KERN_INFO
"%s: Disabling PC-AT compatible 8259 interrupts\n",
__func__);
outb(0xff, 0xA1);
outb(0xff, 0x21);
}
} }
static inline int static inline int

View file

@ -312,3 +312,28 @@ paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
cpu_asm_switch->work_processed_syscall; cpu_asm_switch->work_processed_syscall;
paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel; paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel;
} }
/***************************************************************************
* pv_iosapic_ops
* iosapic read/write hooks.
*/
static unsigned int
ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
{
return __ia64_native_iosapic_read(iosapic, reg);
}
static void
ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
{
__ia64_native_iosapic_write(iosapic, reg, val);
}
struct pv_iosapic_ops pv_iosapic_ops = {
.pcat_compat_init = ia64_native_iosapic_pcat_compat_init,
.get_irq_chip = ia64_native_iosapic_get_irq_chip,
.__read = ia64_native_iosapic_read,
.__write = ia64_native_iosapic_write,
};

View file

@ -55,13 +55,27 @@
#define NR_IOSAPICS 256 #define NR_IOSAPICS 256
static inline unsigned int __iosapic_read(char __iomem *iosapic, unsigned int reg) #ifdef CONFIG_PARAVIRT_GUEST
#include <asm/paravirt.h>
#else
#define iosapic_pcat_compat_init ia64_native_iosapic_pcat_compat_init
#define __iosapic_read __ia64_native_iosapic_read
#define __iosapic_write __ia64_native_iosapic_write
#define iosapic_get_irq_chip ia64_native_iosapic_get_irq_chip
#endif
extern void __init ia64_native_iosapic_pcat_compat_init(void);
extern struct irq_chip *ia64_native_iosapic_get_irq_chip(unsigned long trigger);
static inline unsigned int
__ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg)
{ {
writel(reg, iosapic + IOSAPIC_REG_SELECT); writel(reg, iosapic + IOSAPIC_REG_SELECT);
return readl(iosapic + IOSAPIC_WINDOW); return readl(iosapic + IOSAPIC_WINDOW);
} }
static inline void __iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) static inline void
__ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
{ {
writel(reg, iosapic + IOSAPIC_REG_SELECT); writel(reg, iosapic + IOSAPIC_REG_SELECT);
writel(val, iosapic + IOSAPIC_WINDOW); writel(val, iosapic + IOSAPIC_WINDOW);

View file

@ -112,6 +112,46 @@ static inline void paravirt_post_smp_prepare_boot_cpu(void)
pv_init_ops.post_smp_prepare_boot_cpu(); pv_init_ops.post_smp_prepare_boot_cpu();
} }
/******************************************************************************
* replacement of iosapic operations.
*/
struct pv_iosapic_ops {
void (*pcat_compat_init)(void);
struct irq_chip *(*get_irq_chip)(unsigned long trigger);
unsigned int (*__read)(char __iomem *iosapic, unsigned int reg);
void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val);
};
extern struct pv_iosapic_ops pv_iosapic_ops;
static inline void
iosapic_pcat_compat_init(void)
{
if (pv_iosapic_ops.pcat_compat_init)
pv_iosapic_ops.pcat_compat_init();
}
static inline struct irq_chip*
iosapic_get_irq_chip(unsigned long trigger)
{
return pv_iosapic_ops.get_irq_chip(trigger);
}
static inline unsigned int
__iosapic_read(char __iomem *iosapic, unsigned int reg)
{
return pv_iosapic_ops.__read(iosapic, reg);
}
static inline void
__iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val)
{
return pv_iosapic_ops.__write(iosapic, reg, val);
}
#endif /* !__ASSEMBLY__ */ #endif /* !__ASSEMBLY__ */
#else #else