Subversion Repositories HelenOS

Rev

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

Rev Author Line No. Line
740 jermar 1
/*
2
 * Copyright (C) 2006 Jakub 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
 
29
/*
30
 * TLB management.
31
 */
32
 
33
#include <mm/tlb.h>
901 jermar 34
#include <mm/asid.h>
902 jermar 35
#include <mm/page.h>
36
#include <mm/as.h>
818 vana 37
#include <arch/mm/tlb.h>
901 jermar 38
#include <arch/mm/page.h>
1210 vana 39
#include <arch/mm/vhpt.h>
819 vana 40
#include <arch/barrier.h>
900 jermar 41
#include <arch/interrupt.h>
928 vana 42
#include <arch/pal/pal.h>
43
#include <arch/asm.h>
899 jermar 44
#include <typedefs.h>
900 jermar 45
#include <panic.h>
993 jermar 46
#include <print.h>
902 jermar 47
#include <arch.h>
740 jermar 48
 
756 jermar 49
/** Invalidate all TLB entries. */
740 jermar 50
void tlb_invalidate_all(void)
51
{
993 jermar 52
		ipl_t ipl;
928 vana 53
		__address adr;
993 jermar 54
		__u32 count1, count2, stride1, stride2;
928 vana 55
 
56
		int i,j;
57
 
993 jermar 58
		adr = PAL_PTCE_INFO_BASE();
59
		count1 = PAL_PTCE_INFO_COUNT1();
60
		count2 = PAL_PTCE_INFO_COUNT2();
61
		stride1 = PAL_PTCE_INFO_STRIDE1();
62
		stride2 = PAL_PTCE_INFO_STRIDE2();
928 vana 63
 
993 jermar 64
		ipl = interrupts_disable();
928 vana 65
 
993 jermar 66
		for(i = 0; i < count1; i++) {
67
			for(j = 0; j < count2; j++) {
68
				__asm__ volatile (
69
					"ptc.e %0 ;;"
928 vana 70
					:
993 jermar 71
					: "r" (adr)
928 vana 72
				);
993 jermar 73
				adr += stride2;
928 vana 74
			}
993 jermar 75
			adr += stride1;
928 vana 76
		}
77
 
993 jermar 78
		interrupts_restore(ipl);
928 vana 79
 
80
		srlz_d();
81
		srlz_i();
1210 vana 82
#ifdef CONFIG_VHPT
83
		vhpt_invalidate_all();
84
#endif	
740 jermar 85
}
86
 
87
/** Invalidate entries belonging to an address space.
88
 *
89
 * @param asid Address space identifier.
90
 */
91
void tlb_invalidate_asid(asid_t asid)
92
{
935 vana 93
	tlb_invalidate_all();
740 jermar 94
}
818 vana 95
 
935 vana 96
 
947 vana 97
void tlb_invalidate_pages(asid_t asid, __address page, count_t cnt)
935 vana 98
{
944 vana 99
	region_register rr;
100
	bool restore_rr = false;
993 jermar 101
	int b = 0;
102
	int c = cnt;
944 vana 103
 
947 vana 104
	__address va;
993 jermar 105
	va = page;
947 vana 106
 
944 vana 107
	rr.word = rr_read(VA2VRN(va));
108
	if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
109
		/*
110
		 * The selected region register does not contain required RID.
111
		 * Save the old content of the register and replace the RID.
112
		 */
113
		region_register rr0;
114
 
115
		rr0 = rr;
116
		rr0.map.rid = ASID2RID(asid, VA2VRN(va));
117
		rr_write(VA2VRN(va), rr0.word);
118
		srlz_d();
119
		srlz_i();
120
	}
121
 
993 jermar 122
	while(c >>= 1)
123
		b++;
124
	b >>= 1;
944 vana 125
	__u64 ps;
126
 
