diff options
Diffstat (limited to 'arch/sparc/kernel/entry.S')
-rw-r--r-- | arch/sparc/kernel/entry.S | 94 |
1 files changed, 20 insertions, 74 deletions
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index e8cdf715a546..faf9ccd9ef5d 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -20,11 +20,7 @@ | |||
20 | #include <asm/memreg.h> | 20 | #include <asm/memreg.h> |
21 | #include <asm/page.h> | 21 | #include <asm/page.h> |
22 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
23 | #ifdef CONFIG_SUN4 | ||
24 | #include <asm/pgtsun4.h> | ||
25 | #else | ||
26 | #include <asm/pgtsun4c.h> | 23 | #include <asm/pgtsun4c.h> |
27 | #endif | ||
28 | #include <asm/winmacro.h> | 24 | #include <asm/winmacro.h> |
29 | #include <asm/signal.h> | 25 | #include <asm/signal.h> |
30 | #include <asm/obio.h> | 26 | #include <asm/obio.h> |
@@ -276,17 +272,18 @@ smp4m_ticker: | |||
276 | */ | 272 | */ |
277 | maybe_smp4m_msg: | 273 | maybe_smp4m_msg: |
278 | GET_PROCESSOR4M_ID(o3) | 274 | GET_PROCESSOR4M_ID(o3) |
279 | set sun4m_interrupts, %l5 | 275 | sethi %hi(sun4m_irq_percpu), %l5 |
280 | ld [%l5], %o5 | 276 | sll %o3, 2, %o3 |
277 | or %l5, %lo(sun4m_irq_percpu), %o5 | ||
281 | sethi %hi(0x40000000), %o2 | 278 | sethi %hi(0x40000000), %o2 |
282 | sll %o3, 12, %o3 | ||
283 | ld [%o5 + %o3], %o1 | 279 | ld [%o5 + %o3], %o1 |
284 | andcc %o1, %o2, %g0 | 280 | ld [%o1 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending |
281 | andcc %o3, %o2, %g0 | ||
285 | be,a smp4m_ticker | 282 | be,a smp4m_ticker |
286 | cmp %l7, 14 | 283 | cmp %l7, 14 |
287 | st %o2, [%o5 + 0x4] | 284 | st %o2, [%o1 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x40000000 |
288 | WRITE_PAUSE | 285 | WRITE_PAUSE |
289 | ld [%o5], %g0 | 286 | ld [%o1 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending |
290 | WRITE_PAUSE | 287 | WRITE_PAUSE |
291 | or %l0, PSR_PIL, %l4 | 288 | or %l0, PSR_PIL, %l4 |
292 | wr %l4, 0x0, %psr | 289 | wr %l4, 0x0, %psr |
@@ -304,16 +301,16 @@ linux_trap_ipi15_sun4m: | |||
304 | SAVE_ALL | 301 | SAVE_ALL |
305 | sethi %hi(0x80000000), %o2 | 302 | sethi %hi(0x80000000), %o2 |
306 | GET_PROCESSOR4M_ID(o0) | 303 | GET_PROCESSOR4M_ID(o0) |
307 | set sun4m_interrupts, %l5 | 304 | sethi %hi(sun4m_irq_percpu), %l5 |
308 | ld [%l5], %o5 | 305 | or %l5, %lo(sun4m_irq_percpu), %o5 |
309 | sll %o0, 12, %o0 | 306 | sll %o0, 2, %o0 |
310 | add %o5, %o0, %o5 | 307 | ld [%o5 + %o0], %o5 |
311 | ld [%o5], %o3 | 308 | ld [%o5 + 0x00], %o3 ! sun4m_irq_percpu[cpu]->pending |
312 | andcc %o3, %o2, %g0 | 309 | andcc %o3, %o2, %g0 |
313 | be 1f ! Must be an NMI async memory error | 310 | be 1f ! Must be an NMI async memory error |
314 | st %o2, [%o5 + 4] | 311 | st %o2, [%o5 + 0x04] ! sun4m_irq_percpu[cpu]->clear=0x80000000 |
315 | WRITE_PAUSE | 312 | WRITE_PAUSE |
316 | ld [%o5], %g0 | 313 | ld [%o5 + 0x00], %g0 ! sun4m_irq_percpu[cpu]->pending |
317 | WRITE_PAUSE | 314 | WRITE_PAUSE |
318 | or %l0, PSR_PIL, %l4 | 315 | or %l0, PSR_PIL, %l4 |
319 | wr %l4, 0x0, %psr | 316 | wr %l4, 0x0, %psr |
@@ -327,12 +324,11 @@ linux_trap_ipi15_sun4m: | |||
327 | 1: | 324 | 1: |
328 | /* NMI async memory error handling. */ | 325 | /* NMI async memory error handling. */ |
329 | sethi %hi(0x80000000), %l4 | 326 | sethi %hi(0x80000000), %l4 |
330 | sethi %hi(0x4000), %o3 | 327 | sethi %hi(sun4m_irq_global), %o5 |
331 | sub %o5, %o0, %o5 | 328 | ld [%o5 + %lo(sun4m_irq_global)], %l5 |
332 | add %o5, %o3, %l5 | 329 | st %l4, [%l5 + 0x0c] ! sun4m_irq_global->mask_set=0x80000000 |
333 | st %l4, [%l5 + 0xc] | ||
334 | WRITE_PAUSE | 330 | WRITE_PAUSE |
335 | ld [%l5], %g0 | 331 | ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending |
336 | WRITE_PAUSE | 332 | WRITE_PAUSE |
337 | or %l0, PSR_PIL, %l4 | 333 | or %l0, PSR_PIL, %l4 |
338 | wr %l4, 0x0, %psr | 334 | wr %l4, 0x0, %psr |
@@ -341,9 +337,9 @@ linux_trap_ipi15_sun4m: | |||
341 | WRITE_PAUSE | 337 | WRITE_PAUSE |
342 | call sun4m_nmi | 338 | call sun4m_nmi |
343 | nop | 339 | nop |
344 | st %l4, [%l5 + 0x8] | 340 | st %l4, [%l5 + 0x08] ! sun4m_irq_global->mask_clear=0x80000000 |
345 | WRITE_PAUSE | 341 | WRITE_PAUSE |
346 | ld [%l5], %g0 | 342 | ld [%l5 + 0x00], %g0 ! sun4m_irq_global->pending |
347 | WRITE_PAUSE | 343 | WRITE_PAUSE |
348 | RESTORE_ALL | 344 | RESTORE_ALL |
349 | 345 | ||
@@ -775,11 +771,7 @@ vac_linesize_patch_32: subcc %l7, 32, %l7 | |||
775 | * Ugly, but we cant use hardware flushing on the sun4 and we'd require | 771 | * Ugly, but we cant use hardware flushing on the sun4 and we'd require |
776 | * two instructions (Anton) | 772 | * two instructions (Anton) |
777 | */ | 773 | */ |
778 | #ifdef CONFIG_SUN4 | ||
779 | vac_hwflush_patch1_on: nop | ||
780 | #else | ||
781 | vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 | 774 | vac_hwflush_patch1_on: addcc %l7, -PAGE_SIZE, %l7 |
782 | #endif | ||
783 | 775 | ||
784 | vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG | 776 | vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG |
785 | 777 | ||
@@ -798,42 +790,10 @@ vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG | |||
798 | ! %l7 = 1 for textfault | 790 | ! %l7 = 1 for textfault |
799 | ! We want error in %l5, vaddr in %l6 | 791 | ! We want error in %l5, vaddr in %l6 |
800 | sun4c_fault: | 792 | sun4c_fault: |
801 | #ifdef CONFIG_SUN4 | ||
802 | sethi %hi(sun4c_memerr_reg), %l4 | ||
803 | ld [%l4+%lo(sun4c_memerr_reg)], %l4 ! memerr ctrl reg addr | ||
804 | ld [%l4], %l6 ! memerr ctrl reg | ||
805 | ld [%l4 + 4], %l5 ! memerr vaddr reg | ||
806 | andcc %l6, 0x80, %g0 ! check for error type | ||
807 | st %g0, [%l4 + 4] ! clear the error | ||
808 | be 0f ! normal error | ||
809 | sethi %hi(AC_BUS_ERROR), %l4 ! bus err reg addr | ||
810 | |||
811 | call prom_halt ! something weird happened | ||
812 | ! what exactly did happen? | ||
813 | ! what should we do here? | ||
814 | |||
815 | 0: or %l4, %lo(AC_BUS_ERROR), %l4 ! bus err reg addr | ||
816 | lduba [%l4] ASI_CONTROL, %l6 ! bus err reg | ||
817 | |||
818 | cmp %l7, 1 ! text fault? | ||
819 | be 1f ! yes | ||
820 | nop | ||
821 | |||
822 | ld [%l1], %l4 ! load instruction that caused fault | ||
823 | srl %l4, 21, %l4 | ||
824 | andcc %l4, 1, %g0 ! store instruction? | ||
825 | |||
826 | be 1f ! no | ||
827 | sethi %hi(SUN4C_SYNC_BADWRITE), %l4 ! yep | ||
828 | ! %lo(SUN4C_SYNC_BADWRITE) = 0 | ||
829 | or %l4, %l6, %l6 ! set write bit to emulate sun4c | ||
830 | 1: | ||
831 | #else | ||
832 | sethi %hi(AC_SYNC_ERR), %l4 | 793 | sethi %hi(AC_SYNC_ERR), %l4 |
833 | add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6 | 794 | add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6 |
834 | lda [%l6] ASI_CONTROL, %l5 ! Address | 795 | lda [%l6] ASI_CONTROL, %l5 ! Address |
835 | lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit | 796 | lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit |
836 | #endif | ||
837 | 797 | ||
838 | andn %l5, 0xfff, %l5 ! Encode all info into l7 | 798 | andn %l5, 0xfff, %l5 ! Encode all info into l7 |
839 | srl %l6, 14, %l4 | 799 | srl %l6, 14, %l4 |
@@ -880,12 +840,7 @@ sun4c_fault: | |||
880 | or %l4, %lo(swapper_pg_dir), %l4 | 840 | or %l4, %lo(swapper_pg_dir), %l4 |
881 | sll %l6, 2, %l6 | 841 | sll %l6, 2, %l6 |
882 | ld [%l4 + %l6], %l4 | 842 | ld [%l4 + %l6], %l4 |
883 | #ifdef CONFIG_SUN4 | ||
884 | sethi %hi(PAGE_MASK), %l6 | ||
885 | andcc %l4, %l6, %g0 | ||
886 | #else | ||
887 | andcc %l4, PAGE_MASK, %g0 | 843 | andcc %l4, PAGE_MASK, %g0 |
888 | #endif | ||
889 | be sun4c_fault_fromuser | 844 | be sun4c_fault_fromuser |
890 | lduXa [%l5] ASI_SEGMAP, %l4 | 845 | lduXa [%l5] ASI_SEGMAP, %l4 |
891 | 846 | ||
@@ -937,11 +892,7 @@ invalid_segment_patch1: | |||
937 | ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr | 892 | ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr |
938 | 893 | ||
939 | ! Flush segment from the cache. | 894 | ! Flush segment from the cache. |
940 | #ifdef CONFIG_SUN4 | ||
941 | sethi %hi((128 * 1024)), %l7 | ||
942 | #else | ||
943 | sethi %hi((64 * 1024)), %l7 | 895 | sethi %hi((64 * 1024)), %l7 |
944 | #endif | ||
945 | 9: | 896 | 9: |
946 | vac_hwflush_patch1: | 897 | vac_hwflush_patch1: |
947 | vac_linesize_patch: | 898 | vac_linesize_patch: |
@@ -1029,12 +980,7 @@ invalid_segment_patch2: | |||
1029 | or %l4, %lo(swapper_pg_dir), %l4 | 980 | or %l4, %lo(swapper_pg_dir), %l4 |
1030 | sll %l3, 2, %l3 | 981 | sll %l3, 2, %l3 |
1031 | ld [%l4 + %l3], %l4 | 982 | ld [%l4 + %l3], %l4 |
1032 | #ifndef CONFIG_SUN4 | ||
1033 | and %l4, PAGE_MASK, %l4 | 983 | and %l4, PAGE_MASK, %l4 |
1034 | #else | ||
1035 | sethi %hi(PAGE_MASK), %l6 | ||
1036 | and %l4, %l6, %l4 | ||
1037 | #endif | ||
1038 | 984 | ||
1039 | srl %l5, (PAGE_SHIFT - 2), %l6 | 985 | srl %l5, (PAGE_SHIFT - 2), %l6 |
1040 | and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 | 986 | and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6 |