1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
|
/*-
* Copyright 2003-2011 Netlogic Microsystems (Netlogic). All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
*
* THIS SOFTWARE IS PROVIDED BY Netlogic Microsystems ``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 NETLOGIC OR CONTRIBUTORS 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.
*
* $FreeBSD$
* NETLOGIC_BSD */
#ifndef __XLP_MMU_H__
#define __XLP_MMU_H__
#include <mips/nlm/hal/cop0.h>
#include <mips/nlm/hal/mips-extns.h>
#define XLP_MMU_SETUP_REG 0x400
#define XLP_MMU_LFSRSEED_REG 0x401
#define XLP_MMU_HPW_NUM_PAGE_LVL_REG 0x410
#define XLP_MMU_PGWKR_PGDBASE_REG 0x411
#define XLP_MMU_PGWKR_PGDSHFT_REG 0x412
#define XLP_MMU_PGWKR_PGDMASK_REG 0x413
#define XLP_MMU_PGWKR_PUDSHFT_REG 0x414
#define XLP_MMU_PGWKR_PUDMASK_REG 0x415
#define XLP_MMU_PGWKR_PMDSHFT_REG 0x416
#define XLP_MMU_PGWKR_PMDMASK_REG 0x417
#define XLP_MMU_PGWKR_PTESHFT_REG 0x418
#define XLP_MMU_PGWKR_PTEMASK_REG 0x419
typedef struct hw_pagewalker {
int pgd_present;
int pud_present;
int pmd_present;
int pte_present;
uint64_t pgd_baseaddr;
uint32_t pgd_shift;
uint32_t pgd_mask;
uint32_t pud_shift;
uint32_t pud_mask;
uint32_t pmd_shift;
uint32_t pmd_mask;
uint32_t pte_shift;
uint32_t pte_mask;
} nlm_pagewalker;
/**
* On power on reset, XLP comes up with 64 TLBs.
* Large-variable-tlb's (ELVT) and extended TLB is disabled.
* Enabling large-variable-tlb's sets up the standard
* TLB size from 64 to 128 TLBs.
* Enabling fixed TLB (EFT) sets up an additional 2048 tlbs.
* ELVT + EFT = 128 + 2048 = 2176 TLB entries.
* threads 64-entry-standard-tlb 128-entry-standard-tlb
* per std-tlb-only| std+EFT | std-tlb-only| std+EFT
* core | | |
* --------------------------------------------------------
* 1 64 64+2048 128 128+2048
* 2 64 64+1024 64 64+1024
* 4 32 32+512 32 32+512
*
* 1(G) 64 64+2048 128 128+2048
* 2(G) 128 128+2048 128 128+2048
* 4(G) 128 128+2048 128 128+2048
* (G) = Global mode
*/
/* en = 1 to enable
* en = 0 to disable
*/
static __inline__ void nlm_large_variable_tlb_en (int en)
{
unsigned int val;
val = nlm_read_c0_config6();
val |= (en << 5);
nlm_write_c0_config6(val);
return;
}
/* en = 1 to enable
* en = 0 to disable
*/
static __inline__ void nlm_pagewalker_en (int en)
{
unsigned int val;
val = nlm_read_c0_config6();
val |= (en << 3);
nlm_write_c0_config6(val);
return;
}
/* en = 1 to enable
* en = 0 to disable
*/
static __inline__ void nlm_extended_tlb_en (int en)
{
unsigned int val;
val = nlm_read_c0_config6();
val |= (en << 2);
nlm_write_c0_config6(val);
return;
}
static __inline__ int nlm_get_num_combined_tlbs(void)
{
return (((nlm_read_c0_config6() >> 16) & 0xffff) + 1);
}
/* get number of variable TLB entries */
static __inline__ int nlm_get_num_vtlbs(void)
{
return (((nlm_read_c0_config6() >> 6) & 0x3ff) + 1);
}
static __inline__ void nlm_setup_extended_pagemask (int mask)
{
nlm_write_c0_config7(mask);
}
/* hashindex_en = 1 to enable hash mode, hashindex_en=0 to disable
* global_mode = 1 to enable global mode, global_mode=0 to disable
* clk_gating = 0 to enable clock gating, clk_gating=1 to disable
*/
static __inline__ void nlm_mmu_setup(int hashindex_en, int global_mode,
int clk_gating)
{
/*uint32_t mmusetup = nlm_mfcr(XLP_MMU_SETUP_REG);*/
uint32_t mmusetup = 0;
mmusetup |= (hashindex_en << 13);
mmusetup |= (clk_gating << 3);
mmusetup |= (global_mode << 0);
nlm_mtcr(XLP_MMU_SETUP_REG, mmusetup);
}
static __inline__ void nlm_mmu_lfsr_seed (int thr0_seed, int thr1_seed,
int thr2_seed, int thr3_seed)
{
uint32_t seed = nlm_mfcr(XLP_MMU_LFSRSEED_REG);
seed |= ((thr3_seed & 0x7f) << 23);
seed |= ((thr2_seed & 0x7f) << 16);
seed |= ((thr1_seed & 0x7f) << 7);
seed |= ((thr0_seed & 0x7f) << 0);
nlm_mtcr(XLP_MMU_LFSRSEED_REG, seed);
}
static __inline__ void nlm_pagewalker_setup (nlm_pagewalker *walker)
{
uint64_t val;
if (!walker->pgd_present)
return;
val = nlm_mfcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG);
if (walker->pgd_present)
val |= (1 << 3);
if (walker->pud_present)
val |= (1 << 2);
if (walker->pmd_present)
val |= (1 << 1);
if (walker->pte_present)
val |= (1 << 0);
nlm_mtcr(XLP_MMU_HPW_NUM_PAGE_LVL_REG, val);
nlm_mtcr(XLP_MMU_PGWKR_PGDBASE_REG, walker->pgd_baseaddr);
nlm_mtcr(XLP_MMU_PGWKR_PGDSHFT_REG, walker->pgd_shift);
nlm_mtcr(XLP_MMU_PGWKR_PGDMASK_REG, walker->pgd_mask);
nlm_mtcr(XLP_MMU_PGWKR_PUDSHFT_REG, walker->pud_shift);
nlm_mtcr(XLP_MMU_PGWKR_PUDMASK_REG, walker->pud_mask);
nlm_mtcr(XLP_MMU_PGWKR_PMDSHFT_REG, walker->pmd_shift);
nlm_mtcr(XLP_MMU_PGWKR_PMDMASK_REG, walker->pmd_mask);
nlm_mtcr(XLP_MMU_PGWKR_PTESHFT_REG, walker->pte_shift);
nlm_mtcr(XLP_MMU_PGWKR_PTEMASK_REG, walker->pte_mask);
}
#endif
|