993 jermar 127
	switch (b) {
944 vana 128
		case 0: /*cnt 1-3*/
993 jermar 129
			ps = PAGE_WIDTH;
944 vana 130
			break;
131
		case 1: /*cnt 4-15*/
947 vana 132
			/*cnt=((cnt-1)/4)+1;*/
993 jermar 133
			ps = PAGE_WIDTH+2;
134
			va &= ~((1<<ps)-1);
944 vana 135
			break;
136
		case 2: /*cnt 16-63*/
947 vana 137
			/*cnt=((cnt-1)/16)+1;*/
993 jermar 138
			ps = PAGE_WIDTH+4;
139
			va &= ~((1<<ps)-1);
944 vana 140
			break;
141
		case 3: /*cnt 64-255*/
947 vana 142
			/*cnt=((cnt-1)/64)+1;*/
993 jermar 143
			ps = PAGE_WIDTH+6;
144
			va &= ~((1<<ps)-1);
944 vana 145
			break;
146
		case 4: /*cnt 256-1023*/
947 vana 147
			/*cnt=((cnt-1)/256)+1;*/
993 jermar 148
			ps = PAGE_WIDTH+8;
149
			va &= ~((1<<ps)-1);
944 vana 150
			break;
151
		case 5: /*cnt 1024-4095*/
947 vana 152
			/*cnt=((cnt-1)/1024)+1;*/
993 jermar 153
			ps = PAGE_WIDTH+10;
154
			va &= ~((1<<ps)-1);
944 vana 155
			break;
156
		case 6: /*cnt 4096-16383*/
947 vana 157
			/*cnt=((cnt-1)/4096)+1;*/
993 jermar 158
			ps = PAGE_WIDTH+12;
159
			va &= ~((1<<ps)-1);
944 vana 160
			break;
161
		case 7: /*cnt 16384-65535*/
162
		case 8: /*cnt 65536-(256K-1)*/
947 vana 163
			/*cnt=((cnt-1)/16384)+1;*/
993 jermar 164
			ps = PAGE_WIDTH+14;
165
			va &= ~((1<<ps)-1);
944 vana 166
			break;
167
		default:
947 vana 168
			/*cnt=((cnt-1)/(16384*16))+1;*/
944 vana 169
			ps=PAGE_WIDTH+18;
170
			va&=~((1<<ps)-1);
171
			break;
172
	}
947 vana 173
	/*cnt+=(page!=va);*/
993 jermar 174
	for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps))	{
175
		__asm__ volatile (
947 vana 176
			"ptc.l %0,%1;;"
177
			:
993 jermar 178
			: "r" (va), "r" (ps<<2)
947 vana 179
		);
944 vana 180
	}
181
	srlz_d();
182
	srlz_i();
183
 
184
	if (restore_rr) {
185
		rr_write(VA2VRN(va), rr.word);
186
		srlz_d();
187
		srlz_i();
188
	}
935 vana 189
}
190
 
191
 
899 jermar 192
/** Insert data into data translation cache.
193
 *
194
 * @param va Virtual page address.
195
 * @param asid Address space identifier.
196
 * @param entry The rest of TLB entry as required by TLB insertion format.
197
 */
919 jermar 198
void dtc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry)
199
{
899 jermar 200
	tc_mapping_insert(va, asid, entry, true);
201
}
818 vana 202
 
899 jermar 203
/** Insert data into instruction translation cache.
204
 *
205
 * @param va Virtual page address.
206
 * @param asid Address space identifier.
207
 * @param entry The rest of TLB entry as required by TLB insertion format.
208
 */
919 jermar 209
void itc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry)
210
{
899 jermar 211
	tc_mapping_insert(va, asid, entry, false);
212
}
818 vana 213
 
899 jermar 214
/** Insert data into instruction or data translation cache.
215
 *
216
 * @param va Virtual page address.
217
 * @param asid Address space identifier.
218
 * @param entry The rest of TLB entry as required by TLB insertion format.
219
 * @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
220
 */
221
void tc_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtc)
818 vana 222
{
223
	region_register rr;
899 jermar 224
	bool restore_rr = false;
818 vana 225
 
901 jermar 226
	rr.word = rr_read(VA2VRN(va));
227
	if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
899 jermar 228
		/*
229
		 * The selected region register does not contain required RID.
230
		 * Save the old content of the register and replace the RID.
231
		 */
232
		region_register rr0;
818 vana 233
 
899 jermar 234
		rr0 = rr;
901 jermar 235
		rr0.map.rid = ASID2RID(asid, VA2VRN(va));
236
		rr_write(VA2VRN(va), rr0.word);
899 jermar 237
		srlz_d();
238
		srlz_i();
818 vana 239
	}
