Subversion Repositories HelenOS

Rev

Rev 3450 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 3450 Rev 3493
1
/*
1
/*
2
 * Copyright (c) 2005 Jakub Jermar
2
 * Copyright (c) 2005 Jakub Jermar
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup sparc64mm  
29
/** @addtogroup sparc64mm  
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#ifndef KERN_sparc64_TLB_H_
35
#ifndef KERN_sparc64_TLB_H_
36
#define KERN_sparc64_TLB_H_
36
#define KERN_sparc64_TLB_H_
37
 
37
 
38
#if defined (US)
38
#if defined (US)
39
#define ITLB_ENTRY_COUNT        64
39
#define ITLB_ENTRY_COUNT        64
40
#define DTLB_ENTRY_COUNT        64
40
#define DTLB_ENTRY_COUNT        64
41
#define DTLB_MAX_LOCKED_ENTRIES     DTLB_ENTRY_COUNT
41
#define DTLB_MAX_LOCKED_ENTRIES     DTLB_ENTRY_COUNT
42
#endif
42
#endif
43
 
43
 
44
/** DT16 is the only of the three DMMU caches that can hold locked entries. */
44
/** DT16 is the only of the three DMMUs that can hold locked entries. */
45
#if defined (US3)
45
#if defined (US3)
46
#define DTLB_MAX_LOCKED_ENTRIES     16
46
#define DTLB_MAX_LOCKED_ENTRIES     16
47
#endif
47
#endif
48
 
48
 
49
#define MEM_CONTEXT_KERNEL      0
49
#define MEM_CONTEXT_KERNEL      0
50
#define MEM_CONTEXT_TEMP        1
50
#define MEM_CONTEXT_TEMP        1
51
 
51
 
52
/** Page sizes. */
52
/** Page sizes. */
53
#define PAGESIZE_8K 0
53
#define PAGESIZE_8K 0
54
#define PAGESIZE_64K    1
54
#define PAGESIZE_64K    1
55
#define PAGESIZE_512K   2
55
#define PAGESIZE_512K   2
56
#define PAGESIZE_4M 3
56
#define PAGESIZE_4M 3
57
 
57
 
58
/** Bit width of the TLB-locked portion of kernel address space. */
58
/** Bit width of the TLB-locked portion of kernel address space. */
59
#define KERNEL_PAGE_WIDTH       22  /* 4M */
59
#define KERNEL_PAGE_WIDTH       22  /* 4M */
60
 
60
 
61
/* TLB Demap Operation types. */
61
/* TLB Demap Operation types. */
62
#define TLB_DEMAP_PAGE      0
62
#define TLB_DEMAP_PAGE      0
63
#define TLB_DEMAP_CONTEXT   1
63
#define TLB_DEMAP_CONTEXT   1
64
#if defined (US3)
64
#if defined (US3)
65
#define TLB_DEMAP_ALL       2
65
#define TLB_DEMAP_ALL       2
66
#endif
66
#endif
67
 
67
 
68
#define TLB_DEMAP_TYPE_SHIFT    6
68
#define TLB_DEMAP_TYPE_SHIFT    6
69
 
69
 
70
/* TLB Demap Operation Context register encodings. */
70
/* TLB Demap Operation Context register encodings. */
71
#define TLB_DEMAP_PRIMARY   0
71
#define TLB_DEMAP_PRIMARY   0
72
#define TLB_DEMAP_SECONDARY 1
72
#define TLB_DEMAP_SECONDARY 1
73
#define TLB_DEMAP_NUCLEUS   2
73
#define TLB_DEMAP_NUCLEUS   2
74
 
74
 
75
/* There are more TLBs in one MMU in US3, their codes are defined here. */
75
/* There are more TLBs in one MMU in US3, their codes are defined here. */
76
#if defined (US3)
76
#if defined (US3)
77
/* D-MMU: one 16-entry TLB and two 512-entry TLBs */
77
/* D-MMU: one 16-entry TLB and two 512-entry TLBs */
78
#define TLB_DT16    0
78
#define TLB_DT16    0
79
#define TLB_DT512_0 2
79
#define TLB_DT512_0 2
80
#define TLB_DT512_1 3
80
#define TLB_DT512_1 3
81
   
81
   
82
/* I-MMU: one 16-entry TLB and one 128-entry TLB */
82
/* I-MMU: one 16-entry TLB and one 128-entry TLB */
83
#define TLB_IT16    0
83
#define TLB_IT16    0
84
#define TLB_IT128   2
84
#define TLB_IT128   2
85
#endif
85
#endif
86
 
86
 
87
#define TLB_DEMAP_CONTEXT_SHIFT 4
87
#define TLB_DEMAP_CONTEXT_SHIFT 4
88
 
88
 
