1*3cfca013Sjasper /* $OpenBSD: mmu.c,v 1.4 2010/06/02 05:35:17 jasper Exp $ */
295c7671fSmiod /* $NetBSD: mmu.c,v 1.15 2006/02/12 02:30:55 uwe Exp $ */
395c7671fSmiod
495c7671fSmiod /*-
595c7671fSmiod * Copyright (c) 2002 The NetBSD Foundation, Inc.
695c7671fSmiod * All rights reserved.
795c7671fSmiod *
895c7671fSmiod * This code is derived from software contributed to The NetBSD Foundation
995c7671fSmiod * by UCHIYAMA Yasushi.
1095c7671fSmiod *
1195c7671fSmiod * Redistribution and use in source and binary forms, with or without
1295c7671fSmiod * modification, are permitted provided that the following conditions
1395c7671fSmiod * are met:
1495c7671fSmiod * 1. Redistributions of source code must retain the above copyright
1595c7671fSmiod * notice, this list of conditions and the following disclaimer.
1695c7671fSmiod * 2. Redistributions in binary form must reproduce the above copyright
1795c7671fSmiod * notice, this list of conditions and the following disclaimer in the
1895c7671fSmiod * documentation and/or other materials provided with the distribution.
1995c7671fSmiod *
2095c7671fSmiod * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
2195c7671fSmiod * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2295c7671fSmiod * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2395c7671fSmiod * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2495c7671fSmiod * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2595c7671fSmiod * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2695c7671fSmiod * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2795c7671fSmiod * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2895c7671fSmiod * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2995c7671fSmiod * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3095c7671fSmiod * POSSIBILITY OF SUCH DAMAGE.
3195c7671fSmiod */
3295c7671fSmiod
3395c7671fSmiod #include <sys/param.h>
3495c7671fSmiod #include <sys/systm.h>
3595c7671fSmiod
3695c7671fSmiod #include <sh/mmu.h>
3795c7671fSmiod #include <sh/mmu_sh3.h>
3895c7671fSmiod #include <sh/mmu_sh4.h>
3995c7671fSmiod
4095c7671fSmiod #if defined(SH3) && defined(SH4)
4195c7671fSmiod void (*__sh_mmu_start)(void);
4295c7671fSmiod void (*__sh_tlb_invalidate_addr)(int, vaddr_t);
4395c7671fSmiod void (*__sh_tlb_invalidate_asid)(int);
4495c7671fSmiod void (*__sh_tlb_invalidate_all)(void);
4595c7671fSmiod void (*__sh_tlb_update)(int, vaddr_t, uint32_t);
4695c7671fSmiod #endif /* SH3 && SH4 */
4795c7671fSmiod
4895c7671fSmiod void
sh_mmu_init(void)4995c7671fSmiod sh_mmu_init(void)
5095c7671fSmiod {
5195c7671fSmiod /*
5295c7671fSmiod * Assign function hooks but only if both SH3 and SH4 are defined.
5395c7671fSmiod * They are called directly otherwise. See <sh3/mmu.h>.
5495c7671fSmiod */
5595c7671fSmiod #if defined(SH3) && defined(SH4)
5695c7671fSmiod if (CPU_IS_SH3) {
5795c7671fSmiod __sh_mmu_start = sh3_mmu_start;
5895c7671fSmiod __sh_tlb_invalidate_addr = sh3_tlb_invalidate_addr;
5995c7671fSmiod __sh_tlb_invalidate_asid = sh3_tlb_invalidate_asid;
6095c7671fSmiod __sh_tlb_invalidate_all = sh3_tlb_invalidate_all;
6195c7671fSmiod __sh_tlb_update = sh3_tlb_update;
6295c7671fSmiod }
6395c7671fSmiod else if (CPU_IS_SH4) {
6495c7671fSmiod __sh_mmu_start = sh4_mmu_start;
6595c7671fSmiod __sh_tlb_invalidate_addr = sh4_tlb_invalidate_addr;
6695c7671fSmiod __sh_tlb_invalidate_asid = sh4_tlb_invalidate_asid;
6795c7671fSmiod __sh_tlb_invalidate_all = sh4_tlb_invalidate_all;
6895c7671fSmiod __sh_tlb_update = sh4_tlb_update;
6995c7671fSmiod }
7095c7671fSmiod #endif /* SH3 && SH4 */
7195c7671fSmiod }
7295c7671fSmiod
7395c7671fSmiod void
sh_mmu_information(void)7495c7671fSmiod sh_mmu_information(void)
7595c7671fSmiod {
76427f1045Sderaadt #ifdef DEBUG
7795c7671fSmiod uint32_t r;
7895c7671fSmiod #ifdef SH3
7995c7671fSmiod if (CPU_IS_SH3) {
8095c7671fSmiod printf("cpu0: 4-way set-associative 128 TLB entries\n");
8195c7671fSmiod r = _reg_read_4(SH3_MMUCR);
8295c7671fSmiod printf("cpu0: %s mode, %s virtual storage mode\n",
8395c7671fSmiod r & SH3_MMUCR_IX ? "ASID+VPN" : "VPN",
8495c7671fSmiod r & SH3_MMUCR_SV ? "single" : "multiple");
8595c7671fSmiod }
8695c7671fSmiod #endif
8795c7671fSmiod #ifdef SH4
8895c7671fSmiod if (CPU_IS_SH4) {
89*3cfca013Sjasper unsigned int urb;
90427f1045Sderaadt printf("cpu0: fully-associative 4 ITLB, 64 UTLB entries\n");
9195c7671fSmiod r = _reg_read_4(SH4_MMUCR);
92*3cfca013Sjasper urb = (r & SH4_MMUCR_URB_MASK) >> SH4_MMUCR_URB_SHIFT;
9395c7671fSmiod printf("cpu0: %s virtual storage mode, SQ access: kernel%s, ",
9495c7671fSmiod r & SH3_MMUCR_SV ? "single" : "multiple",
9595c7671fSmiod r & SH4_MMUCR_SQMD ? "" : "/user");
9695c7671fSmiod printf("wired %d\n",
97*3cfca013Sjasper urb ? 64 - urb : 0);
9895c7671fSmiod }
9995c7671fSmiod #endif
100427f1045Sderaadt #endif /* DEBUG */
10195c7671fSmiod }
10295c7671fSmiod
10395c7671fSmiod void
sh_tlb_set_asid(int asid)10495c7671fSmiod sh_tlb_set_asid(int asid)
10595c7671fSmiod {
10695c7671fSmiod _reg_write_4(SH_(PTEH), asid);
10795c7671fSmiod }
108