diff options
author | Isaku Yamahata <yamahata@valinux.co.jp> | 2008-05-19 09:13:42 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2008-05-27 18:10:41 -0400 |
commit | 33b39e84209b0308b572dce017df7ee9b63f086c (patch) | |
tree | e27bb8c44aa70b3172c9be846960baf7dbe98bd4 | |
parent | e51835d58a5abdf82211f36f500f666ca7ef9aee (diff) |
[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>
-rw-r--r-- | arch/ia64/kernel/iosapic.c | 45 | ||||
-rw-r--r-- | arch/ia64/kernel/paravirt.c | 25 | ||||
-rw-r--r-- | include/asm-ia64/iosapic.h | 18 | ||||
-rw-r--r-- | include/asm-ia64/paravirt.h | 40 |
4 files changed, 110 insertions, 18 deletions
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c index 082c31dcfd99..587196dd84fd 100644 --- a/arch/ia64/kernel/iosapic.c +++ b/arch/ia64/kernel/iosapic.c | |||
@@ -587,6 +587,15 @@ static inline int irq_is_shared (int irq) | |||
587 | return (iosapic_intr_info[irq].count > 1); | 587 | return (iosapic_intr_info[irq].count > 1); |
588 | } | 588 | } |
589 | 589 | ||
590 | struct irq_chip* | ||
591 | ia64_native_iosapic_get_irq_chip(unsigned long trigger) | ||
592 | { | ||
593 | if (trigger == IOSAPIC_EDGE) | ||
594 | return &irq_type_iosapic_edge; | ||
595 | else | ||
596 | return &irq_type_iosapic_level; | ||
597 | } | ||
598 | |||
590 | static int | 599 | static int |
591 | register_intr (unsigned int gsi, int irq, unsigned char delivery, | 600 | register_intr (unsigned int gsi, int irq, unsigned char delivery, |
592 | unsigned long polarity, unsigned long trigger) | 601 | unsigned long polarity, unsigned long trigger) |
@@ -637,13 +646,10 @@ register_intr (unsigned int gsi, int irq, unsigned char delivery, | |||
637 | iosapic_intr_info[irq].dmode = delivery; | 646 | iosapic_intr_info[irq].dmode = delivery; |
638 | iosapic_intr_info[irq].trigger = trigger; | 647 | iosapic_intr_info[irq].trigger = trigger; |
639 | 648 | ||
640 | if (trigger == IOSAPIC_EDGE) | 649 | irq_type = iosapic_get_irq_chip(trigger); |
641 | irq_type = &irq_type_iosapic_edge; | ||
642 | else | ||
643 | irq_type = &irq_type_iosapic_level; | ||
644 | 650 | ||
645 | idesc = irq_desc + irq; | 651 | idesc = irq_desc + irq; |
646 | if (idesc->chip != irq_type) { | 652 | if (irq_type != NULL && idesc->chip != irq_type) { |
647 | if (idesc->chip != &no_irq_type) | 653 | if (idesc->chip != &no_irq_type) |
648 | printk(KERN_WARNING | 654 | printk(KERN_WARNING |
649 | "%s: changing vector %d from %s to %s\n", | 655 | "%s: changing vector %d from %s to %s\n", |
@@ -976,6 +982,22 @@ iosapic_override_isa_irq (unsigned int isa_irq, unsigned int gsi, | |||
976 | } | 982 | } |
977 | 983 | ||
978 | void __init | 984 | void __init |
985 | ia64_native_iosapic_pcat_compat_init(void) | ||
986 | { | ||
987 | if (pcat_compat) { | ||
988 | /* | ||
989 | * Disable the compatibility mode interrupts (8259 style), | ||
990 | * needs IN/OUT support enabled. | ||
991 | */ | ||
992 | printk(KERN_INFO | ||
993 | "%s: Disabling PC-AT compatible 8259 interrupts\n", | ||
994 | __func__); | ||
995 | outb(0xff, 0xA1); | ||
996 | outb(0xff, 0x21); | ||
997 | } | ||
998 | } | ||
999 | |||
1000 | void __init | ||
979 | iosapic_system_init (int system_pcat_compat) | 1001 | iosapic_system_init (int system_pcat_compat) |
980 | { | 1002 | { |
981 | int irq; | 1003 | int irq; |
@@ -989,17 +1011,8 @@ iosapic_system_init (int system_pcat_compat) | |||
989 | } | 1011 | } |
990 | 1012 | ||
991 | pcat_compat = system_pcat_compat; | 1013 | pcat_compat = system_pcat_compat; |
992 | if (pcat_compat) { | 1014 | if (pcat_compat) |
993 | /* | 1015 | iosapic_pcat_compat_init(); |
994 | * Disable the compatibility mode interrupts (8259 style), | ||
995 | * needs IN/OUT support enabled. | ||
996 | */ | ||
997 | printk(KERN_INFO | ||
998 | "%s: Disabling PC-AT compatible 8259 interrupts\n", | ||
999 | __func__); | ||
1000 | outb(0xff, 0xA1); | ||
1001 | outb(0xff, 0x21); | ||
1002 | } | ||
1003 | } | 1016 | } |
1004 | 1017 | ||
1005 | static inline int | 1018 | static inline int |
diff --git a/arch/ia64/kernel/paravirt.c b/arch/ia64/kernel/paravirt.c index 5daf659ff291..65c211b2f985 100644 --- a/arch/ia64/kernel/paravirt.c +++ b/arch/ia64/kernel/paravirt.c | |||
@@ -312,3 +312,28 @@ paravirt_cpu_asm_init(const struct pv_cpu_asm_switch *cpu_asm_switch) | |||
312 | cpu_asm_switch->work_processed_syscall; | 312 | cpu_asm_switch->work_processed_syscall; |
313 | paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel; | 313 | paravirt_leave_kernel_targ = cpu_asm_switch->leave_kernel; |
314 | } | 314 | } |
315 | |||
316 | /*************************************************************************** | ||
317 | * pv_iosapic_ops | ||
318 | * iosapic read/write hooks. | ||
319 | */ | ||
320 | |||
321 | static unsigned int | ||
322 | ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg) | ||
323 | { | ||
324 | return __ia64_native_iosapic_read(iosapic, reg); | ||
325 | } | ||
326 | |||
327 | static void | ||
328 | ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) | ||
329 | { | ||
330 | __ia64_native_iosapic_write(iosapic, reg, val); | ||
331 | } | ||
332 | |||
333 | struct pv_iosapic_ops pv_iosapic_ops = { | ||
334 | .pcat_compat_init = ia64_native_iosapic_pcat_compat_init, | ||
335 | .get_irq_chip = ia64_native_iosapic_get_irq_chip, | ||
336 | |||
337 | .__read = ia64_native_iosapic_read, | ||
338 | .__write = ia64_native_iosapic_write, | ||
339 | }; | ||
diff --git a/include/asm-ia64/iosapic.h b/include/asm-ia64/iosapic.h index a3a4288daae8..b9c102e15f22 100644 --- a/include/asm-ia64/iosapic.h +++ b/include/asm-ia64/iosapic.h | |||
@@ -55,13 +55,27 @@ | |||
55 | 55 | ||
56 | #define NR_IOSAPICS 256 | 56 | #define NR_IOSAPICS 256 |
57 | 57 | ||
58 | static inline unsigned int __iosapic_read(char __iomem *iosapic, unsigned int reg) | 58 | #ifdef CONFIG_PARAVIRT_GUEST |
59 | #include <asm/paravirt.h> | ||
60 | #else | ||
61 | #define iosapic_pcat_compat_init ia64_native_iosapic_pcat_compat_init | ||
62 | #define __iosapic_read __ia64_native_iosapic_read | ||
63 | #define __iosapic_write __ia64_native_iosapic_write | ||
64 | #define iosapic_get_irq_chip ia64_native_iosapic_get_irq_chip | ||
65 | #endif | ||
66 | |||
67 | extern void __init ia64_native_iosapic_pcat_compat_init(void); | ||
68 | extern struct irq_chip *ia64_native_iosapic_get_irq_chip(unsigned long trigger); | ||
69 | |||
70 | static inline unsigned int | ||
71 | __ia64_native_iosapic_read(char __iomem *iosapic, unsigned int reg) | ||
59 | { | 72 | { |
60 | writel(reg, iosapic + IOSAPIC_REG_SELECT); | 73 | writel(reg, iosapic + IOSAPIC_REG_SELECT); |
61 | return readl(iosapic + IOSAPIC_WINDOW); | 74 | return readl(iosapic + IOSAPIC_WINDOW); |
62 | } | 75 | } |
63 | 76 | ||
64 | static inline void __iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) | 77 | static inline void |
78 | __ia64_native_iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) | ||
65 | { | 79 | { |
66 | writel(reg, iosapic + IOSAPIC_REG_SELECT); | 80 | writel(reg, iosapic + IOSAPIC_REG_SELECT); |
67 | writel(val, iosapic + IOSAPIC_WINDOW); | 81 | writel(val, iosapic + IOSAPIC_WINDOW); |
diff --git a/include/asm-ia64/paravirt.h b/include/asm-ia64/paravirt.h index 84d74c32eb98..3a40f624e86e 100644 --- a/include/asm-ia64/paravirt.h +++ b/include/asm-ia64/paravirt.h | |||
@@ -112,6 +112,46 @@ static inline void paravirt_post_smp_prepare_boot_cpu(void) | |||
112 | pv_init_ops.post_smp_prepare_boot_cpu(); | 112 | pv_init_ops.post_smp_prepare_boot_cpu(); |
113 | } | 113 | } |
114 | 114 | ||
115 | /****************************************************************************** | ||
116 | * replacement of iosapic operations. | ||
117 | */ | ||
118 | |||
119 | struct pv_iosapic_ops { | ||
120 | void (*pcat_compat_init)(void); | ||
121 | |||
122 | struct irq_chip *(*get_irq_chip)(unsigned long trigger); | ||
123 | |||
124 | unsigned int (*__read)(char __iomem *iosapic, unsigned int reg); | ||
125 | void (*__write)(char __iomem *iosapic, unsigned int reg, u32 val); | ||
126 | }; | ||
127 | |||
128 | extern struct pv_iosapic_ops pv_iosapic_ops; | ||
129 | |||
130 | static inline void | ||
131 | iosapic_pcat_compat_init(void) | ||
132 | { | ||
133 | if (pv_iosapic_ops.pcat_compat_init) | ||
134 | pv_iosapic_ops.pcat_compat_init(); | ||
135 | } | ||
136 | |||
137 | static inline struct irq_chip* | ||
138 | iosapic_get_irq_chip(unsigned long trigger) | ||
139 | { | ||
140 | return pv_iosapic_ops.get_irq_chip(trigger); | ||
141 | } | ||
142 | |||
143 | static inline unsigned int | ||
144 | __iosapic_read(char __iomem *iosapic, unsigned int reg) | ||
145 | { | ||
146 | return pv_iosapic_ops.__read(iosapic, reg); | ||
147 | } | ||
148 | |||
149 | static inline void | ||
150 | __iosapic_write(char __iomem *iosapic, unsigned int reg, u32 val) | ||
151 | { | ||
152 | return pv_iosapic_ops.__write(iosapic, reg, val); | ||
153 | } | ||
154 | |||
115 | #endif /* !__ASSEMBLY__ */ | 155 | #endif /* !__ASSEMBLY__ */ |
116 | 156 | ||
117 | #else | 157 | #else |