89
/* TLB Tag Access shifts */
89
/* TLB Tag Access shifts */
90
#define TLB_TAG_ACCESS_CONTEXT_SHIFT    0
90
#define TLB_TAG_ACCESS_CONTEXT_SHIFT    0
91
#define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
91
#define TLB_TAG_ACCESS_CONTEXT_MASK ((1 << 13) - 1)
92
#define TLB_TAG_ACCESS_VPN_SHIFT    13
92
#define TLB_TAG_ACCESS_VPN_SHIFT    13
93
 
93
 
94
#ifndef __ASM__
94
#ifndef __ASM__
95
 
95
 
96
#include <arch/mm/tte.h>
96
#include <arch/mm/tte.h>
97
#include <arch/mm/mmu.h>
97
#include <arch/mm/mmu.h>
98
#include <arch/mm/page.h>
98
#include <arch/mm/page.h>
99
#include <arch/asm.h>
99
#include <arch/asm.h>
100
#include <arch/barrier.h>
100
#include <arch/barrier.h>
101
#include <arch/types.h>
101
#include <arch/types.h>
102
 
102
 
103
union tlb_context_reg {
103
union tlb_context_reg {
104
    uint64_t v;
104
    uint64_t v;
105
    struct {
105
    struct {
106
        unsigned long : 51;
106
        unsigned long : 51;
107
        unsigned context : 13;      /**< Context/ASID. */
107
        unsigned context : 13;      /**< Context/ASID. */
108
    } __attribute__ ((packed));
108
    } __attribute__ ((packed));
109
};
109
};
110
typedef union tlb_context_reg tlb_context_reg_t;
110
typedef union tlb_context_reg tlb_context_reg_t;
111
 
111
 
112
/** I-/D-TLB Data In/Access Register type. */
112
/** I-/D-TLB Data In/Access Register type. */
113
typedef tte_data_t tlb_data_t;
113
typedef tte_data_t tlb_data_t;
114
 
114
 
115
/** I-/D-TLB Data Access Address in Alternate Space. */
115
/** I-/D-TLB Data Access Address in Alternate Space. */
116
 
116
 
117
#if defined (US)
117
#if defined (US)
118
 
118
 
119
union tlb_data_access_addr {
119
union tlb_data_access_addr {
120
    uint64_t value;
120
    uint64_t value;
121
    struct {
121
    struct {
122
        uint64_t : 55;
122
        uint64_t : 55;
123
        unsigned tlb_entry : 6;
123
        unsigned tlb_entry : 6;
124
        unsigned : 3;
124
        unsigned : 3;
125
    } __attribute__ ((packed));
125
    } __attribute__ ((packed));
126
};
126
};
127
typedef union tlb_data_access_addr dtlb_data_access_addr_t;
127
typedef union tlb_data_access_addr dtlb_data_access_addr_t;
128
typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
128
typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
129
typedef union tlb_data_access_addr itlb_data_access_addr_t;
129
typedef union tlb_data_access_addr itlb_data_access_addr_t;
130
typedef union tlb_data_access_addr itlb_tag_read_addr_t;
130
typedef union tlb_data_access_addr itlb_tag_read_addr_t;
131
 
131
 
132
#elif defined (US3)
132
#elif defined (US3)
133
 
133
 
134
/*
134
/*
135
 * In US3, I-MMU and D-MMU have different formats of the data
135
 * In US3, I-MMU and D-MMU have different formats of the data
136
 * access register virtual address. In the corresponding
136
 * access register virtual address. In the corresponding
137
 * structures the member variable for the entry number is
137
 * structures the member variable for the entry number is
138
 * called "local_tlb_entry" - it contrast with the "tlb_entry"
138
 * called "local_tlb_entry" - it contrast with the "tlb_entry"
139
 * for the US data access register VA structure. The rationale
139
 * for the US data access register VA structure. The rationale
140
 * behind this is to prevent careless mistakes in the code
140
 * behind this is to prevent careless mistakes in the code
141
 * caused by setting only the entry number and not the TLB
141
 * caused by setting only the entry number and not the TLB
142
 * number in the US3 code (when taking the code from US).
142
 * number in the US3 code (when taking the code from US).
143
 */
143
 */
144
 
144
 
145
union dtlb_data_access_addr {
145
union dtlb_data_access_addr {
146
    uint64_t value;
146
    uint64_t value;
147
    struct {
147
    struct {
148
        uint64_t : 45;
148
        uint64_t : 45;
149
        unsigned : 1;
149
        unsigned : 1;
150
        unsigned tlb_number : 2;
150
        unsigned tlb_number : 2;
151
        unsigned : 4;
151
        unsigned : 4;
152
        unsigned local_tlb_entry : 9;
152
        unsigned local_tlb_entry : 9;
153
        unsigned : 3;
153
        unsigned : 3;
154
    } __attribute__ ((packed));
154
    } __attribute__ ((packed));
155
};
155
};
156
typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
156
typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
157
typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
157
typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
158
 
158
 
