* Walk the list of hardware regions, processing it against the list of * exclusions that contain the given exflags, and generating an "avail list". * * If maxphyssz is not zero it sets upper limit, in bytes, for the total * "avail list" size. Walk stops once the limit is reached and the last region * is cut short if necessary. * * Updates the value at *pavail with the sum of all pages in a
| 152 | * Returns the number of pages of non-excluded memory added to the avail list. |
| 153 | */ |
| 154 | static size_t |
| 155 | regions_to_avail(vm_paddr_t *avail, uint32_t exflags, size_t maxavail, |
| 156 | uint64_t maxphyssz, long *pavail, long *prealmem) |
| 157 | { |
| 158 | size_t acnt, exi, hwi; |
| 159 | uint64_t end, start, xend, xstart; |
| 160 | long availmem, totalmem; |
| 161 | const struct region *exp, *hwp; |
| 162 | uint64_t availsz; |
| 163 | |
| 164 | totalmem = 0; |
| 165 | availmem = 0; |
| 166 | availsz = 0; |
| 167 | acnt = 0; |
| 168 | for (hwi = 0, hwp = hwregions; hwi < hwcnt; ++hwi, ++hwp) { |
| 169 | start = hwp->addr; |
| 170 | end = hwp->size + start; |
| 171 | totalmem += atop((vm_offset_t)(end - start)); |
| 172 | for (exi = 0, exp = exregions; exi < excnt; ++exi, ++exp) { |
| 173 | /* |
| 174 | * If the excluded region does not match given flags, |
| 175 | * continue checking with the next excluded region. |
| 176 | */ |
| 177 | if ((exp->flags & exflags) == 0) |
| 178 | continue; |
| 179 | xstart = exp->addr; |
| 180 | xend = exp->size + xstart; |
| 181 | /* |
| 182 | * If the excluded region ends before this hw region, |
| 183 | * continue checking with the next excluded region. |
| 184 | */ |
| 185 | if (xend <= start) |
| 186 | continue; |
| 187 | /* |
| 188 | * If the excluded region begins after this hw region |
| 189 | * we're done because both lists are sorted. |
| 190 | */ |
| 191 | if (xstart >= end) |
| 192 | break; |
| 193 | /* |
| 194 | * If the excluded region completely covers this hw |
| 195 | * region, shrink this hw region to zero size. |
| 196 | */ |
| 197 | if ((start >= xstart) && (end <= xend)) { |
| 198 | start = xend; |
| 199 | end = xend; |
| 200 | break; |
| 201 | } |
| 202 | /* |
| 203 | * If the excluded region falls wholly within this hw |
| 204 | * region without abutting or overlapping the beginning |
| 205 | * or end, create an available entry from the leading |
| 206 | * fragment, then adjust the start of this hw region to |
| 207 | * the end of the excluded region, and continue checking |
| 208 | * the next excluded region because another exclusion |
| 209 | * could affect the remainder of this hw region. |
| 210 | */ |
| 211 | if ((xstart > start) && (xend < end)) { |
no test coverage detected