diff options
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/irq.c | 48 | ||||
-rw-r--r-- | arch/sparc64/kernel/trampoline.S | 12 |
2 files changed, 59 insertions, 1 deletions
diff --git a/arch/sparc64/kernel/irq.c b/arch/sparc64/kernel/irq.c index d069a6feb535..3c1a2139f1b9 100644 --- a/arch/sparc64/kernel/irq.c +++ b/arch/sparc64/kernel/irq.c | |||
@@ -855,6 +855,51 @@ void init_irqwork_curcpu(void) | |||
855 | memset(__irq_work + cpu, 0, sizeof(struct irq_work_struct)); | 855 | memset(__irq_work + cpu, 0, sizeof(struct irq_work_struct)); |
856 | } | 856 | } |
857 | 857 | ||
858 | static void __cpuinit init_one_mondo(unsigned long *pa_ptr, unsigned long type) | ||
859 | { | ||
860 | register unsigned long func __asm__("%o0"); | ||
861 | register unsigned long arg0 __asm__("%o1"); | ||
862 | register unsigned long arg1 __asm__("%o2"); | ||
863 | register unsigned long arg2 __asm__("%o3"); | ||
864 | unsigned long page = get_zeroed_page(GFP_ATOMIC); | ||
865 | |||
866 | if (!page) { | ||
867 | prom_printf("SUN4V: Error, cannot allocate mondo queue.\n"); | ||
868 | prom_halt(); | ||
869 | } | ||
870 | |||
871 | *pa_ptr = __pa(page); | ||
872 | |||
873 | func = HV_FAST_CPU_QCONF; | ||
874 | arg0 = type; | ||
875 | arg1 = *pa_ptr; | ||
876 | arg2 = 128; /* XXX Implied by Niagara queue offsets. XXX */ | ||
877 | __asm__ __volatile__("ta %8" | ||
878 | : "=&r" (func), "=&r" (arg0), | ||
879 | "=&r" (arg1), "=&r" (arg2) | ||
880 | : "0" (func), "1" (arg0), | ||
881 | "2" (arg1), "3" (arg2), | ||
882 | "i" (HV_FAST_TRAP)); | ||
883 | |||
884 | if (func != HV_EOK) { | ||
885 | prom_printf("SUN4V: cpu_qconf(%lu) failed with error %lu\n", | ||
886 | type, func); | ||
887 | prom_halt(); | ||
888 | } | ||
889 | } | ||
890 | |||
891 | /* Allocate and init the mondo queues for this cpu. */ | ||
892 | void __cpuinit sun4v_init_mondo_queues(void) | ||
893 | { | ||
894 | int cpu = hard_smp_processor_id(); | ||
895 | struct trap_per_cpu *tb = &trap_block[cpu]; | ||
896 | |||
897 | init_one_mondo(&tb->cpu_mondo_pa, HV_CPU_QUEUE_CPU_MONDO); | ||
898 | init_one_mondo(&tb->dev_mondo_pa, HV_CPU_QUEUE_DEVICE_MONDO); | ||
899 | init_one_mondo(&tb->resum_mondo_pa, HV_CPU_QUEUE_RES_ERROR); | ||
900 | init_one_mondo(&tb->nonresum_mondo_pa, HV_CPU_QUEUE_NONRES_ERROR); | ||
901 | } | ||
902 | |||
858 | /* Only invoked on boot processor. */ | 903 | /* Only invoked on boot processor. */ |
859 | void __init init_IRQ(void) | 904 | void __init init_IRQ(void) |
860 | { | 905 | { |
@@ -862,6 +907,9 @@ void __init init_IRQ(void) | |||
862 | kill_prom_timer(); | 907 | kill_prom_timer(); |
863 | memset(&ivector_table[0], 0, sizeof(ivector_table)); | 908 | memset(&ivector_table[0], 0, sizeof(ivector_table)); |
864 | 909 | ||
910 | if (tlb_type == hypervisor) | ||
911 | sun4v_init_mondo_queues(); | ||
912 | |||
865 | /* We need to clear any IRQ's pending in the soft interrupt | 913 | /* We need to clear any IRQ's pending in the soft interrupt |
866 | * registers, a spurious one could be left around from the | 914 | * registers, a spurious one could be left around from the |
867 | * PROM timer which we just disabled. | 915 | * PROM timer which we just disabled. |
diff --git a/arch/sparc64/kernel/trampoline.S b/arch/sparc64/kernel/trampoline.S index d9e2af35158d..fbf844f84a49 100644 --- a/arch/sparc64/kernel/trampoline.S +++ b/arch/sparc64/kernel/trampoline.S | |||
@@ -309,7 +309,17 @@ do_unlock: | |||
309 | 309 | ||
310 | call init_irqwork_curcpu | 310 | call init_irqwork_curcpu |
311 | nop | 311 | nop |
312 | call init_cur_cpu_trap | 312 | |
313 | sethi %hi(tlb_type), %g3 | ||
314 | lduw [%g3 + %lo(tlb_type)], %g2 | ||
315 | cmp %g2, 3 | ||
316 | bne,pt %icc, 1f | ||
317 | nop | ||
318 | |||
319 | call sun4v_init_mondo_queues | ||
320 | nop | ||
321 | |||
322 | 1: call init_cur_cpu_trap | ||
313 | nop | 323 | nop |
314 | 324 | ||
315 | /* Start using proper page size encodings in ctx register. */ | 325 | /* Start using proper page size encodings in ctx register. */ |