Subversion Repositories HelenOS

Rev

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

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