159
union itlb_data_access_addr {
159
union itlb_data_access_addr {
160
    uint64_t value;
160
    uint64_t value;
161
    struct {
161
    struct {
162
        uint64_t : 45;
162
        uint64_t : 45;
163
        unsigned : 1;
163
        unsigned : 1;
164
        unsigned tlb_number : 2;
164
        unsigned tlb_number : 2;
165
        unsigned : 6;
165
        unsigned : 6;
166
        unsigned local_tlb_entry : 7;
166
        unsigned local_tlb_entry : 7;
167
        unsigned : 3;
167
        unsigned : 3;
168
    } __attribute__ ((packed));
168
    } __attribute__ ((packed));
169
};
169
};
170
typedef union itlb_data_access_addr itlb_data_access_addr_t;
170
typedef union itlb_data_access_addr itlb_data_access_addr_t;
171
typedef union itlb_data_access_addr itlb_tag_read_addr_t;
171
typedef union itlb_data_access_addr itlb_tag_read_addr_t;
172
 
172
 
173
#endif
173
#endif
174
 
174
 
175
/** I-/D-TLB Tag Read Register. */
175
/** I-/D-TLB Tag Read Register. */
176
union tlb_tag_read_reg {
176
union tlb_tag_read_reg {
177
    // TODO have a look at how non-8kB pages will be treated
177
    // TODO have a look at how non-8kB pages will be treated
178
    uint64_t value;
178
    uint64_t value;
179
    struct {
179
    struct {
180
        uint64_t vpn : 51;  /**< Virtual Address bits 63:13. */
180
        uint64_t vpn : 51;  /**< Virtual Address bits 63:13. */
181
        unsigned context : 13;  /**< Context identifier. */
181
        unsigned context : 13;  /**< Context identifier. */
182
    } __attribute__ ((packed));
182
    } __attribute__ ((packed));
183
};
183
};
184
typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
184
typedef union tlb_tag_read_reg tlb_tag_read_reg_t;
185
typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
185
typedef union tlb_tag_read_reg tlb_tag_access_reg_t;
186
 
186
 
187
 
187
 
188
/** TLB Demap Operation Address. */
188
/** TLB Demap Operation Address. */
189
union tlb_demap_addr {
189
union tlb_demap_addr {
190
    uint64_t value;
190
    uint64_t value;
191
    struct {
191
    struct {
192
        uint64_t vpn: 51;   /**< Virtual Address bits 63:13. */
192
        uint64_t vpn: 51;   /**< Virtual Address bits 63:13. */
193
#if defined (US)
193
#if defined (US)
194
        unsigned : 6;       /**< Ignored. */
194
        unsigned : 6;       /**< Ignored. */
195
        unsigned type : 1;  /**< The type of demap operation. */
195
        unsigned type : 1;  /**< The type of demap operation. */
196
#elif defined (US3)
196
#elif defined (US3)
197
        unsigned : 5;       /**< Ignored. */
197
        unsigned : 5;       /**< Ignored. */
198
        unsigned type: 2;   /**< The type of demap operation. */
198
        unsigned type: 2;   /**< The type of demap operation. */
199
#endif
199
#endif
200
        unsigned context : 2;   /**< Context register selection. */
200
        unsigned context : 2;   /**< Context register selection. */
201
        unsigned : 4;       /**< Zero. */
201
        unsigned : 4;       /**< Zero. */
202
    } __attribute__ ((packed));
202
    } __attribute__ ((packed));
203
};
203
};
204
typedef union tlb_demap_addr tlb_demap_addr_t;
204
typedef union tlb_demap_addr tlb_demap_addr_t;
205
 
205
 
206
/** TLB Synchronous Fault Status Register. */
206
/** TLB Synchronous Fault Status Register. */
207
union tlb_sfsr_reg {
207
union tlb_sfsr_reg {
208
    uint64_t value;
208
    uint64_t value;
209
    struct {
209
    struct {
210
#if defined (US)
210
#if defined (US)
211
        unsigned long : 40; /**< Implementation dependent. */
211
        unsigned long : 40; /**< Implementation dependent. */
212
        unsigned asi : 8;   /**< ASI. */
212
        unsigned asi : 8;   /**< ASI. */
213
        unsigned : 2;
213
        unsigned : 2;
214
        unsigned ft : 7;    /**< Fault type. */
214
        unsigned ft : 7;    /**< Fault type. */
215
#elif defined (US3)
215
#elif defined (US3)
216
        unsigned long : 39; /**< Implementation dependent. */
216
        unsigned long : 39; /**< Implementation dependent. */
217
        unsigned nf : 1;    /**< Non-faulting load. */
217
        unsigned nf : 1;    /**< Non-faulting load. */
218
        unsigned asi : 8;   /**< ASI. */
218
        unsigned asi : 8;   /**< ASI. */
219
        unsigned tm : 1;    /**< I-TLB miss. */
219
        unsigned tm : 1;    /**< I-TLB miss. */
220
        unsigned : 3;       /**< Reserved. */
220
        unsigned : 3;       /**< Reserved. */
221
        unsigned ft : 5;    /**< Fault type. */
221
        unsigned ft : 5;    /**< Fault type. */
222
#endif
222
#endif
223
        unsigned e : 1;     /**< Side-effect bit. */
223
        unsigned e : 1;     /**< Side-effect bit. */
224
        unsigned ct : 2;    /**< Context Register selection. */
224
        unsigned ct : 2;    /**< Context Register selection. */
225
        unsigned pr : 1;    /**< Privilege bit. */
225
        unsigned pr : 1;    /**< Privilege bit. */
226
        unsigned w : 1;     /**< Write bit. */
226
        unsigned w : 1;     /**< Write bit. */
227
        unsigned ow : 1;    /**< Overwrite bit. */
227
        unsigned ow : 1;    /**< Overwrite bit. */
228
        unsigned fv : 1;    /**< Fault Valid bit. */
228
        unsigned fv : 1;    /**< Fault Valid bit. */
229
    } __attribute__ ((packed));
229
    } __attribute__ ((packed));
230
};
230
};
231
typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
231
typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
232
 
