1224110Sjchandra/*-
2224110Sjchandra * Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
3224110Sjchandra * reserved.
4224110Sjchandra *
5224110Sjchandra * Redistribution and use in source and binary forms, with or without
6224110Sjchandra * modification, are permitted provided that the following conditions are
7224110Sjchandra * met:
8224110Sjchandra *
9224110Sjchandra * 1. Redistributions of source code must retain the above copyright
10224110Sjchandra *    notice, this list of conditions and the following disclaimer.
11224110Sjchandra * 2. Redistributions in binary form must reproduce the above copyright
12224110Sjchandra *    notice, this list of conditions and the following disclaimer in
13224110Sjchandra *    the documentation and/or other materials provided with the
14224110Sjchandra *    distribution.
15224110Sjchandra *
16224110Sjchandra * THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``AS IS'' AND
17224110Sjchandra * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18224110Sjchandra * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19224110Sjchandra * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE
20224110Sjchandra * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21224110Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22224110Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23224110Sjchandra * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24224110Sjchandra * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25224110Sjchandra * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26224110Sjchandra * THE POSSIBILITY OF SUCH DAMAGE.
27224110Sjchandra *
28225394Sjchandra * NETLOGIC_BSD
29224110Sjchandra * $FreeBSD$
30225394Sjchandra */
31224110Sjchandra
32224110Sjchandra#ifndef __XLP_MMU_H__
33227722Sjchandra#define	__XLP_MMU_H__
34224110Sjchandra
35224110Sjchandra#include <mips/nlm/hal/mips-extns.h>
36224110Sjchandra
37225394Sjchandrastatic __inline__ uint32_t
38225394Sjchandranlm_read_c0_config6(void)
39225394Sjchandra{
40225394Sjchandra	uint32_t rv;
41224110Sjchandra
42225394Sjchandra	__asm__ __volatile__ (
43225394Sjchandra		".set	push\n"
44225394Sjchandra		".set	mips64\n"
45225394Sjchandra		"mfc0	%0, $16, 6\n"
46225394Sjchandra		".set	pop\n"
47225394Sjchandra		: "=r" (rv));
48224110Sjchandra
49225394Sjchandra        return rv;
50225394Sjchandra}
51225394Sjchandra
52225394Sjchandrastatic __inline__ void
53225394Sjchandranlm_write_c0_config6(uint32_t value)
54225394Sjchandra{
55225394Sjchandra	__asm__ __volatile__ (
56225394Sjchandra		".set	push\n"
57225394Sjchandra		".set	mips64\n"
58225394Sjchandra		"mtc0	%0, $16, 6\n"
59225394Sjchandra		".set	pop\n"
60225394Sjchandra		: : "r" (value));
61225394Sjchandra}
62225394Sjchandra
63225394Sjchandrastatic __inline__ uint32_t
64225394Sjchandranlm_read_c0_config7(void)
65225394Sjchandra{
66225394Sjchandra	uint32_t rv;
67225394Sjchandra
68225394Sjchandra	__asm__ __volatile__ (
69225394Sjchandra		".set	push\n"
70225394Sjchandra		".set	mips64\n"
71225394Sjchandra		"mfc0	%0, $16, 7\n"
72225394Sjchandra		".set	pop\n"
73225394Sjchandra		: "=r" (rv));
74225394Sjchandra
75225394Sjchandra        return rv;
76225394Sjchandra}
77225394Sjchandra
78225394Sjchandrastatic __inline__ void
79225394Sjchandranlm_write_c0_config7(uint32_t value)
80225394Sjchandra{
81225394Sjchandra	__asm__ __volatile__ (
82225394Sjchandra		".set	push\n"
83225394Sjchandra		".set	mips64\n"
84225394Sjchandra		"mtc0	%0, $16, 7\n"
85225394Sjchandra		".set	pop\n"
86225394Sjchandra		: : "r" (value));
87225394Sjchandra}
88224110Sjchandra/**
89224110Sjchandra * On power on reset, XLP comes up with 64 TLBs.
90224110Sjchandra * Large-variable-tlb's (ELVT) and extended TLB is disabled.
91224110Sjchandra * Enabling large-variable-tlb's sets up the standard
92224110Sjchandra * TLB size from 64 to 128 TLBs.
93224110Sjchandra * Enabling fixed TLB (EFT) sets up an additional 2048 tlbs.
94224110Sjchandra * ELVT + EFT = 128 + 2048 = 2176 TLB entries.
95224110Sjchandra * threads  64-entry-standard-tlb    128-entry-standard-tlb
96224110Sjchandra * per      std-tlb-only| std+EFT  | std-tlb-only| std+EFT
97224110Sjchandra * core                 |          |             |
98224110Sjchandra * --------------------------------------------------------
99224110Sjchandra * 1         64           64+2048     128          128+2048
100224110Sjchandra * 2         64           64+1024      64           64+1024
101224110Sjchandra * 4         32           32+512       32           32+512
102224110Sjchandra *
103224110Sjchandra * 1(G)      64           64+2048     128          128+2048
104224110Sjchandra * 2(G)      128         128+2048     128          128+2048
105224110Sjchandra * 4(G)      128         128+2048     128          128+2048
106224110Sjchandra * (G) = Global mode
107224110Sjchandra */
108224110Sjchandra
109224110Sjchandra
110224110Sjchandra/* en = 1 to enable
111224110Sjchandra * en = 0 to disable
112224110Sjchandra */
113224110Sjchandrastatic __inline__ void nlm_large_variable_tlb_en (int en)
114224110Sjchandra{
115224110Sjchandra	unsigned int val;
116224110Sjchandra
117224110Sjchandra	val = nlm_read_c0_config6();
118224110Sjchandra	val |= (en << 5);
119224110Sjchandra	nlm_write_c0_config6(val);
120224110Sjchandra	return;
121224110Sjchandra}
122224110Sjchandra
123224110Sjchandra/* en = 1 to enable
124224110Sjchandra * en = 0 to disable
125224110Sjchandra */
126225394Sjchandrastatic __inline__ void nlm_pagewalker_en(int en)
127224110Sjchandra{
128224110Sjchandra	unsigned int val;
129224110Sjchandra
130224110Sjchandra	val = nlm_read_c0_config6();
131224110Sjchandra	val |= (en << 3);
132224110Sjchandra	nlm_write_c0_config6(val);
133224110Sjchandra	return;
134224110Sjchandra}
135224110Sjchandra
136224110Sjchandra/* en = 1 to enable
137224110Sjchandra * en = 0 to disable
138224110Sjchandra */
139225394Sjchandrastatic __inline__ void nlm_extended_tlb_en(int en)
140224110Sjchandra{
141224110Sjchandra	unsigned int val;
142224110Sjchandra
143224110Sjchandra	val = nlm_read_c0_config6();
144224110Sjchandra	val |= (en << 2);
145224110Sjchandra	nlm_write_c0_config6(val);
146224110Sjchandra	return;
147224110Sjchandra}
148224110Sjchandra
149224110Sjchandrastatic __inline__ int nlm_get_num_combined_tlbs(void)
150224110Sjchandra{
151224110Sjchandra	return (((nlm_read_c0_config6() >> 16) & 0xffff) + 1);
152224110Sjchandra}
153224110Sjchandra
154224110Sjchandra/* get number of variable TLB entries */
155224110Sjchandrastatic __inline__ int nlm_get_num_vtlbs(void)
156224110Sjchandra{
157224110Sjchandra	return (((nlm_read_c0_config6() >> 6) & 0x3ff) + 1);
158224110Sjchandra}
159224110Sjchandra
160225394Sjchandrastatic __inline__ void nlm_setup_extended_pagemask(int mask)
161224110Sjchandra{
162224110Sjchandra	nlm_write_c0_config7(mask);
163224110Sjchandra}
164224110Sjchandra
165224110Sjchandra#endif
166