Subversion Repositories HelenOS

Rev

Rev 3835 | Rev 3993 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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