232
 
233
/** Read MMU Primary Context Register.
233
/** Read MMU Primary Context Register.
234
 *
234
 *
235
 * @return Current value of Primary Context Register.
235
 * @return Current value of Primary Context Register.
236
 */
236
 */
237
static inline uint64_t mmu_primary_context_read(void)
237
static inline uint64_t mmu_primary_context_read(void)
238
{
238
{
239
    return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
239
    return asi_u64_read(ASI_DMMU, VA_PRIMARY_CONTEXT_REG);
240
}
240
}
241
 
241
 
242
/** Write MMU Primary Context Register.
242
/** Write MMU Primary Context Register.
243
 *
243
 *
244
 * @param v New value of Primary Context Register.
244
 * @param v New value of Primary Context Register.
245
 */
245
 */
246
static inline void mmu_primary_context_write(uint64_t v)
246
static inline void mmu_primary_context_write(uint64_t v)
247
{
247
{
248
    asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
248
    asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v);
249
    flush_pipeline();
249
    flush_pipeline();
250
}
250
}
251
 
251
 
252
/** Read MMU Secondary Context Register.
252
/** Read MMU Secondary Context Register.
253
 *
253
 *
254
 * @return Current value of Secondary Context Register.
254
 * @return Current value of Secondary Context Register.
255
 */
255
 */
256
static inline uint64_t mmu_secondary_context_read(void)
256
static inline uint64_t mmu_secondary_context_read(void)
257
{
257
{
258
    return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
258
    return asi_u64_read(ASI_DMMU, VA_SECONDARY_CONTEXT_REG);
259
}
259
}
260
 
260
 
261
/** Write MMU Primary Context Register.
261
/** Write MMU Primary Context Register.
262
 *
262
 *
263
 * @param v New value of Primary Context Register.
263
 * @param v New value of Primary Context Register.
264
 */
264
 */
265
static inline void mmu_secondary_context_write(uint64_t v)
265
static inline void mmu_secondary_context_write(uint64_t v)
266
{
266
{
267
    asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
267
    asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v);
268
    flush_pipeline();
268
    flush_pipeline();
269
}
269
}
270
 
270
 
271
#if defined (US)
271
#if defined (US)
272
 
272
 
273
/** Read IMMU TLB Data Access Register.
273
/** Read IMMU TLB Data Access Register.
274
 *
274
 *
275
 * @param entry TLB Entry index.
275
 * @param entry TLB Entry index.
276
 *
276
 *
277
 * @return Current value of specified IMMU TLB Data Access Register.
277
 * @return Current value of specified IMMU TLB Data Access Register.
278
 */
278
 */
279
static inline uint64_t itlb_data_access_read(index_t entry)
279
static inline uint64_t itlb_data_access_read(index_t entry)
280
{
280
{
281
    itlb_data_access_addr_t reg;
281
    itlb_data_access_addr_t reg;
282
   
282
   
283
    reg.value = 0;
283
    reg.value = 0;
284
    reg.tlb_entry = entry;
284
    reg.tlb_entry = entry;
285
    return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
285
    return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
286
}
286
}
287
 
287
 
288
/** Write IMMU TLB Data Access Register.
288
/** Write IMMU TLB Data Access Register.
289
 *
289
 *
290
 * @param entry TLB Entry index.
290
 * @param entry TLB Entry index.
291
 * @param value Value to be written.
291
 * @param value Value to be written.
292
 */
292
 */
293
static inline void itlb_data_access_write(index_t entry, uint64_t value)
293
static inline void itlb_data_access_write(index_t entry, uint64_t value)
294
{
294
{
295
    itlb_data_access_addr_t reg;
295
    itlb_data_access_addr_t reg;
296
   
296
   
297
    reg.value = 0;
297
    reg.value = 0;
298
    reg.tlb_entry = entry;
298
    reg.tlb_entry = entry;
299
    asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
299
    asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
300
    flush_pipeline();
300
    flush_pipeline();
301
}
301
}
302
 