899 jermar 240
 
241
	__asm__ volatile (
242
		"mov r8=psr;;\n"
900 jermar 243
		"rsm %0;;\n"   			/* PSR_IC_MASK */
899 jermar 244
		"srlz.d;;\n"
245
		"srlz.i;;\n"
246
		"mov cr.ifa=%1\n"		/* va */
247
		"mov cr.itir=%2;;\n"		/* entry.word[1] */
248
		"cmp.eq p6,p7 = %4,r0;;\n"	/* decide between itc and dtc */ 
249
		"(p6) itc.i %3;;\n"
250
		"(p7) itc.d %3;;\n"
251
		"mov psr.l=r8;;\n"
252
		"srlz.d;;\n"
253
		:
900 jermar 254
		: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
255
		: "p6", "p7", "r8"
899 jermar 256
	);
257
 
258
	if (restore_rr) {
901 jermar 259
		rr_write(VA2VRN(va), rr.word);
819 vana 260
		srlz_d();
899 jermar 261
		srlz_i();
818 vana 262
	}
899 jermar 263
}
818 vana 264
 
899 jermar 265
/** Insert data into instruction translation register.
266
 *
267
 * @param va Virtual page address.
268
 * @param asid Address space identifier.
269
 * @param entry The rest of TLB entry as required by TLB insertion format.
270
 * @param tr Translation register.
271
 */
272
void itr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
273
{
274
	tr_mapping_insert(va, asid, entry, false, tr);
275
}
818 vana 276
 
899 jermar 277
/** Insert data into data translation register.
278
 *
279
 * @param va Virtual page address.
280
 * @param asid Address space identifier.
281
 * @param entry The rest of TLB entry as required by TLB insertion format.
282
 * @param tr Translation register.
283
 */
284
void dtr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, index_t tr)
285
{
286
	tr_mapping_insert(va, asid, entry, true, tr);
818 vana 287
}
288
 
899 jermar 289
/** Insert data into instruction or data translation register.
290
 *
291
 * @param va Virtual page address.
292
 * @param asid Address space identifier.
293
 * @param entry The rest of TLB entry as required by TLB insertion format.
294
 * @param dtc If true, insert into data translation register, use instruction translation register otherwise.
295
 * @param tr Translation register.
296
 */
297
void tr_mapping_insert(__address va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
818 vana 298
{
299
	region_register rr;
899 jermar 300
	bool restore_rr = false;
818 vana 301
 
901 jermar 302
	rr.word = rr_read(VA2VRN(va));
303
	if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) {
899 jermar 304
		/*
305
		 * The selected region register does not contain required RID.
306
		 * Save the old content of the register and replace the RID.
307
		 */
308
		region_register rr0;
818 vana 309
 
899 jermar 310
		rr0 = rr;
901 jermar 311
		rr0.map.rid = ASID2RID(asid, VA2VRN(va));
312
		rr_write(VA2VRN(va), rr0.word);
899 jermar 313
		srlz_d();
314
		srlz_i();
315
	}
818 vana 316
 
899 jermar 317
	__asm__ volatile (
318
		"mov r8=psr;;\n"
900 jermar 319
		"rsm %0;;\n"			/* PSR_IC_MASK */
899 jermar 320
		"srlz.d;;\n"
321
		"srlz.i;;\n"
322
		"mov cr.ifa=%1\n"        	/* va */		 
323
		"mov cr.itir=%2;;\n"		/* entry.word[1] */ 
324
		"cmp.eq p6,p7=%5,r0;;\n"	/* decide between itr and dtr */
325
		"(p6) itr.i itr[%4]=%3;;\n"
326
		"(p7) itr.d dtr[%4]=%3;;\n"
327
		"mov psr.l=r8;;\n"
328
		"srlz.d;;\n"
329
		:
900 jermar 330
		: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
331
		: "p6", "p7", "r8"
899 jermar 332
	);
333
 
334
	if (restore_rr) {
901 jermar 335
		rr_write(VA2VRN(va), rr.word);
819 vana 336
		srlz_d();
899 jermar 337
		srlz_i();
818 vana 338
	}
899 jermar 339
}
818 vana 340
 
