[BACK]Return to mmu_sh4.c CVS log [TXT][DIR] Up to [local] / sys / arch / sh / sh

Annotation of sys/arch/sh/sh/mmu_sh4.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: mmu_sh4.c,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $    */
                      2: /*     $NetBSD: mmu_sh4.c,v 1.11 2006/03/04 01:13:35 uwe Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2002 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by UCHIYAMA Yasushi.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *        This product includes software developed by the NetBSD
                     22:  *        Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42:
                     43: #include <sh/pte.h>    /* OpenBSD/sh specific PTE */
                     44: #include <sh/mmu.h>
                     45: #include <sh/mmu_sh4.h>
                     46:
                     47: #define        SH4_MMU_HAZARD  __asm volatile("nop;nop;nop;nop;nop;nop;nop;nop;")
                     48:
                     49: static inline void __sh4_itlb_invalidate_all(void);
                     50:
                     51: static inline void
                     52: __sh4_itlb_invalidate_all()
                     53: {
                     54:        _reg_write_4(SH4_ITLB_AA, 0);
                     55:        _reg_write_4(SH4_ITLB_AA | (1 << SH4_ITLB_E_SHIFT), 0);
                     56:        _reg_write_4(SH4_ITLB_AA | (2 << SH4_ITLB_E_SHIFT), 0);
                     57:        _reg_write_4(SH4_ITLB_AA | (3 << SH4_ITLB_E_SHIFT), 0);
                     58: }
                     59:
                     60: void
                     61: sh4_mmu_start()
                     62: {
                     63:        /* Zero clear all TLB entry */
                     64:        _reg_write_4(SH4_MMUCR, 0);     /* zero wired entry */
                     65:        sh_tlb_invalidate_all();
                     66:
                     67:        /* Set current ASID to 0 */
                     68:        sh_tlb_set_asid(0);
                     69:
                     70:        /*
                     71:         * User can't access store queue
                     72:         * make wired entry for u-area.
                     73:         */
                     74:        _reg_write_4(SH4_MMUCR, SH4_MMUCR_AT | SH4_MMUCR_TI | SH4_MMUCR_SQMD |
                     75:            (SH4_UTLB_ENTRY - UPAGES) << SH4_MMUCR_URB_SHIFT);
                     76:
                     77:        SH4_MMU_HAZARD;
                     78: }
                     79:
                     80: void
                     81: sh4_tlb_invalidate_addr(int asid, vaddr_t va)
                     82: {
                     83:        uint32_t pteh;
                     84:        int s;
                     85:
                     86:        va &= SH4_PTEH_VPN_MASK;
                     87:        s = _cpu_exception_suspend();
                     88:
                     89:        /* Save current ASID */
                     90:        pteh = _reg_read_4(SH4_PTEH);
                     91:        /* Set ASID for associative write */
                     92:        _reg_write_4(SH4_PTEH, asid);
                     93:
                     94:        /* Associative write(UTLB/ITLB). not required ITLB invalidate. */
                     95:        RUN_P2;
                     96:        _reg_write_4(SH4_UTLB_AA | SH4_UTLB_A, va); /* Clear D, V */
                     97:        RUN_P1;
                     98:        /* Restore ASID */
                     99:        _reg_write_4(SH4_PTEH, pteh);
                    100:
                    101:        _cpu_exception_resume(s);
                    102: }
                    103:
                    104: void
                    105: sh4_tlb_invalidate_asid(int asid)
                    106: {
                    107:        uint32_t a;
                    108:        int e, s;
                    109:
                    110:        s = _cpu_exception_suspend();
                    111:        /* Invalidate entry attribute to ASID */
                    112:        RUN_P2;
                    113:        for (e = 0; e < SH4_UTLB_ENTRY; e++) {
                    114:                a = SH4_UTLB_AA | (e << SH4_UTLB_E_SHIFT);
                    115:                if ((_reg_read_4(a) & SH4_UTLB_AA_ASID_MASK) == asid)
                    116:                        _reg_write_4(a, 0);
                    117:        }
                    118:
                    119:        __sh4_itlb_invalidate_all();
                    120:        RUN_P1;
                    121:        _cpu_exception_resume(s);
                    122: }
                    123:
                    124: void
                    125: sh4_tlb_invalidate_all()
                    126: {
                    127:        uint32_t a;
                    128:        int e, eend, s;
                    129:
                    130:        s = _cpu_exception_suspend();
                    131:        /* If non-wired entry limit is zero, clear all entry. */
                    132:        a = _reg_read_4(SH4_MMUCR) & SH4_MMUCR_URB_MASK;
                    133:        eend = a ? (a >> SH4_MMUCR_URB_SHIFT) : SH4_UTLB_ENTRY;
                    134:
                    135:        RUN_P2;
                    136:        for (e = 0; e < eend; e++) {
                    137:                a = SH4_UTLB_AA | (e << SH4_UTLB_E_SHIFT);
                    138:                _reg_write_4(a, 0);
                    139:                a = SH4_UTLB_DA1 | (e << SH4_UTLB_E_SHIFT);
                    140:                _reg_write_4(a, 0);
                    141:        }
                    142:        __sh4_itlb_invalidate_all();
                    143:        _reg_write_4(SH4_ITLB_DA1, 0);
                    144:        _reg_write_4(SH4_ITLB_DA1 | (1 << SH4_ITLB_E_SHIFT), 0);
                    145:        _reg_write_4(SH4_ITLB_DA1 | (2 << SH4_ITLB_E_SHIFT), 0);
                    146:        _reg_write_4(SH4_ITLB_DA1 | (3 << SH4_ITLB_E_SHIFT), 0);
                    147:        RUN_P1;
                    148:        _cpu_exception_resume(s);
                    149: }
                    150:
                    151: void
                    152: sh4_tlb_update(int asid, vaddr_t va, uint32_t pte)
                    153: {
                    154:        uint32_t oasid;
                    155:        uint32_t ptel;
                    156:        int s;
                    157:
                    158:        KDASSERT(asid < 0x100 && (pte & ~PGOFSET) != 0 && va != 0);
                    159:
                    160:        s = _cpu_exception_suspend();
                    161:        /* Save old ASID */
                    162:        oasid = _reg_read_4(SH4_PTEH) & SH4_PTEH_ASID_MASK;
                    163:
                    164:        /* Invalidate old entry (if any) */
                    165:        sh4_tlb_invalidate_addr(asid, va);
                    166:
                    167:        _reg_write_4(SH4_PTEH, asid);
                    168:        /* Load new entry */
                    169:        _reg_write_4(SH4_PTEH, (va & ~PGOFSET) | asid);
                    170:        ptel = pte & PG_HW_BITS;
                    171:        if (pte & _PG_PCMCIA) {
                    172:                _reg_write_4(SH4_PTEA,
                    173:                    (pte >> _PG_PCMCIA_SHIFT) & SH4_PTEA_SA_MASK);
                    174:        } else {
                    175:                _reg_write_4(SH4_PTEA, 0);
                    176:        }
                    177:        _reg_write_4(SH4_PTEL, ptel);
                    178:        __asm volatile("ldtlb; nop");
                    179:
                    180:        /* Restore old ASID */
                    181:        if (asid != oasid)
                    182:                _reg_write_4(SH4_PTEH, oasid);
                    183:        _cpu_exception_resume(s);
                    184: }

CVSweb