302
 
303
/** Read DMMU TLB Data Access Register.
303
/** Read DMMU TLB Data Access Register.
304
 *
304
 *
305
 * @param entry TLB Entry index.
305
 * @param entry TLB Entry index.
306
 *
306
 *
307
 * @return Current value of specified DMMU TLB Data Access Register.
307
 * @return Current value of specified DMMU TLB Data Access Register.
308
 */
308
 */
309
static inline uint64_t dtlb_data_access_read(index_t entry)
309
static inline uint64_t dtlb_data_access_read(index_t entry)
310
{
310
{
311
    dtlb_data_access_addr_t reg;
311
    dtlb_data_access_addr_t reg;
312
   
312
   
313
    reg.value = 0;
313
    reg.value = 0;
314
    reg.tlb_entry = entry;
314
    reg.tlb_entry = entry;
315
    return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
315
    return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
316
}
316
}
317
 
317
 
318
/** Write DMMU TLB Data Access Register.
318
/** Write DMMU TLB Data Access Register.
319
 *
319
 *
320
 * @param entry TLB Entry index.
320
 * @param entry TLB Entry index.
321
 * @param value Value to be written.
321
 * @param value Value to be written.
322
 */
322
 */
323
static inline void dtlb_data_access_write(index_t entry, uint64_t value)
323
static inline void dtlb_data_access_write(index_t entry, uint64_t value)
324
{
324
{
325
    dtlb_data_access_addr_t reg;
325
    dtlb_data_access_addr_t reg;
326
   
326
   
327
    reg.value = 0;
327
    reg.value = 0;
328
    reg.tlb_entry = entry;
328
    reg.tlb_entry = entry;
329
    asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
329
    asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
330
    membar();
330
    membar();
331
}
331
}
332
 
332
 
333
/** Read IMMU TLB Tag Read Register.
333
/** Read IMMU TLB Tag Read Register.
334
 *
334
 *
335
 * @param entry TLB Entry index.
335
 * @param entry TLB Entry index.
336
 *
336
 *
337
 * @return Current value of specified IMMU TLB Tag Read Register.
337
 * @return Current value of specified IMMU TLB Tag Read Register.
338
 */
338
 */
339
static inline uint64_t itlb_tag_read_read(index_t entry)
339
static inline uint64_t itlb_tag_read_read(index_t entry)
340
{
340
{
341
    itlb_tag_read_addr_t tag;
341
    itlb_tag_read_addr_t tag;
342
 
342
 
343
    tag.value = 0;
343
    tag.value = 0;
344
    tag.tlb_entry = entry;
344
    tag.tlb_entry = entry;
345
    return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
345
    return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
346
}
346
}
347
 
347
 
348
/** Read DMMU TLB Tag Read Register.
348
/** Read DMMU TLB Tag Read Register.
349
 *
349
 *
350
 * @param entry TLB Entry index.
350
 * @param entry TLB Entry index.
351
 *
351
 *
352
 * @return Current value of specified DMMU TLB Tag Read Register.
352
 * @return Current value of specified DMMU TLB Tag Read Register.
353
 */
353
 */
354
static inline uint64_t dtlb_tag_read_read(index_t entry)
354
static inline uint64_t dtlb_tag_read_read(index_t entry)
355
{
355
{
356
    dtlb_tag_read_addr_t tag;
356
    dtlb_tag_read_addr_t tag;
357
 
357
 
358
    tag.value = 0;
358
    tag.value = 0;
359
    tag.tlb_entry = entry;
359
    tag.tlb_entry = entry;
360
    return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
360
    return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
361
}
361
}
362
 
362
 
363
#elif defined (US3)
363
#elif defined (US3)
364
 
364
 
365
 
365
 
366
/** Read IMMU TLB Data Access Register.
366
/** Read IMMU TLB Data Access Register.
367
 *
367
 *
368
 * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
368
 * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
369
 * @param entry TLB Entry index.
369
 * @param entry TLB Entry index.
370
 *
370
 *
371
 * @return Current value of specified IMMU TLB Data Access Register.
371
 * @return Current value of specified IMMU TLB Data Access Register.
372
 */
372
 */
373
static inline uint64_t itlb_data_access_read(int tlb, index_t entry)
373
static inline uint64_t itlb_data_access_read(int tlb, index_t entry)
374
{
374
{
375
    itlb_data_access_addr_t reg;
375
    itlb_data_access_addr_t reg;
376
   
376
   
377
    reg.value = 0;
377
    reg.value = 0;
378
    reg.tlb_number = tlb;
378
    reg.tlb_number = tlb;
379
    reg.local_tlb_entry = entry;
379
    reg.local_tlb_entry = entry;
380
    return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
380
    return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
381
}
381
}
382
 
382
 
