123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- /*
- * arch/score/mm/tlbex.S
- *
- * Score Processor version.
- *
- * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
- * Lennox Wu <lennox.wu@sunplusct.com>
- * Chen Liqin <liqin.chen@sunplusct.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see the file COPYING, or write
- * to the Free Software Foundation, Inc.,
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- */
- #include <asm/asmmacro.h>
- #include <asm/pgtable-bits.h>
- #include <asm/scoreregs.h>
- /*
- * After this macro runs, the pte faulted on is
- * in register PTE, a ptr into the table in which
- * the pte belongs is in PTR.
- */
- .macro load_pte, pte, ptr
- la \ptr, pgd_current
- lw \ptr, [\ptr, 0]
- mfcr \pte, cr6
- srli \pte, \pte, 22
- slli \pte, \pte, 2
- add \ptr, \ptr, \pte
- lw \ptr, [\ptr, 0]
- mfcr \pte, cr6
- srli \pte, \pte, 10
- andi \pte, 0xffc
- add \ptr, \ptr, \pte
- lw \pte, [\ptr, 0]
- .endm
- .macro pte_reload, ptr
- lw \ptr, [\ptr, 0]
- mtcr \ptr, cr12
- nop
- nop
- nop
- nop
- nop
- .endm
- .macro do_fault, write
- SAVE_ALL
- mfcr r6, cr6
- mv r4, r0
- ldi r5, \write
- la r8, do_page_fault
- brl r8
- j ret_from_exception
- .endm
- .macro pte_writable, pte, ptr, label
- andi \pte, 0x280
- cmpi.c \pte, 0x280
- bne \label
- lw \pte, [\ptr, 0] /*reload PTE*/
- .endm
- /*
- * Make PTE writable, update software status bits as well,
- * then store at PTR.
- */
- .macro pte_makewrite, pte, ptr
- ori \pte, 0x426
- sw \pte, [\ptr, 0]
- .endm
- .text
- ENTRY(score7_FTLB_refill_Handler)
- la r31, pgd_current /* get pgd pointer */
- lw r31, [r31, 0] /* get the address of PGD */
- mfcr r30, cr6
- srli r30, r30, 22 /* PGDIR_SHIFT = 22*/
- slli r30, r30, 2
- add r31, r31, r30
- lw r31, [r31, 0] /* get the address of the start address of PTE table */
- mfcr r30, cr9
- andi r30, 0xfff /* equivalent to get PET index and right shift 2 bits */
- add r31, r31, r30
- lw r30, [r31, 0] /* load pte entry */
- mtcr r30, cr12
- nop
- nop
- nop
- nop
- nop
- mtrtlb
- nop
- nop
- nop
- nop
- nop
- rte /* 6 cycles to make sure tlb entry works */
- ENTRY(score7_KSEG_refill_Handler)
- la r31, pgd_current /* get pgd pointer */
- lw r31, [r31, 0] /* get the address of PGD */
- mfcr r30, cr6
- srli r30, r30, 22 /* PGDIR_SHIFT = 22 */
- slli r30, r30, 2
- add r31, r31, r30
- lw r31, [r31, 0] /* get the address of the start address of PTE table */
- mfcr r30, cr6 /* get Bad VPN */
- srli r30, r30, 10
- andi r30, 0xffc /* PTE VPN mask (bit 11~2) */
- add r31, r31, r30
- lw r30, [r31, 0] /* load pte entry */
- mtcr r30, cr12
- nop
- nop
- nop
- nop
- nop
- mtrtlb
- nop
- nop
- nop
- nop
- nop
- rte /* 6 cycles to make sure tlb entry works */
- nopage_tlbl:
- do_fault 0 /* Read */
- ENTRY(handle_tlb_refill)
- load_pte r30, r31
- pte_writable r30, r31, handle_tlb_refill_nopage
- pte_makewrite r30, r31 /* Access|Modify|Dirty|Valid */
- pte_reload r31
- mtrtlb
- nop
- nop
- nop
- nop
- nop
- rte
- handle_tlb_refill_nopage:
- do_fault 0 /* Read */
- ENTRY(handle_tlb_invaild)
- load_pte r30, r31
- stlb /* find faulting entry */
- pte_writable r30, r31, handle_tlb_invaild_nopage
- pte_makewrite r30, r31 /* Access|Modify|Dirty|Valid */
- pte_reload r31
- mtptlb
- nop
- nop
- nop
- nop
- nop
- rte
- handle_tlb_invaild_nopage:
- do_fault 0 /* Read */
- ENTRY(handle_mod)
- load_pte r30, r31
- stlb /* find faulting entry */
- andi r30, _PAGE_WRITE /* Writable? */
- cmpz.c r30
- beq nowrite_mod
- lw r30, [r31, 0] /* reload into r30 */
- /* Present and writable bits set, set accessed and dirty bits. */
- pte_makewrite r30, r31
- /* Now reload the entry into the tlb. */
- pte_reload r31
- mtptlb
- nop
- nop
- nop
- nop
- nop
- rte
- nowrite_mod:
- do_fault 1 /* Write */
|