Subversion Repositories HelenOS

Rev

Rev 3153 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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