383
/** Write IMMU TLB Data Access Register.
383
/** Write IMMU TLB Data Access Register.
384
 * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
384
 * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
385
 * @param entry TLB Entry index.
385
 * @param entry TLB Entry index.
386
 * @param value Value to be written.
386
 * @param value Value to be written.
387
 */
387
 */
388
static inline void itlb_data_access_write(int tlb, index_t entry, uint64_t value)
388
static inline void itlb_data_access_write(int tlb, index_t entry, uint64_t value)
389
{
389
{
390
    itlb_data_access_addr_t reg;
390
    itlb_data_access_addr_t reg;
391
   
391
   
392
    reg.value = 0;
392
    reg.value = 0;
393
    reg.tlb_number = tlb;
393
    reg.tlb_number = tlb;
394
    reg.local_tlb_entry = entry;
394
    reg.local_tlb_entry = entry;
395
    asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
395
    asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
396
    flush_pipeline();
396
    flush_pipeline();
397
}
397
}
398
 
398
 
399
/** Read DMMU TLB Data Access Register.
399
/** Read DMMU TLB Data Access Register.
400
 *
400
 *
401
 * @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)
401
 * @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)
402
 * @param entry TLB Entry index.
402
 * @param entry TLB Entry index.
403
 *
403
 *
404
 * @return Current value of specified DMMU TLB Data Access Register.
404
 * @return Current value of specified DMMU TLB Data Access Register.
405
 */
405
 */
406
static inline uint64_t dtlb_data_access_read(int tlb, index_t entry)
406
static inline uint64_t dtlb_data_access_read(int tlb, index_t entry)
407
{
407
{
408
    dtlb_data_access_addr_t reg;
408
    dtlb_data_access_addr_t reg;
409
   
409
   
410
    reg.value = 0;
410
    reg.value = 0;
411
    reg.tlb_number = tlb;
411
    reg.tlb_number = tlb;
412
    reg.local_tlb_entry = entry;
412
    reg.local_tlb_entry = entry;
413
    return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
413
    return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
414
}
414
}
415
 
415
 
416
/** Write DMMU TLB Data Access Register.
416
/** Write DMMU TLB Data Access Register.
417
 *
417
 *
418
 * @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)  
418
 * @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)  
419
 * @param entry TLB Entry index.
419
 * @param entry TLB Entry index.
420
 * @param value Value to be written.
420
 * @param value Value to be written.
421
 */
421
 */
422
static inline void dtlb_data_access_write(int tlb, index_t entry, uint64_t value)
422
static inline void dtlb_data_access_write(int tlb, index_t entry, uint64_t value)
423
{
423
{
424
    dtlb_data_access_addr_t reg;
424
    dtlb_data_access_addr_t reg;
425
   
425
   
426
    reg.value = 0;
426
    reg.value = 0;
427
    reg.tlb_number = tlb;
427
    reg.tlb_number = tlb;
428
    reg.local_tlb_entry = entry;
428
    reg.local_tlb_entry = entry;
429
    asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
429
    asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
430
    membar();
430
    membar();
431
}
431
}
432
 
432
 
433
/** Read IMMU TLB Tag Read Register.
433
/** Read IMMU TLB Tag Read Register.
434
 *
434
 *
435
 * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
435
 * @param tlb TLB number (one of TLB_IT16 or TLB_IT128)
436
 * @param entry TLB Entry index.
436
 * @param entry TLB Entry index.
437
 *
437
 *
438
 * @return Current value of specified IMMU TLB Tag Read Register.
438
 * @return Current value of specified IMMU TLB Tag Read Register.
439
 */
439
 */
440
static inline uint64_t itlb_tag_read_read(int tlb, index_t entry)
440
static inline uint64_t itlb_tag_read_read(int tlb, index_t entry)
441
{
441
{
442
    itlb_tag_read_addr_t tag;
442
    itlb_tag_read_addr_t tag;
443
 
443
 
444
    tag.value = 0;
444
    tag.value = 0;
445
    tag.tlb_number = tlb;
445
    tag.tlb_number = tlb;
446
    tag.local_tlb_entry = entry;
446
    tag.local_tlb_entry = entry;
447
    return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
447
    return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
448
}
448
}
449
 
449
 
450
/** Read DMMU TLB Tag Read Register.
450
/** Read DMMU TLB Tag Read Register.
451
 *
451
 *
452
 * @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)  
452
 * @param tlb TLB number (one of TLB_DT16, TLB_DT512_0, TLB_DT512_1)  
453
 * @param entry TLB Entry index.
453
 * @param entry TLB Entry index.
454
 *
454
 *
455
 * @return Current value of specified DMMU TLB Tag Read Register.
455
 * @return Current value of specified DMMU TLB Tag Read Register.
456
 */
456
 */
457
static inline uint64_t dtlb_tag_read_read(int tlb, index_t entry)
457
static inline uint64_t dtlb_tag_read_read(int tlb, index_t entry)
458
{
458
{
459
    dtlb_tag_read_addr_t tag;
459
    dtlb_tag_read_addr_t tag;
460
 
460
 
461
    tag.value = 0;
461
    tag.value = 0;
462
    tag.tlb_number = tlb;
462
    tag.tlb_number = tlb;
463
    tag.local_tlb_entry = entry;
463
    tag.local_tlb_entry = entry;
464
    return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
464
    return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
465
}
465
}
466
 