901 jermar 341
/** Insert data into DTLB.
342
 *
343
 * @param va Virtual page address.
344
 * @param asid Address space identifier.
345
 * @param entry The rest of TLB entry as required by TLB insertion format.
346
 * @param dtr If true, insert into data translation register, use data translation cache otherwise.
347
 * @param tr Translation register if dtr is true, ignored otherwise.
348
 */
902 jermar 349
void dtlb_kernel_mapping_insert(__address page, __address frame, bool dtr, index_t tr)
901 jermar 350
{
351
	tlb_entry_t entry;
352
 
353
	entry.word[0] = 0;
354
	entry.word[1] = 0;
355
 
356
	entry.p = true;			/* present */
357
	entry.ma = MA_WRITEBACK;
358
	entry.a = true;			/* already accessed */
359
	entry.d = true;			/* already dirty */
360
	entry.pl = PL_KERNEL;
361
	entry.ar = AR_READ | AR_WRITE;
362
	entry.ppn = frame >> PPN_SHIFT;
363
	entry.ps = PAGE_WIDTH;
364
 
365
	if (dtr)
366
		dtr_mapping_insert(page, ASID_KERNEL, entry, tr);
367
	else
368
		dtc_mapping_insert(page, ASID_KERNEL, entry);
369
}
370
 
902 jermar 371
/** Copy content of PTE into data translation cache.
372
 *
373
 * @param t PTE.
374
 */
375
void dtc_pte_copy(pte_t *t)
376
{
377
	tlb_entry_t entry;
378
 
379
	entry.word[0] = 0;
380
	entry.word[1] = 0;
381
 
382
	entry.p = t->p;
383
	entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
384
	entry.a = t->a;
385
	entry.d = t->d;
386
	entry.pl = t->k ? PL_KERNEL : PL_USER;
387
	entry.ar = t->w ? AR_WRITE : AR_READ;
388
	entry.ppn = t->frame >> PPN_SHIFT;
389
	entry.ps = PAGE_WIDTH;
390
 
391
	dtc_mapping_insert(t->page, t->as->asid, entry);
1210 vana 392
#ifdef CONFIG_VHPT
393
	vhpt_mapping_insert(t->page, t->as->asid, entry);
394
#endif	
902 jermar 395
}
396
 
397
/** Copy content of PTE into instruction translation cache.
398
 *
399
 * @param t PTE.
400
 */
401
void itc_pte_copy(pte_t *t)
402
{
403
	tlb_entry_t entry;
404
 
405
	entry.word[0] = 0;
406
	entry.word[1] = 0;
407
 
408
	ASSERT(t->x);
409
 
410
	entry.p = t->p;
411
	entry.ma = t->c ? MA_WRITEBACK : MA_UNCACHEABLE;
412
	entry.a = t->a;
413
	entry.pl = t->k ? PL_KERNEL : PL_USER;
414
	entry.ar = t->x ? (AR_EXECUTE | AR_READ) : AR_READ;
415
	entry.ppn = t->frame >> PPN_SHIFT;
416
	entry.ps = PAGE_WIDTH;
417
 
418
	itc_mapping_insert(t->page, t->as->asid, entry);
1210 vana 419
#ifdef CONFIG_VHPT
420
	vhpt_mapping_insert(t->page, t->as->asid, entry);
421
#endif	
902 jermar 422
}
423
 
424
/** Instruction TLB fault handler for faults with VHPT turned off.
425
 *
426
 * @param vector Interruption vector.
958 jermar 427
 * @param istate Structure with saved interruption state.
902 jermar 428
 */
958 jermar 429
void alternate_instruction_tlb_fault(__u64 vector, istate_t *istate)
899 jermar 430
{
902 jermar 431
	region_register rr;
1411 jermar 432
	rid_t rid;
902 jermar 433
	__address va;
434
	pte_t *t;
435
 
958 jermar 436
	va = istate->cr_ifa;	/* faulting address */
1411 jermar 437
	rr.word = rr_read(VA2VRN(va));
438
	rid = rr.map.rid;
439
 
1044 jermar 440
	page_table_lock(AS, true);
902 jermar 441
	t = page_mapping_find(AS, va);
442
	if (t) {
443
		/*
444
		 * The mapping was found in software page hash table.
445
		 * Insert it into data translation cache.
446
		 */
447
		itc_pte_copy(t);
1044 jermar 448
		page_table_unlock(AS, true);
902 jermar 449
	} else {
450
		/*
451
		 * Forward the page fault to address space page fault handler.
452
		 */
1044 jermar 453
		page_table_unlock(AS, true);
1411 jermar 454
		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
455
			panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
902 jermar 456
		}
457
	}
