/* * Copyright (c) 2006 Jakub Jermar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @addtogroup kernel_sparc64_interrupt * @{ */ /** * @file * @brief This file contains fast MMU trap handlers. */ .macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER /* * First, try to refill TLB from TSB. */ #ifdef CONFIG_TSB ldxa [%g0] ASI_IMMU, %g1 ! read TSB Tag Target Register ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2 ! read TSB 8K Pointer ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4 ! 16-byte atomic load into %g4 and %g5 cmp %g1, %g4 ! is this the entry we are looking for? bne,pn %xcc, 0f nop stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG ! copy mapping from ITSB to ITLB retry #endif 0: wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate mov TT_FAST_INSTRUCTION_ACCESS_MMU_MISS, %g2 mov VA_IMMU_TAG_ACCESS, %g5 ldxa [%g5] ASI_IMMU, %g5 ! read the faulting Context and VPN PREEMPTIBLE_HANDLER exc_dispatch .endm .macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl /* * First, try to refill TLB from TSB. */ #ifdef CONFIG_TSB ldxa [%g0] ASI_DMMU, %g1 ! read TSB Tag Target Register srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2 ! is this a kernel miss? brz,pn %g2, 0f ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3 ! read TSB 8K Pointer ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4 ! 16-byte atomic load into %g4 and %g5 cmp %g1, %g4 ! is this the entry we are looking for? bne,pn %xcc, 0f nop stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG ! copy mapping from DTSB to DTLB retry #endif /* * Second, test if it is the portion of the kernel address space * which is faulting. If that is the case, immediately create * identity mapping for that page in DTLB. VPN 0 is excluded from * this treatment. * * Note that branch-delay slots are used in order to save space. */ 0: sethi %hi(fast_data_access_mmu_miss_data_hi), %g7 wr %g0, ASI_DMMU, %asi ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1 ! read the faulting Context and VPN ldx [%g7 + %lo(tlb_tag_access_context_mask)], %g2 andcc %g1, %g2, %g3 ! get Context bnz %xcc, 0f ! Context is non-zero andncc %g1, %g2, %g3 ! get page address into %g3 bz %xcc, 0f ! page address is zero ldx [%g7 + %lo(end_of_identity)], %g4 cmp %g3, %g4 bgeu %xcc, 0f ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2 add %g3, %g2, %g2 stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page retry /* * Third, catch and handle special cases when the trap is caused by * the userspace register window spill or fill handler. In case * one of these two traps caused this trap, we just lower the trap * level and service the DTLB miss. In the end, we restart * the offending SAVE or RESTORE. */ 0: .if (\tl > 0) wrpr %g0, 1, %tl .endif /* * Switch from the MM globals. */ wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate mov TT_FAST_DATA_ACCESS_MMU_MISS, %g2 ldxa [VA_DMMU_TAG_ACCESS] %asi, %g5 ! read the faulting Context and VPN PREEMPTIBLE_HANDLER exc_dispatch .endm .macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl /* * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER. */ .if (\tl > 0) wrpr %g0, 1, %tl .endif /* * Switch from the MM globals. */ wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate mov TT_FAST_DATA_ACCESS_PROTECTION, %g2 mov VA_DMMU_TAG_ACCESS, %g5 ldxa [%g5] ASI_DMMU, %g5 ! read the faulting Context and VPN PREEMPTIBLE_HANDLER exc_dispatch .endm /** @} */