466
 
467
#endif
467
#endif
468
 
468
 
469
 
469
 
470
/** Write IMMU TLB Tag Access Register.
470
/** Write IMMU TLB Tag Access Register.
471
 *
471
 *
472
 * @param v Value to be written.
472
 * @param v Value to be written.
473
 */
473
 */
474
static inline void itlb_tag_access_write(uint64_t v)
474
static inline void itlb_tag_access_write(uint64_t v)
475
{
475
{
476
    asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
476
    asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v);
477
    flush_pipeline();
477
    flush_pipeline();
478
}
478
}
479
 
479
 
480
/** Read IMMU TLB Tag Access Register.
480
/** Read IMMU TLB Tag Access Register.
481
 *
481
 *
482
 * @return Current value of IMMU TLB Tag Access Register.
482
 * @return Current value of IMMU TLB Tag Access Register.
483
 */
483
 */
484
static inline uint64_t itlb_tag_access_read(void)
484
static inline uint64_t itlb_tag_access_read(void)
485
{
485
{
486
    return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
486
    return asi_u64_read(ASI_IMMU, VA_IMMU_TAG_ACCESS);
487
}
487
}
488
 
488
 
489
/** Write DMMU TLB Tag Access Register.
489
/** Write DMMU TLB Tag Access Register.
490
 *
490
 *
491
 * @param v Value to be written.
491
 * @param v Value to be written.
492
 */
492
 */
493
static inline void dtlb_tag_access_write(uint64_t v)
493
static inline void dtlb_tag_access_write(uint64_t v)
494
{
494
{
495
    asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
495
    asi_u64_write(ASI_DMMU, VA_DMMU_TAG_ACCESS, v);
496
    membar();
496
    membar();
497
}
497
}
498
 
498
 
499
/** Read DMMU TLB Tag Access Register.
499
/** Read DMMU TLB Tag Access Register.
500
 *
500
 *
501
 * @return Current value of DMMU TLB Tag Access Register.
501
 * @return Current value of DMMU TLB Tag Access Register.
502
 */
502
 */
503
static inline uint64_t dtlb_tag_access_read(void)
503
static inline uint64_t dtlb_tag_access_read(void)
504
{
504
{
505
    return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
505
    return asi_u64_read(ASI_DMMU, VA_DMMU_TAG_ACCESS);
506
}
506
}
507
 
507
 
508
 
508
 
509
/** Write IMMU TLB Data in Register.
509
/** Write IMMU TLB Data in Register.
510
 *
510
 *
511
 * @param v Value to be written.
511
 * @param v Value to be written.
512
 */
512
 */
513
static inline void itlb_data_in_write(uint64_t v)
513
static inline void itlb_data_in_write(uint64_t v)
514
{
514
{
515
    asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
515
    asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v);
516
    flush_pipeline();
516
    flush_pipeline();
517
}
517
}
518
 
518
 
519
/** Write DMMU TLB Data in Register.
519
/** Write DMMU TLB Data in Register.
520
 *
520
 *
521
 * @param v Value to be written.
521
 * @param v Value to be written.
522
 */
522
 */
523
static inline void dtlb_data_in_write(uint64_t v)
523
static inline void dtlb_data_in_write(uint64_t v)
524
{
524
{
525
    asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
525
    asi_u64_write(ASI_DTLB_DATA_IN_REG, 0, v);
526
    membar();
526
    membar();
527
}
527
}
528
 
528
 
529
/** Read ITLB Synchronous Fault Status Register.
529
/** Read ITLB Synchronous Fault Status Register.
530
 *
530
 *
531
 * @return Current content of I-SFSR register.
531
 * @return Current content of I-SFSR register.
532
 */
532
 */
533
static inline uint64_t itlb_sfsr_read(void)
533
static inline uint64_t itlb_sfsr_read(void)
534
{
534
{
535
    return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
535
    return asi_u64_read(ASI_IMMU, VA_IMMU_SFSR);
536
}
536
}
537
 
537
 
538
/** Write ITLB Synchronous Fault Status Register.
538
/** Write ITLB Synchronous Fault Status Register.
539
 *
539
 *
540
 * @param v New value of I-SFSR register.
540
 * @param v New value of I-SFSR register.
541
 */
541
 */
542
static inline void itlb_sfsr_write(uint64_t v)
542
static inline void itlb_sfsr_write(uint64_t v)
543
{
543
{
544
    asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
544
    asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v);
545
    flush_pipeline();
545
    flush_pipeline();
546
}
546
}
547
 
547
 
548
/** Read DTLB Synchronous Fault Status Register.
548
/** Read DTLB Synchronous Fault Status Register.
549
 *
549
 *
550
 * @return Current content of D-SFSR register.
550
 * @return Current content of D-SFSR register.
551
 */
