]> xenbits.xensource.com Git - xen.git/commitdiff
[IA64] Kexec: Add kexec_disable_iosapic
authorAlex Williamson <alex.williamson@hp.com>
Thu, 27 Sep 2007 21:12:58 +0000 (15:12 -0600)
committerAlex Williamson <alex.williamson@hp.com>
Thu, 27 Sep 2007 21:12:58 +0000 (15:12 -0600)
Ported from Linux, this shuts down iosapic before preforming kexec.
This resolves a problem whereby the serial port on an HP RX2620
(which uses IOSAPIC) was not able to accept input. It probably
resolves a bunch of other as yet unseen problems too.

Thanks to Takebe-san for working out the solution to this puzzle.

Cc: Akio Takebe <takebe_akio@jp.fujitsu.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
xen/arch/ia64/linux-xen/iosapic.c
xen/arch/ia64/xen/crash.c
xen/arch/ia64/xen/machine_kexec.c
xen/include/xen/kexec.h

index 90d9ba38f49dd2e10aba334e953dd153ba920531..64cc108a6fa59643f2ce32143648a835f21a492a 100644 (file)
@@ -268,6 +268,24 @@ nop (unsigned int vector)
        /* do nothing... */
 }
 
+void
+kexec_disable_iosapic(void)
+{
+        struct iosapic_intr_info *info;
+        struct iosapic_rte_info *rte;
+        u8 vec = 0;
+        for (info = iosapic_intr_info; info <
+                        iosapic_intr_info + IA64_NUM_VECTORS; ++info, ++vec) {
+                list_for_each_entry(rte, &info->rtes,
+                                rte_list) {
+                        iosapic_write(rte->addr,
+                                        IOSAPIC_RTE_LOW(rte->rte_index),
+                                        IOSAPIC_MASK|vec);
+                        iosapic_eoi(rte->addr, vec);
+                }
+        }
+}
+
 static void
 mask_irq (unsigned int irq)
 {
index df340b1c5789cd34dc6df25d10328374e54ad10a..1bdf36a5d112f0364cef22499011cca5235732a3 100644 (file)
@@ -30,6 +30,7 @@ void machine_crash_shutdown(void)
     dom0_mm_pgd_mfn = __pa(dom0->arch.mm.pgd) >> PAGE_SHIFT;
     memcpy((char *)info + offsetof(crash_xen_info_t, dom0_mm_pgd_mfn),
           &dom0_mm_pgd_mfn, sizeof(dom0_mm_pgd_mfn));
+    kexec_disable_iosapic();
 #ifdef CONFIG_SMP
     smp_send_stop();
 #endif
index 01acaa5ce767bf0a120fa0ed3e6c9bcb3852c74f..5cf49f21f8e1603f6605c1862eb848b98c6704f1 100644 (file)
@@ -85,6 +85,7 @@ static void ia64_machine_kexec(struct unw_frame_info *info, void *arg)
 
 void machine_kexec(xen_kexec_image_t *image)
 {
+       kexec_disable_iosapic();
        unw_init_running(ia64_machine_kexec, image);
        for(;;);
 }
index 523846af0655479a35e92b6e6ff89377e5fd3e24..1e04f9733c24d9c778db1f71fd15dfe8cdb45615 100644 (file)
@@ -27,6 +27,7 @@ void machine_kexec_reserved(xen_kexec_reserve_t *reservation);
 void machine_reboot_kexec(xen_kexec_image_t *image);
 void machine_kexec(xen_kexec_image_t *image);
 void kexec_crash(void);
+void kexec_disable_iosapic(void);
 void kexec_crash_save_cpu(void);
 crash_xen_info_t *kexec_crash_save_info(void);
 void machine_crash_shutdown(void);