899 jermar 458
}
818 vana 459
 
902 jermar 460
/** Data TLB fault handler for faults with VHPT turned off.
901 jermar 461
 *
462
 * @param vector Interruption vector.
958 jermar 463
 * @param istate Structure with saved interruption state.
901 jermar 464
 */
958 jermar 465
void alternate_data_tlb_fault(__u64 vector, istate_t *istate)
899 jermar 466
{
901 jermar 467
	region_register rr;
468
	rid_t rid;
469
	__address va;
902 jermar 470
	pte_t *t;
901 jermar 471
 
958 jermar 472
	va = istate->cr_ifa;	/* faulting address */
901 jermar 473
	rr.word = rr_read(VA2VRN(va));
474
	rid = rr.map.rid;
475
	if (RID2ASID(rid) == ASID_KERNEL) {
476
		if (VA2VRN(va) == VRN_KERNEL) {
477
			/*
478
			 * Provide KA2PA(identity) mapping for faulting piece of
479
			 * kernel address space.
480
			 */
902 jermar 481
			dtlb_kernel_mapping_insert(va, KA2PA(va), false, 0);
901 jermar 482
			return;
483
		}
484
	}
919 jermar 485
 
1044 jermar 486
	page_table_lock(AS, true);
902 jermar 487
	t = page_mapping_find(AS, va);
488
	if (t) {
489
		/*
490
		 * The mapping was found in software page hash table.
491
		 * Insert it into data translation cache.
492
		 */
493
		dtc_pte_copy(t);
1044 jermar 494
		page_table_unlock(AS, true);
902 jermar 495
	} else {
496
		/*
497
		 * Forward the page fault to address space page fault handler.
498
		 */
1044 jermar 499
		page_table_unlock(AS, true);
1411 jermar 500
		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
1221 decky 501
			panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
902 jermar 502
		}
503
	}
818 vana 504
}
505
 
902 jermar 506
/** Data nested TLB fault handler.
507
 *
508
 * This fault should not occur.
509
 *
510
 * @param vector Interruption vector.
958 jermar 511
 * @param istate Structure with saved interruption state.
902 jermar 512
 */
958 jermar 513
void data_nested_tlb_fault(__u64 vector, istate_t *istate)
899 jermar 514
{
515
	panic("%s\n", __FUNCTION__);
516
}
818 vana 517
 
902 jermar 518
/** Data Dirty bit fault handler.
519
 *
520
 * @param vector Interruption vector.
958 jermar 521
 * @param istate Structure with saved interruption state.
902 jermar 522
 */
958 jermar 523
void data_dirty_bit_fault(__u64 vector, istate_t *istate)
819 vana 524
{
1411 jermar 525
	region_register rr;
526
	rid_t rid;
527
	__address va;
902 jermar 528
	pte_t *t;
1411 jermar 529
 
530
	va = istate->cr_ifa;	/* faulting address */
531
	rr.word = rr_read(VA2VRN(va));
532
	rid = rr.map.rid;
902 jermar 533
 
1044 jermar 534
	page_table_lock(AS, true);
1411 jermar 535
	t = page_mapping_find(AS, va);
902 jermar 536
	ASSERT(t && t->p);
1411 jermar 537
	if (t && t->p && t->w) {
902 jermar 538
		/*
539
		 * Update the Dirty bit in page tables and reinsert
540
		 * the mapping into DTC.
541
		 */
542
		t->d = true;
543
		dtc_pte_copy(t);
1411 jermar 544
	} else {
545
		if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
546
			panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
547
			t->d = true;
548
			dtc_pte_copy(t);
549
		}
902 jermar 550
	}
1044 jermar 551
	page_table_unlock(AS, true);
899 jermar 552
}
819 vana 553
 
