Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33b39e84 authored by Isaku Yamahata's avatar Isaku Yamahata Committed by Tony Luck
Browse files

[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: default avatarIsaku Yamahata <yamahata@valinux.co.jp>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent e51835d5
Loading
Loading
Loading
Loading
+29 −16
Original line number Diff line number Diff line
@@ -587,6 +587,15 @@ static inline int irq_is_shared (int irq)
	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
register_intr (unsigned int gsi, int irq, unsigned char delivery,
	       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].trigger  = trigger;

	if (trigger == IOSAPIC_EDGE)
		irq_type = &irq_type_iosapic_edge;
	else
		irq_type = &irq_type_iosapic_level;
	irq_type = iosapic_get_irq_chip(trigger);

	idesc = irq_desc + irq;
	if (idesc->chip != irq_type) {
	if (irq_type != NULL && idesc->chip != irq_type) {
		if (idesc->chip != &no_irq_type)
			printk(KERN_WARNING
			       "%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);
}

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
iosapic_system_init (int system_pcat_compat)
{
@@ -989,17 +1011,8 @@ iosapic_system_init (int system_pcat_compat)
	}

	pcat_compat = system_pcat_compat;
	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);
	}
	if (pcat_compat)
		iosapic_pcat_compat_init();
}

static inline int
+25 −0
Original line number Diff line number Diff line
@@ -312,3 +312,28 @@ paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch)
		cpu_asm_switch->work_processed_syscall;
	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,
};
+16 −2
Original line number Diff line number Diff line
@@ -55,13 +55,27 @@

#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);
	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(val, iosapic + IOSAPIC_WINDOW);
+40 −0
Original line number Diff line number Diff line
@@ -112,6 +112,46 @@ static inline void paravirt_post_smp_prepare_boot_cpu(void)
		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__ */

#else