551
 */
552
static inline uint64_t dtlb_sfsr_read(void)
552
static inline uint64_t dtlb_sfsr_read(void)
553
{
553
{
554
    return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
554
    return asi_u64_read(ASI_DMMU, VA_DMMU_SFSR);
555
}
555
}
556
 
556
 
557
/** Write DTLB Synchronous Fault Status Register.
557
/** Write DTLB Synchronous Fault Status Register.
558
 *
558
 *
559
 * @param v New value of D-SFSR register.
559
 * @param v New value of D-SFSR register.
560
 */
560
 */
561
static inline void dtlb_sfsr_write(uint64_t v)
561
static inline void dtlb_sfsr_write(uint64_t v)
562
{
562
{
563
    asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
563
    asi_u64_write(ASI_DMMU, VA_DMMU_SFSR, v);
564
    membar();
564
    membar();
565
}
565
}
566
 
566
 
567
/** Read DTLB Synchronous Fault Address Register.
567
/** Read DTLB Synchronous Fault Address Register.
568
 *
568
 *
569
 * @return Current content of D-SFAR register.
569
 * @return Current content of D-SFAR register.
570
 */
570
 */
571
static inline uint64_t dtlb_sfar_read(void)
571
static inline uint64_t dtlb_sfar_read(void)
572
{
572
{
573
    return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
573
    return asi_u64_read(ASI_DMMU, VA_DMMU_SFAR);
574
}
574
}
575
 
575
 
576
/** Perform IMMU TLB Demap Operation.
576
/** Perform IMMU TLB Demap Operation.
577
 *
577
 *
578
 * @param type
578
 * @param type
579
 *  Selects between context and page demap
579
 *  Selects between context and page demap
580
 *  (and entire MMU demap on US-III).
580
 *  (and entire MMU demap on US-III).
581
 * @param context_encoding Specifies which Context register has Context ID for
581
 * @param context_encoding Specifies which Context register has Context ID for
582
 *  demap.
582
 *  demap.
583
 * @param page Address which is on the page to be demapped.
583
 * @param page Address which is on the page to be demapped.
584
 */
584
 */
585
static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
585
static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
586
{
586
{
587
    tlb_demap_addr_t da;
587
    tlb_demap_addr_t da;
588
    page_address_t pg;
588
    page_address_t pg;
589
   
589
   
590
    da.value = 0;
590
    da.value = 0;
591
    pg.address = page;
591
    pg.address = page;
592
   
592
   
593
    da.type = type;
593
    da.type = type;
594
    da.context = context_encoding;
594
    da.context = context_encoding;
595
    da.vpn = pg.vpn;
595
    da.vpn = pg.vpn;
596
   
596
   
597
    asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
597
    asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
598
                             * address within the
598
                             * address within the
599
                             * ASI */
599
                             * ASI */
600
    flush_pipeline();
600
    flush_pipeline();
601
}
601
}
602
 
602
 
603
/** Perform DMMU TLB Demap Operation.
603
/** Perform DMMU TLB Demap Operation.
604
 *
604
 *
605
 * @param type
605
 * @param type
606
 *  Selects between context and page demap
606
 *  Selects between context and page demap
607
 *  (and entire MMU demap on US-III).
607
 *  (and entire MMU demap on US-III).
608
 * @param context_encoding Specifies which Context register has Context ID for
608
 * @param context_encoding Specifies which Context register has Context ID for
609
 *   demap.
609
 *   demap.
610
 * @param page Address which is on the page to be demapped.
610
 * @param page Address which is on the page to be demapped.
611
 */
611
 */
612
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
612
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
613
{
613
{
614
    tlb_demap_addr_t da;
614
    tlb_demap_addr_t da;
615
    page_address_t pg;
615
    page_address_t pg;
616
   
616
   
617
    da.value = 0;
617
    da.value = 0;
618
    pg.address = page;
618
    pg.address = page;
619
   
619
   
620
    da.type = type;
620
    da.type = type;
621
    da.context = context_encoding;
621
    da.context = context_encoding;
622
    da.vpn = pg.vpn;
622
    da.vpn = pg.vpn;
623
   
623
   
624
    asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
624
    asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
625
                             * address within the
625
                             * address within the
626
                             * ASI */
626
                             * ASI */
627
    membar();
627
    membar();
628
}
628
}
629
 
629
 
630
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
630
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
631
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
631
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
632
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
632
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
633
 
633
 
634
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
634
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
635
 
635
 
636
extern void dump_sfsr_and_sfar(void);
636
extern void dump_sfsr_and_sfar(void);
637
 
637
 
638
#endif /* !def __ASM__ */
638
#endif /* !def __ASM__ */
639
 
639
 
640
#endif
640
#endif
641
 
641
 
642
/** @}
642
/** @}
643
 */
-
 
644
643
 */
-
 
644