902 jermar 554
/** Instruction access bit fault handler.
555
 *
556
 * @param vector Interruption vector.
958 jermar 557
 * @param istate Structure with saved interruption state.
902 jermar 558
 */
958 jermar 559
void instruction_access_bit_fault(__u64 vector, istate_t *istate)
899 jermar 560
{
1411 jermar 561
	region_register rr;
562
	rid_t rid;
563
	__address va;
564
	pte_t *t;	
902 jermar 565
 
1411 jermar 566
	va = istate->cr_ifa;	/* faulting address */
567
	rr.word = rr_read(VA2VRN(va));
568
	rid = rr.map.rid;
569
 
1044 jermar 570
	page_table_lock(AS, true);
1411 jermar 571
	t = page_mapping_find(AS, va);
902 jermar 572
	ASSERT(t && t->p);
1411 jermar 573
	if (t && t->p && t->x) {
902 jermar 574
		/*
575
		 * Update the Accessed bit in page tables and reinsert
576
		 * the mapping into ITC.
577
		 */
578
		t->a = true;
579
		itc_pte_copy(t);
1411 jermar 580
	} else {
581
		if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
582
			panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
583
			t->a = true;
584
			itc_pte_copy(t);
585
		}
902 jermar 586
	}
1044 jermar 587
	page_table_unlock(AS, true);
899 jermar 588
}
819 vana 589
 
902 jermar 590
/** Data access bit fault handler.
591
 *
592
 * @param vector Interruption vector.
958 jermar 593
 * @param istate Structure with saved interruption state.
902 jermar 594
 */
958 jermar 595
void data_access_bit_fault(__u64 vector, istate_t *istate)
899 jermar 596
{
1411 jermar 597
	region_register rr;
598
	rid_t rid;
599
	__address va;
902 jermar 600
	pte_t *t;
601
 
1411 jermar 602
	va = istate->cr_ifa;	/* faulting address */
603
	rr.word = rr_read(VA2VRN(va));
604
	rid = rr.map.rid;
605
 
1044 jermar 606
	page_table_lock(AS, true);
1411 jermar 607
	t = page_mapping_find(AS, va);
902 jermar 608
	ASSERT(t && t->p);
609
	if (t && t->p) {
610
		/*
611
		 * Update the Accessed bit in page tables and reinsert
612
		 * the mapping into DTC.
613
		 */
614
		t->a = true;
615
		dtc_pte_copy(t);
1411 jermar 616
	} else {
617
		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
618
			panic("%s: va=%p, rid=%d, iip=%p\n", __FUNCTION__, va, rid, istate->cr_iip);
619
			t->a = true;
620
			itc_pte_copy(t);
621
		}
902 jermar 622
	}
1044 jermar 623
	page_table_unlock(AS, true);
819 vana 624
}
625
 
902 jermar 626
/** Page not present fault handler.
627
 *
628
 * @param vector Interruption vector.
958 jermar 629
 * @param istate Structure with saved interruption state.
902 jermar 630
 */
958 jermar 631
void page_not_present(__u64 vector, istate_t *istate)
819 vana 632
{
902 jermar 633
	region_register rr;
1411 jermar 634
	rid_t rid;
902 jermar 635
	__address va;
636
	pte_t *t;
637
 
958 jermar 638
	va = istate->cr_ifa;	/* faulting address */
1411 jermar 639
	rr.word = rr_read(VA2VRN(va));
640
	rid = rr.map.rid;
641
 
1044 jermar 642
	page_table_lock(AS, true);
902 jermar 643
	t = page_mapping_find(AS, va);
644
	ASSERT(t);
645
 
646
	if (t->p) {
647
		/*
648
		 * If the Present bit is set in page hash table, just copy it
649
		 * and update ITC/DTC.
650
		 */
651
		if (t->x)
652
			itc_pte_copy(t);
653
		else
654
			dtc_pte_copy(t);
1044 jermar 655
		page_table_unlock(AS, true);
902 jermar 656
	} else {
1044 jermar 657
		page_table_unlock(AS, true);
1411 jermar 658
		if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
659
			panic("%s: va=%p, rid=%d\n", __FUNCTION__, va, rid);
902 jermar 660
		}
661
	}
819 vana 662
}