pmap.c (013818111a1477055223a69d538ebcd1c23b955e) | pmap.c (8a5ac5d56f6fa2d4569c90ce3efe3077588dd9f9) |
---|---|
1/*- 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * Copyright (c) 1994 John S. Dyson 5 * All rights reserved. 6 * Copyright (c) 1994 David Greenman 7 * All rights reserved. 8 * Copyright (c) 2005-2008 Alan L. Cox <alc@cs.rice.edu> --- 105 unchanged lines hidden (view full) --- 114#include <sys/kernel.h> 115#include <sys/ktr.h> 116#include <sys/lock.h> 117#include <sys/malloc.h> 118#include <sys/mman.h> 119#include <sys/msgbuf.h> 120#include <sys/mutex.h> 121#include <sys/proc.h> | 1/*- 2 * Copyright (c) 1991 Regents of the University of California. 3 * All rights reserved. 4 * Copyright (c) 1994 John S. Dyson 5 * All rights reserved. 6 * Copyright (c) 1994 David Greenman 7 * All rights reserved. 8 * Copyright (c) 2005-2008 Alan L. Cox <alc@cs.rice.edu> --- 105 unchanged lines hidden (view full) --- 114#include <sys/kernel.h> 115#include <sys/ktr.h> 116#include <sys/lock.h> 117#include <sys/malloc.h> 118#include <sys/mman.h> 119#include <sys/msgbuf.h> 120#include <sys/mutex.h> 121#include <sys/proc.h> |
122#include <sys/sf_buf.h> |
|
122#include <sys/sx.h> 123#include <sys/vmmeter.h> 124#include <sys/sched.h> 125#include <sys/sysctl.h> 126#ifdef SMP 127#include <sys/smp.h> 128#endif 129 --- 597 unchanged lines hidden (view full) --- 727/*************************************************** 728 * Low level helper routines..... 729 ***************************************************/ 730 731/* 732 * Determine the appropriate bits to set in a PTE or PDE for a specified 733 * caching mode. 734 */ | 123#include <sys/sx.h> 124#include <sys/vmmeter.h> 125#include <sys/sched.h> 126#include <sys/sysctl.h> 127#ifdef SMP 128#include <sys/smp.h> 129#endif 130 --- 597 unchanged lines hidden (view full) --- 728/*************************************************** 729 * Low level helper routines..... 730 ***************************************************/ 731 732/* 733 * Determine the appropriate bits to set in a PTE or PDE for a specified 734 * caching mode. 735 */ |
735static int | 736int |
736pmap_cache_bits(int mode, boolean_t is_pde) 737{ 738 int pat_flag, pat_index, cache_bits; 739 740 /* The PAT bit is different for PTE's and PDE's. */ 741 pat_flag = is_pde ? PG_PDE_PAT : PG_PTE_PAT; 742 743 /* If we don't support PAT, map extended modes to older ones. */ --- 196 unchanged lines hidden (view full) --- 940PMAP_INLINE void 941pmap_invalidate_cache(void) 942{ 943 944 wbinvd(); 945} 946#endif /* !SMP */ 947 | 737pmap_cache_bits(int mode, boolean_t is_pde) 738{ 739 int pat_flag, pat_index, cache_bits; 740 741 /* The PAT bit is different for PTE's and PDE's. */ 742 pat_flag = is_pde ? PG_PDE_PAT : PG_PTE_PAT; 743 744 /* If we don't support PAT, map extended modes to older ones. */ --- 196 unchanged lines hidden (view full) --- 941PMAP_INLINE void 942pmap_invalidate_cache(void) 943{ 944 945 wbinvd(); 946} 947#endif /* !SMP */ 948 |
949void 950pmap_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva) 951{ 952 953 KASSERT((sva & PAGE_MASK) == 0, 954 ("pmap_invalidate_cache_range: sva not page-aligned")); 955 KASSERT((eva & PAGE_MASK) == 0, 956 ("pmap_invalidate_cache_range: eva not page-aligned")); 957 958 if (cpu_feature & CPUID_SS) 959 ; /* If "Self Snoop" is supported, do nothing. */ 960 else if (cpu_feature & CPUID_CLFSH) { 961 962 /* 963 * Otherwise, do per-cache line flush. Use the mfence 964 * instruction to insure that previous stores are 965 * included in the write-back. The processor 966 * propagates flush to other processors in the cache 967 * coherence domain. 968 */ 969 mfence(); 970 for (; eva < sva; eva += cpu_clflush_line_size) 971 clflush(eva); 972 mfence(); 973 } else { 974 975 /* 976 * No targeted cache flush methods are supported by CPU, 977 * globally invalidate cache as a last resort. 978 */ 979 pmap_invalidate_cache(); 980 } 981} 982 |
|
948/* 949 * Are we current address space or kernel? N.B. We return FALSE when 950 * a pmap's page table is in use because a kernel thread is borrowing 951 * it. The borrowed page table can change spontaneously, making any 952 * dependence on its continued use subject to a race condition. 953 */ 954static __inline int 955pmap_is_current(pmap_t pmap) --- 3439 unchanged lines hidden (view full) --- 4395 * Map a set of physical memory pages into the kernel virtual 4396 * address space. Return a pointer to where it is mapped. This 4397 * routine is intended to be used for mapping device memory, 4398 * NOT real memory. 4399 */ 4400void * 4401pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) 4402{ | 983/* 984 * Are we current address space or kernel? N.B. We return FALSE when 985 * a pmap's page table is in use because a kernel thread is borrowing 986 * it. The borrowed page table can change spontaneously, making any 987 * dependence on its continued use subject to a race condition. 988 */ 989static __inline int 990pmap_is_current(pmap_t pmap) --- 3439 unchanged lines hidden (view full) --- 4430 * Map a set of physical memory pages into the kernel virtual 4431 * address space. Return a pointer to where it is mapped. This 4432 * routine is intended to be used for mapping device memory, 4433 * NOT real memory. 4434 */ 4435void * 4436pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) 4437{ |
4403 vm_offset_t va, tmpva, offset; | 4438 vm_offset_t va, offset; 4439 vm_size_t tmpsize; |
4404 4405 offset = pa & PAGE_MASK; 4406 size = roundup(offset + size, PAGE_SIZE); 4407 pa = pa & PG_FRAME; 4408 4409 if (pa < KERNLOAD && pa + size <= KERNLOAD) 4410 va = KERNBASE + pa; 4411 else 4412 va = kmem_alloc_nofault(kernel_map, size); 4413 if (!va) 4414 panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); 4415 | 4440 4441 offset = pa & PAGE_MASK; 4442 size = roundup(offset + size, PAGE_SIZE); 4443 pa = pa & PG_FRAME; 4444 4445 if (pa < KERNLOAD && pa + size <= KERNLOAD) 4446 va = KERNBASE + pa; 4447 else 4448 va = kmem_alloc_nofault(kernel_map, size); 4449 if (!va) 4450 panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); 4451 |
4416 for (tmpva = va; size > 0; ) { 4417 pmap_kenter_attr(tmpva, pa, mode); 4418 size -= PAGE_SIZE; 4419 tmpva += PAGE_SIZE; 4420 pa += PAGE_SIZE; 4421 } 4422 pmap_invalidate_range(kernel_pmap, va, tmpva); 4423 /* If "Self Snoop" is supported, do nothing. */ 4424 if (!(cpu_feature & CPUID_SS)) 4425 pmap_invalidate_cache(); | 4452 for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) 4453 pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); 4454 pmap_invalidate_range(kernel_pmap, va, va + tmpsize); 4455 pmap_invalidate_cache_range(va, va + size); |
4426 return ((void *)(va + offset)); 4427} 4428 4429void * 4430pmap_mapdev(vm_paddr_t pa, vm_size_t size) 4431{ 4432 4433 return (pmap_mapdev_attr(pa, size, PAT_UNCACHEABLE)); --- 23 unchanged lines hidden (view full) --- 4457} 4458 4459/* 4460 * Sets the memory attribute for the specified page. 4461 */ 4462void 4463pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) 4464{ | 4456 return ((void *)(va + offset)); 4457} 4458 4459void * 4460pmap_mapdev(vm_paddr_t pa, vm_size_t size) 4461{ 4462 4463 return (pmap_mapdev_attr(pa, size, PAT_UNCACHEABLE)); --- 23 unchanged lines hidden (view full) --- 4487} 4488 4489/* 4490 * Sets the memory attribute for the specified page. 4491 */ 4492void 4493pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma) 4494{ |
4495 struct sysmaps *sysmaps; 4496 vm_offset_t sva, eva; |
|
4465 4466 m->md.pat_mode = ma; | 4497 4498 m->md.pat_mode = ma; |
4499 if ((m->flags & PG_FICTITIOUS) != 0) 4500 return; |
|
4467 4468 /* 4469 * If "m" is a normal page, flush it from the cache. | 4501 4502 /* 4503 * If "m" is a normal page, flush it from the cache. |
4504 * See pmap_invalidate_cache_range(). 4505 * 4506 * First, try to find an existing mapping of the page by sf 4507 * buffer. sf_buf_invalidate_cache() modifies mapping and 4508 * flushes the cache. |
|
4470 */ | 4509 */ |
4471 if ((m->flags & PG_FICTITIOUS) == 0) { 4472 /* If "Self Snoop" is supported, do nothing. */ 4473 if (!(cpu_feature & CPUID_SS)) 4474 pmap_invalidate_cache(); | 4510 if (sf_buf_invalidate_cache(m)) 4511 return; 4512 4513 /* 4514 * If page is not mapped by sf buffer, but CPU does not 4515 * support self snoop, map the page transient and do 4516 * invalidation. In the worst case, whole cache is flushed by 4517 * pmap_invalidate_cache_range(). 4518 */ 4519 if ((cpu_feature & (CPUID_SS|CPUID_CLFSH)) == CPUID_CLFSH) { 4520 sysmaps = &sysmaps_pcpu[PCPU_GET(cpuid)]; 4521 mtx_lock(&sysmaps->lock); 4522 if (*sysmaps->CMAP2) 4523 panic("pmap_page_set_memattr: CMAP2 busy"); 4524 sched_pin(); 4525 *sysmaps->CMAP2 = PG_V | PG_RW | VM_PAGE_TO_PHYS(m) | 4526 PG_A | PG_M | pmap_cache_bits(m->md.pat_mode, 0); 4527 invlcaddr(sysmaps->CADDR2); 4528 sva = (vm_offset_t)sysmaps->CADDR2; 4529 eva = sva + PAGE_SIZE; 4530 } else 4531 sva = eva = 0; /* gcc */ 4532 pmap_invalidate_cache_range(sva, eva); 4533 if (sva != 0) { 4534 *sysmaps->CMAP2 = 0; 4535 sched_unpin(); 4536 mtx_unlock(&sysmaps->lock); |
4475 } 4476} 4477 4478int 4479pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) 4480{ 4481 vm_offset_t base, offset, tmpva; 4482 pt_entry_t *pte; --- 49 unchanged lines hidden (view full) --- 4532 } 4533 4534 /* 4535 * Flush CPU caches to make sure any data isn't cached that shouldn't 4536 * be, etc. 4537 */ 4538 if (changed) { 4539 pmap_invalidate_range(kernel_pmap, base, tmpva); | 4537 } 4538} 4539 4540int 4541pmap_change_attr(vm_offset_t va, vm_size_t size, int mode) 4542{ 4543 vm_offset_t base, offset, tmpva; 4544 pt_entry_t *pte; --- 49 unchanged lines hidden (view full) --- 4594 } 4595 4596 /* 4597 * Flush CPU caches to make sure any data isn't cached that shouldn't 4598 * be, etc. 4599 */ 4600 if (changed) { 4601 pmap_invalidate_range(kernel_pmap, base, tmpva); |
4540 /* If "Self Snoop" is supported, do nothing. */ 4541 if (!(cpu_feature & CPUID_SS)) 4542 pmap_invalidate_cache(); | 4602 pmap_invalidate_cache_range(base, tmpva); |
4543 } 4544 return (0); 4545} 4546 4547/* 4548 * perform the pmap work for mincore 4549 */ 4550int --- 234 unchanged lines hidden --- | 4603 } 4604 return (0); 4605} 4606 4607/* 4608 * perform the pmap work for mincore 4609 */ 4610int --- 234 unchanged lines hidden --- |