vm_phys.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. /*-
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2002-2006 Rice University
  5. * Copyright (c) 2007 Alan L. Cox <alc@cs.rice.edu>
  6. * All rights reserved.
  7. *
  8. * This software was developed for the FreeBSD Project by Alan L. Cox,
  9. * Olivier Crameri, Peter Druschel, Sitaram Iyer, and Juan Navarro.
  10. *
  11. * Redistribution and use in source and binary forms, with or without
  12. * modification, are permitted provided that the following conditions
  13. * are met:
  14. * 1. Redistributions of source code must retain the above copyright
  15. * notice, this list of conditions and the following disclaimer.
  16. * 2. Redistributions in binary form must reproduce the above copyright
  17. * notice, this list of conditions and the following disclaimer in the
  18. * documentation and/or other materials provided with the distribution.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  25. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  26. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  27. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  28. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
  30. * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  31. * POSSIBILITY OF SUCH DAMAGE.
  32. */
  33. /*
  34. * Physical memory system definitions
  35. */
  36. #ifndef _VM_PHYS_H_
  37. #define _VM_PHYS_H_
  38. #ifdef _KERNEL
  39. #include <vm/_vm_phys.h>
  40. extern vm_paddr_t phys_avail[];
  41. /* Domains must be dense (non-sparse) and zero-based. */
  42. struct mem_affinity {
  43. vm_paddr_t start;
  44. vm_paddr_t end;
  45. int domain;
  46. };
  47. #ifdef NUMA
  48. extern struct mem_affinity *mem_affinity;
  49. extern int *mem_locality;
  50. #endif
  51. /*
  52. * The following functions are only to be used by the virtual memory system.
  53. */
  54. void vm_phys_add_seg(vm_paddr_t start, vm_paddr_t end);
  55. vm_page_t vm_phys_alloc_contig(int domain, u_long npages, vm_paddr_t low,
  56. vm_paddr_t high, u_long alignment, vm_paddr_t boundary);
  57. vm_page_t vm_phys_alloc_freelist_pages(int domain, int freelist, int pool,
  58. int order);
  59. int vm_phys_alloc_npages(int domain, int pool, int npages, vm_page_t ma[]);
  60. vm_page_t vm_phys_alloc_pages(int domain, int pool, int order);
  61. int vm_phys_domain_match(int prefer, vm_paddr_t low, vm_paddr_t high);
  62. void vm_phys_enqueue_contig(vm_page_t m, u_long npages);
  63. int vm_phys_fictitious_reg_range(vm_paddr_t start, vm_paddr_t end,
  64. vm_memattr_t memattr);
  65. void vm_phys_fictitious_unreg_range(vm_paddr_t start, vm_paddr_t end);
  66. vm_page_t vm_phys_fictitious_to_vm_page(vm_paddr_t pa);
  67. int vm_phys_find_range(vm_page_t bounds[], int segind, int domain,
  68. u_long npages, vm_paddr_t low, vm_paddr_t high);
  69. void vm_phys_free_contig(vm_page_t m, u_long npages);
  70. void vm_phys_free_pages(vm_page_t m, int order);
  71. void vm_phys_init(void);
  72. vm_page_t vm_phys_paddr_to_vm_page(vm_paddr_t pa);
  73. vm_page_t vm_phys_seg_paddr_to_vm_page(struct vm_phys_seg *seg, vm_paddr_t pa);
  74. void vm_phys_register_domains(int ndomains, struct mem_affinity *affinity,
  75. int *locality);
  76. bool vm_phys_unfree_page(vm_paddr_t pa);
  77. int vm_phys_mem_affinity(int f, int t);
  78. void vm_phys_early_add_seg(vm_paddr_t start, vm_paddr_t end);
  79. vm_paddr_t vm_phys_early_alloc(int domain, size_t alloc_size);
  80. void vm_phys_early_startup(void);
  81. int vm_phys_avail_largest(void);
  82. vm_paddr_t vm_phys_avail_size(int i);
  83. bool vm_phys_is_dumpable(vm_paddr_t pa);
  84. static inline int
  85. vm_phys_domain(vm_paddr_t pa __numa_used)
  86. {
  87. #ifdef NUMA
  88. int i;
  89. if (vm_ndomains == 1)
  90. return (0);
  91. for (i = 0; mem_affinity[i].end != 0; i++)
  92. if (mem_affinity[i].start <= pa &&
  93. mem_affinity[i].end >= pa)
  94. return (mem_affinity[i].domain);
  95. return (-1);
  96. #else
  97. return (0);
  98. #endif
  99. }
  100. /*
  101. * Find the segind for the first segment at or after the given physical address.
  102. */
  103. static inline int
  104. vm_phys_lookup_segind(vm_paddr_t pa)
  105. {
  106. u_int hi, lo, mid;
  107. lo = 0;
  108. hi = vm_phys_nsegs;
  109. while (lo != hi) {
  110. /*
  111. * for i in [0, lo), segs[i].end <= pa
  112. * for i in [hi, nsegs), segs[i].end > pa
  113. */
  114. mid = lo + (hi - lo) / 2;
  115. if (vm_phys_segs[mid].end <= pa)
  116. lo = mid + 1;
  117. else
  118. hi = mid;
  119. }
  120. return (lo);
  121. }
  122. /*
  123. * Find the segment corresponding to the given physical address.
  124. */
  125. static inline struct vm_phys_seg *
  126. vm_phys_paddr_to_seg(vm_paddr_t pa)
  127. {
  128. struct vm_phys_seg *seg;
  129. int segind;
  130. segind = vm_phys_lookup_segind(pa);
  131. if (segind < vm_phys_nsegs) {
  132. seg = &vm_phys_segs[segind];
  133. if (pa >= seg->start)
  134. return (seg);
  135. }
  136. return (NULL);
  137. }
  138. #endif /* _KERNEL */
  139. #endif /* !_VM_PHYS_H_ */