|
@@ -17,7 +17,6 @@
|
|
|
#include <asm/asm-offsets.h>
|
|
|
#include <asm/psr.h>
|
|
|
#include <asm/vaddrs.h>
|
|
|
-#include <asm/memreg.h>
|
|
|
#include <asm/page.h>
|
|
|
#include <asm/pgtable.h>
|
|
|
#include <asm/pgtsun4c.h>
|
|
@@ -828,253 +827,6 @@ vac_hwflush_patch2_on: sta %g0, [%l3 + %l7] ASI_HWFLUSHSEG
|
|
|
.globl vac_linesize_patch, vac_hwflush_patch1
|
|
|
.globl vac_hwflush_patch2
|
|
|
|
|
|
- .align 4
|
|
|
- .globl sun4c_fault
|
|
|
-
|
|
|
-! %l0 = %psr
|
|
|
-! %l1 = %pc
|
|
|
-! %l2 = %npc
|
|
|
-! %l3 = %wim
|
|
|
-! %l7 = 1 for textfault
|
|
|
-! We want error in %l5, vaddr in %l6
|
|
|
-sun4c_fault:
|
|
|
- sethi %hi(AC_SYNC_ERR), %l4
|
|
|
- add %l4, 0x4, %l6 ! AC_SYNC_VA in %l6
|
|
|
- lda [%l6] ASI_CONTROL, %l5 ! Address
|
|
|
- lda [%l4] ASI_CONTROL, %l6 ! Error, retained for a bit
|
|
|
-
|
|
|
- andn %l5, 0xfff, %l5 ! Encode all info into l7
|
|
|
- srl %l6, 14, %l4
|
|
|
-
|
|
|
- and %l4, 2, %l4
|
|
|
- or %l5, %l4, %l4
|
|
|
-
|
|
|
- or %l4, %l7, %l7 ! l7 = [addr,write,txtfault]
|
|
|
-
|
|
|
- andcc %l0, PSR_PS, %g0
|
|
|
- be sun4c_fault_fromuser
|
|
|
- andcc %l7, 1, %g0 ! Text fault?
|
|
|
-
|
|
|
- be 1f
|
|
|
- sethi %hi(KERNBASE), %l4
|
|
|
-
|
|
|
- mov %l1, %l5 ! PC
|
|
|
-
|
|
|
-1:
|
|
|
- cmp %l5, %l4
|
|
|
- blu sun4c_fault_fromuser
|
|
|
- sethi %hi(~((1 << SUN4C_REAL_PGDIR_SHIFT) - 1)), %l4
|
|
|
-
|
|
|
- /* If the kernel references a bum kernel pointer, or a pte which
|
|
|
- * points to a non existent page in ram, we will run this code
|
|
|
- * _forever_ and lock up the machine!!!!! So we must check for
|
|
|
- * this condition, the AC_SYNC_ERR bits are what we must examine.
|
|
|
- * Also a parity error would make this happen as well. So we just
|
|
|
- * check that we are in fact servicing a tlb miss and not some
|
|
|
- * other type of fault for the kernel.
|
|
|
- */
|
|
|
- andcc %l6, 0x80, %g0
|
|
|
- be sun4c_fault_fromuser
|
|
|
- and %l5, %l4, %l5
|
|
|
-
|
|
|
- /* Test for NULL pte_t * in vmalloc area. */
|
|
|
- sethi %hi(VMALLOC_START), %l4
|
|
|
- cmp %l5, %l4
|
|
|
- blu,a invalid_segment_patch1
|
|
|
- lduXa [%l5] ASI_SEGMAP, %l4
|
|
|
-
|
|
|
- sethi %hi(swapper_pg_dir), %l4
|
|
|
- srl %l5, SUN4C_PGDIR_SHIFT, %l6
|
|
|
- or %l4, %lo(swapper_pg_dir), %l4
|
|
|
- sll %l6, 2, %l6
|
|
|
- ld [%l4 + %l6], %l4
|
|
|
- andcc %l4, PAGE_MASK, %g0
|
|
|
- be sun4c_fault_fromuser
|
|
|
- lduXa [%l5] ASI_SEGMAP, %l4
|
|
|
-
|
|
|
-invalid_segment_patch1:
|
|
|
- cmp %l4, 0x7f
|
|
|
- bne 1f
|
|
|
- sethi %hi(sun4c_kfree_ring), %l4
|
|
|
- or %l4, %lo(sun4c_kfree_ring), %l4
|
|
|
- ld [%l4 + 0x18], %l3
|
|
|
- deccc %l3 ! do we have a free entry?
|
|
|
- bcs,a 2f ! no, unmap one.
|
|
|
- sethi %hi(sun4c_kernel_ring), %l4
|
|
|
-
|
|
|
- st %l3, [%l4 + 0x18] ! sun4c_kfree_ring.num_entries--
|
|
|
-
|
|
|
- ld [%l4 + 0x00], %l6 ! entry = sun4c_kfree_ring.ringhd.next
|
|
|
- st %l5, [%l6 + 0x08] ! entry->vaddr = address
|
|
|
-
|
|
|
- ld [%l6 + 0x00], %l3 ! next = entry->next
|
|
|
- ld [%l6 + 0x04], %l7 ! entry->prev
|
|
|
-
|
|
|
- st %l7, [%l3 + 0x04] ! next->prev = entry->prev
|
|
|
- st %l3, [%l7 + 0x00] ! entry->prev->next = next
|
|
|
-
|
|
|
- sethi %hi(sun4c_kernel_ring), %l4
|
|
|
- or %l4, %lo(sun4c_kernel_ring), %l4
|
|
|
- ! head = &sun4c_kernel_ring.ringhd
|
|
|
-
|
|
|
- ld [%l4 + 0x00], %l7 ! head->next
|
|
|
-
|
|
|
- st %l4, [%l6 + 0x04] ! entry->prev = head
|
|
|
- st %l7, [%l6 + 0x00] ! entry->next = head->next
|
|
|
- st %l6, [%l7 + 0x04] ! head->next->prev = entry
|
|
|
-
|
|
|
- st %l6, [%l4 + 0x00] ! head->next = entry
|
|
|
-
|
|
|
- ld [%l4 + 0x18], %l3
|
|
|
- inc %l3 ! sun4c_kernel_ring.num_entries++
|
|
|
- st %l3, [%l4 + 0x18]
|
|
|
- b 4f
|
|
|
- ld [%l6 + 0x08], %l5
|
|
|
-
|
|
|
-2:
|
|
|
- or %l4, %lo(sun4c_kernel_ring), %l4
|
|
|
- ! head = &sun4c_kernel_ring.ringhd
|
|
|
-
|
|
|
- ld [%l4 + 0x04], %l6 ! entry = head->prev
|
|
|
-
|
|
|
- ld [%l6 + 0x08], %l3 ! tmp = entry->vaddr
|
|
|
-
|
|
|
- ! Flush segment from the cache.
|
|
|
- sethi %hi((64 * 1024)), %l7
|
|
|
-9:
|
|
|
-vac_hwflush_patch1:
|
|
|
-vac_linesize_patch:
|
|
|
- subcc %l7, 16, %l7
|
|
|
- bne 9b
|
|
|
-vac_hwflush_patch2:
|
|
|
- sta %g0, [%l3 + %l7] ASI_FLUSHSEG
|
|
|
-
|
|
|
- st %l5, [%l6 + 0x08] ! entry->vaddr = address
|
|
|
-
|
|
|
- ld [%l6 + 0x00], %l5 ! next = entry->next
|
|
|
- ld [%l6 + 0x04], %l7 ! entry->prev
|
|
|
-
|
|
|
- st %l7, [%l5 + 0x04] ! next->prev = entry->prev
|
|
|
- st %l5, [%l7 + 0x00] ! entry->prev->next = next
|
|
|
- st %l4, [%l6 + 0x04] ! entry->prev = head
|
|
|
-
|
|
|
- ld [%l4 + 0x00], %l7 ! head->next
|
|
|
-
|
|
|
- st %l7, [%l6 + 0x00] ! entry->next = head->next
|
|
|
- st %l6, [%l7 + 0x04] ! head->next->prev = entry
|
|
|
- st %l6, [%l4 + 0x00] ! head->next = entry
|
|
|
-
|
|
|
- mov %l3, %l5 ! address = tmp
|
|
|
-
|
|
|
-4:
|
|
|
-num_context_patch1:
|
|
|
- mov 0x08, %l7
|
|
|
-
|
|
|
- ld [%l6 + 0x08], %l4
|
|
|
- ldub [%l6 + 0x0c], %l3
|
|
|
- or %l4, %l3, %l4 ! encode new vaddr/pseg into l4
|
|
|
-
|
|
|
- sethi %hi(AC_CONTEXT), %l3
|
|
|
- lduba [%l3] ASI_CONTROL, %l6
|
|
|
-
|
|
|
- /* Invalidate old mapping, instantiate new mapping,
|
|
|
- * for each context. Registers l6/l7 are live across
|
|
|
- * this loop.
|
|
|
- */
|
|
|
-3: deccc %l7
|
|
|
- sethi %hi(AC_CONTEXT), %l3
|
|
|
- stba %l7, [%l3] ASI_CONTROL
|
|
|
-invalid_segment_patch2:
|
|
|
- mov 0x7f, %l3
|
|
|
- stXa %l3, [%l5] ASI_SEGMAP
|
|
|
- andn %l4, 0x1ff, %l3
|
|
|
- bne 3b
|
|
|
- stXa %l4, [%l3] ASI_SEGMAP
|
|
|
-
|
|
|
- sethi %hi(AC_CONTEXT), %l3
|
|
|
- stba %l6, [%l3] ASI_CONTROL
|
|
|
-
|
|
|
- andn %l4, 0x1ff, %l5
|
|
|
-
|
|
|
-1:
|
|
|
- sethi %hi(VMALLOC_START), %l4
|
|
|
- cmp %l5, %l4
|
|
|
-
|
|
|
- bgeu 1f
|
|
|
- mov 1 << (SUN4C_REAL_PGDIR_SHIFT - PAGE_SHIFT), %l7
|
|
|
-
|
|
|
- sethi %hi(KERNBASE), %l6
|
|
|
-
|
|
|
- sub %l5, %l6, %l4
|
|
|
- srl %l4, PAGE_SHIFT, %l4
|
|
|
- sethi %hi((SUN4C_PAGE_KERNEL & 0xf4000000)), %l3
|
|
|
- or %l3, %l4, %l3
|
|
|
-
|
|
|
- sethi %hi(PAGE_SIZE), %l4
|
|
|
-
|
|
|
-2:
|
|
|
- sta %l3, [%l5] ASI_PTE
|
|
|
- deccc %l7
|
|
|
- inc %l3
|
|
|
- bne 2b
|
|
|
- add %l5, %l4, %l5
|
|
|
-
|
|
|
- b 7f
|
|
|
- sethi %hi(sun4c_kernel_faults), %l4
|
|
|
-
|
|
|
-1:
|
|
|
- srl %l5, SUN4C_PGDIR_SHIFT, %l3
|
|
|
- sethi %hi(swapper_pg_dir), %l4
|
|
|
- or %l4, %lo(swapper_pg_dir), %l4
|
|
|
- sll %l3, 2, %l3
|
|
|
- ld [%l4 + %l3], %l4
|
|
|
- and %l4, PAGE_MASK, %l4
|
|
|
-
|
|
|
- srl %l5, (PAGE_SHIFT - 2), %l6
|
|
|
- and %l6, ((SUN4C_PTRS_PER_PTE - 1) << 2), %l6
|
|
|
- add %l6, %l4, %l6
|
|
|
-
|
|
|
- sethi %hi(PAGE_SIZE), %l4
|
|
|
-
|
|
|
-2:
|
|
|
- ld [%l6], %l3
|
|
|
- deccc %l7
|
|
|
- sta %l3, [%l5] ASI_PTE
|
|
|
- add %l6, 0x4, %l6
|
|
|
- bne 2b
|
|
|
- add %l5, %l4, %l5
|
|
|
-
|
|
|
- sethi %hi(sun4c_kernel_faults), %l4
|
|
|
-7:
|
|
|
- ld [%l4 + %lo(sun4c_kernel_faults)], %l3
|
|
|
- inc %l3
|
|
|
- st %l3, [%l4 + %lo(sun4c_kernel_faults)]
|
|
|
-
|
|
|
- /* Restore condition codes */
|
|
|
- wr %l0, 0x0, %psr
|
|
|
- WRITE_PAUSE
|
|
|
- jmp %l1
|
|
|
- rett %l2
|
|
|
-
|
|
|
-sun4c_fault_fromuser:
|
|
|
- SAVE_ALL
|
|
|
- nop
|
|
|
-
|
|
|
- mov %l7, %o1 ! Decode the info from %l7
|
|
|
- mov %l7, %o2
|
|
|
- and %o1, 1, %o1 ! arg2 = text_faultp
|
|
|
- mov %l7, %o3
|
|
|
- and %o2, 2, %o2 ! arg3 = writep
|
|
|
- andn %o3, 0xfff, %o3 ! arg4 = faulting address
|
|
|
-
|
|
|
- wr %l0, PSR_ET, %psr
|
|
|
- WRITE_PAUSE
|
|
|
-
|
|
|
- call do_sun4c_fault
|
|
|
- add %sp, STACKFRAME_SZ, %o0 ! arg1 = pt_regs ptr
|
|
|
-
|
|
|
- RESTORE_ALL
|
|
|
-
|
|
|
.align 4
|
|
|
.globl srmmu_fault
|
|
|
srmmu_fault:
|