Subversion Repositories HelenOS

Rev

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

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