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

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

more unification of basic types

  • use sysarg_t and native_t (unsigned and signed variant) in both kernel and uspace
  • remove ipcarg_t in favour of sysarg_t

(no change in functionality)

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