Annotation of sys/arch/sh/sh/mmu_sh3.c, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: mmu_sh3.c,v 1.1.1.1 2006/10/06 21:02:55 miod Exp $ */
2: /* $NetBSD: mmu_sh3.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_sh3.h>
46:
47: void
48: sh3_mmu_start()
49: {
50: /* Zero clear all TLB entry */
51: sh3_tlb_invalidate_all();
52:
53: /* Set current ASID to 0 */
54: sh_tlb_set_asid(0);
55:
56: _reg_write_4(SH3_MMUCR, SH3_MMUCR_AT | SH3_MMUCR_TF);
57: }
58:
59: void
60: sh3_tlb_invalidate_addr(int asid, vaddr_t va)
61: {
62: uint32_t a, d;
63: int w;
64:
65: d = (va & SH3_MMUAA_D_VPN_MASK_4K) | asid; /* 4K page */
66: va = va & SH3_MMU_VPN_MASK; /* [16:12] entry index */
67:
68: /* Probe entry and invalidate it. */
69: for (w = 0; w < SH3_MMU_WAY; w++) {
70: a = va | (w << SH3_MMU_WAY_SHIFT); /* way [9:8] */
71: if ((_reg_read_4(SH3_MMUAA | a) &
72: (SH3_MMUAA_D_VPN_MASK_4K | SH3_MMUAA_D_ASID_MASK)) == d) {
73: _reg_write_4(SH3_MMUAA | a, 0);
74: break;
75: }
76: }
77: }
78:
79: void
80: sh3_tlb_invalidate_asid(int asid)
81: {
82: uint32_t aw, a;
83: int e, w;
84:
85: /* Invalidate entry attribute to ASID */
86: for (w = 0; w < SH3_MMU_WAY; w++) {
87: aw = (w << SH3_MMU_WAY_SHIFT);
88: for (e = 0; e < SH3_MMU_ENTRY; e++) {
89: a = aw | (e << SH3_MMU_VPN_SHIFT);
90: if ((_reg_read_4(SH3_MMUAA | a) &
91: SH3_MMUAA_D_ASID_MASK) == asid) {
92: _reg_write_4(SH3_MMUAA | a, 0);
93: }
94: }
95: }
96: }
97:
98: void
99: sh3_tlb_invalidate_all()
100: {
101: uint32_t aw, a;
102: int e, w;
103:
104: /* Zero clear all TLB entry to avoid unexpected VPN match. */
105: for (w = 0; w < SH3_MMU_WAY; w++) {
106: aw = (w << SH3_MMU_WAY_SHIFT);
107: for (e = 0; e < SH3_MMU_ENTRY; e++) {
108: a = aw | (e << SH3_MMU_VPN_SHIFT);
109: _reg_write_4(SH3_MMUAA | a, 0);
110: _reg_write_4(SH3_MMUDA | a, 0);
111: }
112: }
113: }
114:
115: void
116: sh3_tlb_update(int asid, vaddr_t va, uint32_t pte)
117: {
118: uint32_t oasid;
119:
120: KDASSERT(asid < 0x100 && (pte & ~PGOFSET) != 0 && va != 0);
121:
122: /* Save old ASID */
123: oasid = _reg_read_4(SH3_PTEH) & SH3_PTEH_ASID_MASK;
124:
125: /* Invalidate old entry (if any) */
126: sh3_tlb_invalidate_addr(asid, va);
127:
128: /* Load new entry */
129: _reg_write_4(SH3_PTEH, (va & ~PGOFSET) | asid);
130: _reg_write_4(SH3_PTEL, pte & PG_HW_BITS);
131: __asm volatile("ldtlb");
132:
133: /* Restore old ASID */
134: if (asid != oasid)
135: _reg_write_4(SH3_PTEH, oasid);
136: }
CVSweb