source: mainline/kernel/arch/sparc64/src/mm/sun4u/tlb.c@ d99c1d2

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d99c1d2 was d99c1d2, checked in by Martin Decky <martin@…>, 15 years ago

use [u]int{8|16|32|64}_t type definitions as detected by the autotool
replace direct usage of arch/types.h with typedefs.h

  • Property mode set to 100644
File size: 15.8 KB
RevLine 
[0d04024]1/*
[df4ed85]2 * Copyright (c) 2005 Jakub Jermar
[0d04024]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
[10b890b]29/** @addtogroup sparc64mm
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[0d04024]35#include <arch/mm/tlb.h>
36#include <mm/tlb.h>
[f47fd19]37#include <mm/as.h>
38#include <mm/asid.h>
[0cfc4d38]39#include <arch/mm/frame.h>
40#include <arch/mm/page.h>
41#include <arch/mm/mmu.h>
[f47fd19]42#include <arch/interrupt.h>
[e2bf639]43#include <interrupt.h>
[f47fd19]44#include <arch.h>
[0d04024]45#include <print.h>
[d99c1d2]46#include <typedefs.h>
[0cfc4d38]47#include <config.h>
[49b6d32]48#include <arch/trap/trap.h>
[7bb6b06]49#include <arch/trap/exception.h>
[008029d]50#include <panic.h>
[b6fba84]51#include <arch/asm.h>
[387416b]52#include <genarch/mm/page_ht.h>
[02f441c0]53
[29b2bbf]54#ifdef CONFIG_TSB
55#include <arch/mm/tsb.h>
56#endif
57
[98000fb]58static void dtlb_pte_copy(pte_t *, size_t, bool);
59static void itlb_pte_copy(pte_t *, size_t);
[965dc18]60static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
61static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
62 const char *);
63static void do_fast_data_access_protection_fault(istate_t *,
64 tlb_tag_access_reg_t, const char *);
[f47fd19]65
[a000878c]66const char *context_encoding[] = {
[b6fba84]67 "Primary",
68 "Secondary",
69 "Nucleus",
70 "Reserved"
71};
[0d04024]72
73void tlb_arch_init(void)
74{
[c6e314a]75 /*
[c23baab]76 * Invalidate all non-locked DTLB and ITLB entries.
[c6e314a]77 */
[c23baab]78 tlb_invalidate_all();
[8cee705]79
80 /*
81 * Clear both SFSRs.
82 */
83 dtlb_sfsr_write(0);
84 itlb_sfsr_write(0);
[97f1691]85}
[b6fba84]86
[97f1691]87/** Insert privileged mapping into DMMU TLB.
88 *
[965dc18]89 * @param page Virtual page address.
90 * @param frame Physical frame address.
91 * @param pagesize Page size.
92 * @param locked True for permanent mappings, false otherwise.
93 * @param cacheable True if the mapping is cacheable, false otherwise.
[97f1691]94 */
[2057572]95void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
96 bool locked, bool cacheable)
[97f1691]97{
98 tlb_tag_access_reg_t tag;
99 tlb_data_t data;
100 page_address_t pg;
101 frame_address_t fr;
[b6fba84]102
[97f1691]103 pg.address = page;
104 fr.address = frame;
[02f441c0]105
[965dc18]106 tag.context = ASID_KERNEL;
[02f441c0]107 tag.vpn = pg.vpn;
108
109 dtlb_tag_access_write(tag.value);
110
111 data.value = 0;
112 data.v = true;
[97f1691]113 data.size = pagesize;
[02f441c0]114 data.pfn = fr.pfn;
[97f1691]115 data.l = locked;
116 data.cp = cacheable;
[92778f2]117#ifdef CONFIG_VIRT_IDX_DCACHE
[97f1691]118 data.cv = cacheable;
[92778f2]119#endif /* CONFIG_VIRT_IDX_DCACHE */
[02f441c0]120 data.p = true;
121 data.w = true;
[d681c17]122 data.g = false;
[02f441c0]123
124 dtlb_data_in_write(data.value);
[0d04024]125}
126
[a7961271]127/** Copy PTE to TLB.
128 *
[965dc18]129 * @param t Page Table Entry to be copied.
130 * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
131 * @param ro If true, the entry will be created read-only, regardless
132 * of its w field.
[a7961271]133 */
[98000fb]134void dtlb_pte_copy(pte_t *t, size_t index, bool ro)
[a7961271]135{
136 tlb_tag_access_reg_t tag;
137 tlb_data_t data;
138 page_address_t pg;
139 frame_address_t fr;
140
[2057572]141 pg.address = t->page + (index << MMU_PAGE_WIDTH);
142 fr.address = t->frame + (index << MMU_PAGE_WIDTH);
[a7961271]143
144 tag.value = 0;
145 tag.context = t->as->asid;
146 tag.vpn = pg.vpn;
[2057572]147
[a7961271]148 dtlb_tag_access_write(tag.value);
[2057572]149
[a7961271]150 data.value = 0;
151 data.v = true;
152 data.size = PAGESIZE_8K;
153 data.pfn = fr.pfn;
154 data.l = false;
155 data.cp = t->c;
[92778f2]156#ifdef CONFIG_VIRT_IDX_DCACHE
[a7961271]157 data.cv = t->c;
[92778f2]158#endif /* CONFIG_VIRT_IDX_DCACHE */
[cfa70add]159 data.p = t->k; /* p like privileged */
[a7961271]160 data.w = ro ? false : t->w;
161 data.g = t->g;
[2057572]162
[a7961271]163 dtlb_data_in_write(data.value);
164}
165
[29b2bbf]166/** Copy PTE to ITLB.
167 *
[965dc18]168 * @param t Page Table Entry to be copied.
169 * @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
[29b2bbf]170 */
[98000fb]171void itlb_pte_copy(pte_t *t, size_t index)
[f47fd19]172{
[a7961271]173 tlb_tag_access_reg_t tag;
174 tlb_data_t data;
175 page_address_t pg;
176 frame_address_t fr;
177
[2057572]178 pg.address = t->page + (index << MMU_PAGE_WIDTH);
179 fr.address = t->frame + (index << MMU_PAGE_WIDTH);
[a7961271]180
181 tag.value = 0;
182 tag.context = t->as->asid;
183 tag.vpn = pg.vpn;
184
185 itlb_tag_access_write(tag.value);
186
187 data.value = 0;
188 data.v = true;
189 data.size = PAGESIZE_8K;
190 data.pfn = fr.pfn;
191 data.l = false;
192 data.cp = t->c;
[cfa70add]193 data.p = t->k; /* p like privileged */
[a7961271]194 data.w = false;
195 data.g = t->g;
196
197 itlb_data_in_write(data.value);
[f47fd19]198}
199
[008029d]200/** ITLB miss handler. */
[36f19c0]201void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
[008029d]202{
[2bf4936]203 uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
[98000fb]204 size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
[a7961271]205 pte_t *t;
206
207 page_table_lock(AS, true);
[2bf4936]208 t = page_mapping_find(AS, page_16k);
[a7961271]209 if (t && PTE_EXECUTABLE(t)) {
210 /*
211 * The mapping was found in the software page hash table.
212 * Insert it into ITLB.
213 */
214 t->a = true;
[2057572]215 itlb_pte_copy(t, index);
[29b2bbf]216#ifdef CONFIG_TSB
[2057572]217 itsb_pte_copy(t, index);
[29b2bbf]218#endif
[a7961271]219 page_table_unlock(AS, true);
220 } else {
221 /*
[771cd22]222 * Forward the page fault to the address space page fault
223 * handler.
[a7961271]224 */
225 page_table_unlock(AS, true);
[2bf4936]226 if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
227 AS_PF_FAULT) {
[771cd22]228 do_fast_instruction_access_mmu_miss_fault(istate,
[3ee8a075]229 __func__);
[a7961271]230 }
231 }
[008029d]232}
233
[f47fd19]234/** DTLB miss handler.
235 *
[771cd22]236 * Note that some faults (e.g. kernel faults) were already resolved by the
237 * low-level, assembly language part of the fast_data_access_mmu_miss handler.
[36f19c0]238 *
[965dc18]239 * @param tag Content of the TLB Tag Access register as it existed
240 * when the trap happened. This is to prevent confusion
241 * created by clobbered Tag Access register during a nested
242 * DTLB miss.
243 * @param istate Interrupted state saved on the stack.
[f47fd19]244 */
[36f19c0]245void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
[008029d]246{
[2bf4936]247 uintptr_t page_8k;
248 uintptr_t page_16k;
[98000fb]249 size_t index;
[f47fd19]250 pte_t *t;
[7cb53f62]251
[2bf4936]252 page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
253 page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
[2057572]254 index = tag.vpn % MMU_PAGES_PER_PAGE;
[fd85ae5]255
[f47fd19]256 if (tag.context == ASID_KERNEL) {
257 if (!tag.vpn) {
258 /* NULL access in kernel */
[771cd22]259 do_fast_data_access_mmu_miss_fault(istate, tag,
[3ee8a075]260 __func__);
[2bf4936]261 } else if (page_8k >= end_of_identity) {
262 /*
263 * The kernel is accessing the I/O space.
264 * We still do identity mapping for I/O,
265 * but without caching.
266 */
267 dtlb_insert_mapping(page_8k, KA2PA(page_8k),
268 PAGESIZE_8K, false, false);
269 return;
[f47fd19]270 }
[771cd22]271 do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
[2057572]272 "kernel page fault.");
[68656282]273 }
274
[f47fd19]275 page_table_lock(AS, true);
[2bf4936]276 t = page_mapping_find(AS, page_16k);
[f47fd19]277 if (t) {
278 /*
279 * The mapping was found in the software page hash table.
280 * Insert it into DTLB.
281 */
[a7961271]282 t->a = true;
[2057572]283 dtlb_pte_copy(t, index, true);
[29b2bbf]284#ifdef CONFIG_TSB
[2057572]285 dtsb_pte_copy(t, index, true);
[29b2bbf]286#endif
[f47fd19]287 page_table_unlock(AS, true);
288 } else {
289 /*
[2057572]290 * Forward the page fault to the address space page fault
291 * handler.
[f47fd19]292 */
293 page_table_unlock(AS, true);
[2bf4936]294 if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
295 AS_PF_FAULT) {
[771cd22]296 do_fast_data_access_mmu_miss_fault(istate, tag,
[3ee8a075]297 __func__);
[f47fd19]298 }
299 }
[008029d]300}
301
[36f19c0]302/** DTLB protection fault handler.
303 *
[965dc18]304 * @param tag Content of the TLB Tag Access register as it existed
305 * when the trap happened. This is to prevent confusion
306 * created by clobbered Tag Access register during a nested
307 * DTLB miss.
308 * @param istate Interrupted state saved on the stack.
[36f19c0]309 */
310void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
[008029d]311{
[2bf4936]312 uintptr_t page_16k;
[98000fb]313 size_t index;
[e0b241f]314 pte_t *t;
315
[2bf4936]316 page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
[2057572]317 index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */
[e0b241f]318
319 page_table_lock(AS, true);
[2bf4936]320 t = page_mapping_find(AS, page_16k);
[e0b241f]321 if (t && PTE_WRITABLE(t)) {
322 /*
[771cd22]323 * The mapping was found in the software page hash table and is
324 * writable. Demap the old mapping and insert an updated mapping
325 * into DTLB.
[e0b241f]326 */
327 t->a = true;
328 t->d = true;
[2057572]329 dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
[2bf4936]330 page_16k + index * MMU_PAGE_SIZE);
[2057572]331 dtlb_pte_copy(t, index, false);
[29b2bbf]332#ifdef CONFIG_TSB
[2057572]333 dtsb_pte_copy(t, index, false);
[29b2bbf]334#endif
[e0b241f]335 page_table_unlock(AS, true);
336 } else {
337 /*
[771cd22]338 * Forward the page fault to the address space page fault
339 * handler.
[e0b241f]340 */
341 page_table_unlock(AS, true);
[2bf4936]342 if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
343 AS_PF_FAULT) {
[771cd22]344 do_fast_data_access_protection_fault(istate, tag,
[3ee8a075]345 __func__);
[e0b241f]346 }
347 }
[008029d]348}
349
[965dc18]350/** Print TLB entry (for debugging purposes).
351 *
352 * The diag field has been left out in order to make this function more generic
353 * (there is no diag field in US3 architeture).
354 *
355 * @param i TLB entry number
356 * @param t TLB entry tag
357 * @param d TLB entry data
358 */
359static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
360{
361 printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
362 "ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
363 "cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
364 t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
365 d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
366}
367
368#if defined (US)
369
[0d04024]370/** Print contents of both TLBs. */
371void tlb_print(void)
372{
373 int i;
374 tlb_data_t d;
375 tlb_tag_read_reg_t t;
376
377 printf("I-TLB contents:\n");
378 for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
379 d.value = itlb_data_access_read(i);
[c52ed6b]380 t.value = itlb_tag_read_read(i);
[965dc18]381 print_tlb_entry(i, t, d);
[0d04024]382 }
383
384 printf("D-TLB contents:\n");
385 for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
386 d.value = dtlb_data_access_read(i);
[c52ed6b]387 t.value = dtlb_tag_read_read(i);
[965dc18]388 print_tlb_entry(i, t, d);
[0d04024]389 }
[965dc18]390}
391
392#elif defined (US3)
[0d04024]393
[965dc18]394/** Print contents of all TLBs. */
395void tlb_print(void)
396{
397 int i;
398 tlb_data_t d;
399 tlb_tag_read_reg_t t;
400
401 printf("TLB_ISMALL contents:\n");
402 for (i = 0; i < tlb_ismall_size(); i++) {
403 d.value = dtlb_data_access_read(TLB_ISMALL, i);
404 t.value = dtlb_tag_read_read(TLB_ISMALL, i);
405 print_tlb_entry(i, t, d);
406 }
407
408 printf("TLB_IBIG contents:\n");
409 for (i = 0; i < tlb_ibig_size(); i++) {
410 d.value = dtlb_data_access_read(TLB_IBIG, i);
411 t.value = dtlb_tag_read_read(TLB_IBIG, i);
412 print_tlb_entry(i, t, d);
413 }
414
415 printf("TLB_DSMALL contents:\n");
416 for (i = 0; i < tlb_dsmall_size(); i++) {
417 d.value = dtlb_data_access_read(TLB_DSMALL, i);
418 t.value = dtlb_tag_read_read(TLB_DSMALL, i);
419 print_tlb_entry(i, t, d);
420 }
421
422 printf("TLB_DBIG_1 contents:\n");
423 for (i = 0; i < tlb_dbig_size(); i++) {
424 d.value = dtlb_data_access_read(TLB_DBIG_0, i);
425 t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
426 print_tlb_entry(i, t, d);
427 }
428
429 printf("TLB_DBIG_2 contents:\n");
430 for (i = 0; i < tlb_dbig_size(); i++) {
431 d.value = dtlb_data_access_read(TLB_DBIG_1, i);
432 t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
433 print_tlb_entry(i, t, d);
434 }
[0d04024]435}
[dbb6886]436
[965dc18]437#endif
438
[2057572]439void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
440 const char *str)
[a7961271]441{
[f651e80]442 fault_if_from_uspace(istate, "%s.", str);
[7bb6b06]443 dump_istate(istate);
[f651e80]444 panic("%s.", str);
[a7961271]445}
446
[2057572]447void do_fast_data_access_mmu_miss_fault(istate_t *istate,
448 tlb_tag_access_reg_t tag, const char *str)
[f47fd19]449{
450 uintptr_t va;
451
[2057572]452 va = tag.vpn << MMU_PAGE_WIDTH;
[36f19c0]453 if (tag.context) {
[f651e80]454 fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
[36f19c0]455 tag.context);
456 }
[7bb6b06]457 dump_istate(istate);
[f651e80]458 printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
459 panic("%s.", str);
[f47fd19]460}
461
[2057572]462void do_fast_data_access_protection_fault(istate_t *istate,
463 tlb_tag_access_reg_t tag, const char *str)
[e0b241f]464{
465 uintptr_t va;
466
[2057572]467 va = tag.vpn << MMU_PAGE_WIDTH;
[e0b241f]468
[36f19c0]469 if (tag.context) {
[f651e80]470 fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
[36f19c0]471 tag.context);
472 }
[e0b241f]473 printf("Faulting page: %p, ASID=%d\n", va, tag.context);
[7bb6b06]474 dump_istate(istate);
[f651e80]475 panic("%s.", str);
[e0b241f]476}
477
[8c2214e]478void describe_dmmu_fault(void)
479{
480 tlb_sfsr_reg_t sfsr;
481 uintptr_t sfar;
482
483 sfsr.value = dtlb_sfsr_read();
484 sfar = dtlb_sfar_read();
485
486#if defined (US)
487 printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
488 "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
489 sfsr.ow, sfsr.fv);
490#elif defined (US3)
491 printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
492 "w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
493 sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
494#endif
495
496 printf("DTLB SFAR: address=%p\n", sfar);
497
498 dtlb_sfsr_write(0);
499}
500
[8cee705]501void dump_sfsr_and_sfar(void)
502{
503 tlb_sfsr_reg_t sfsr;
504 uintptr_t sfar;
505
506 sfsr.value = dtlb_sfsr_read();
507 sfar = dtlb_sfar_read();
508
[965dc18]509#if defined (US)
[771cd22]510 printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
[2057572]511 "fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
512 sfsr.ow, sfsr.fv);
[965dc18]513#elif defined (US3)
514 printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
515 "w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
516 sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
517#endif
518
[8cee705]519 printf("DTLB SFAR: address=%p\n", sfar);
520
521 dtlb_sfsr_write(0);
522}
523
[687246b]524#if defined (US)
[965dc18]525/** Invalidate all unlocked ITLB and DTLB entries. */
526void tlb_invalidate_all(void)
527{
528 int i;
529
[8dbc18c]530 /*
531 * Walk all ITLB and DTLB entries and remove all unlocked mappings.
532 *
533 * The kernel doesn't use global mappings so any locked global mappings
[965dc18]534 * found must have been created by someone else. Their only purpose now
[8dbc18c]535 * is to collide with proper mappings. Invalidate immediately. It should
536 * be safe to invalidate them as late as now.
537 */
538
[965dc18]539 tlb_data_t d;
540 tlb_tag_read_reg_t t;
541
[dbb6886]542 for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
543 d.value = itlb_data_access_read(i);
[8dbc18c]544 if (!d.l || d.g) {
[dbb6886]545 t.value = itlb_tag_read_read(i);
546 d.v = false;
547 itlb_tag_access_write(t.value);
548 itlb_data_access_write(i, d.value);
549 }
550 }
[965dc18]551
[dbb6886]552 for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
553 d.value = dtlb_data_access_read(i);
[8dbc18c]554 if (!d.l || d.g) {
[dbb6886]555 t.value = dtlb_tag_read_read(i);
556 d.v = false;
557 dtlb_tag_access_write(t.value);
558 dtlb_data_access_write(i, d.value);
559 }
560 }
[965dc18]561
[687246b]562}
[965dc18]563
[687246b]564#elif defined (US3)
[965dc18]565
[687246b]566/** Invalidate all unlocked ITLB and DTLB entries. */
567void tlb_invalidate_all(void)
568{
569 itlb_demap(TLB_DEMAP_ALL, 0, 0);
570 dtlb_demap(TLB_DEMAP_ALL, 0, 0);
[dbb6886]571}
572
[687246b]573#endif
574
[771cd22]575/** Invalidate all ITLB and DTLB entries that belong to specified ASID
576 * (Context).
[dbb6886]577 *
578 * @param asid Address Space ID.
579 */
580void tlb_invalidate_asid(asid_t asid)
581{
[fd85ae5]582 tlb_context_reg_t pc_save, ctx;
[ed166f7]583
[fd85ae5]584 /* switch to nucleus because we are mapped by the primary context */
585 nucleus_enter();
586
587 ctx.v = pc_save.v = mmu_primary_context_read();
[ed166f7]588 ctx.context = asid;
[fd85ae5]589 mmu_primary_context_write(ctx.v);
590
591 itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
592 dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0);
[ed166f7]593
[fd85ae5]594 mmu_primary_context_write(pc_save.v);
[ed166f7]595
[fd85ae5]596 nucleus_leave();
[dbb6886]597}
598
[771cd22]599/** Invalidate all ITLB and DTLB entries for specified page range in specified
600 * address space.
[dbb6886]601 *
[965dc18]602 * @param asid Address Space ID.
603 * @param page First page which to sweep out from ITLB and DTLB.
604 * @param cnt Number of ITLB and DTLB entries to invalidate.
[dbb6886]605 */
[98000fb]606void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
[dbb6886]607{
[6c441cf8]608 unsigned int i;
[fd85ae5]609 tlb_context_reg_t pc_save, ctx;
[ed166f7]610
[fd85ae5]611 /* switch to nucleus because we are mapped by the primary context */
612 nucleus_enter();
613
614 ctx.v = pc_save.v = mmu_primary_context_read();
[ed166f7]615 ctx.context = asid;
[fd85ae5]616 mmu_primary_context_write(ctx.v);
[4512d7e]617
[2057572]618 for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) {
[454f1da]619 itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
[2057572]620 page + i * MMU_PAGE_SIZE);
[454f1da]621 dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY,
[2057572]622 page + i * MMU_PAGE_SIZE);
[4512d7e]623 }
[ed166f7]624
[fd85ae5]625 mmu_primary_context_write(pc_save.v);
626
627 nucleus_leave();
[dbb6886]628}
[b45c443]629
[10b890b]630/** @}
[b45c443]631 */
Note: See TracBrowser for help on using the repository browser.