(self, size:int, align=0x1000, uncached=False, contiguous=False)
| 237 | return va |
| 238 | |
| 239 | def valloc(self, size:int, align=0x1000, uncached=False, contiguous=False) -> VirtMapping: |
| 240 | if not getenv("GMMU", 1): |
| 241 | paddr = self.palloc(size:=round_up(size, 0x1000), align, zero=False) |
| 242 | return VirtMapping(self.identity_va(uncached) + paddr, size, [(paddr, size)], aspace=AddrSpace.PHYS, uncached=uncached) |
| 243 | |
| 244 | # Alloc physical memory and map it to the virtual address |
| 245 | va = self.alloc_vaddr(size:=round_up(size, 0x1000), align) |
| 246 | |
| 247 | if contiguous: paddrs = [(self.palloc(size, zero=True), size)] |
| 248 | else: |
| 249 | # Traverse the PT to find the largest contiguous sizes we need to allocate. Try to allocate the longest segment to reduce TLB pressure. |
| 250 | nxt_range, rem_size, paddrs = 0, size, [] |
| 251 | while rem_size > 0: |
| 252 | while self.palloc_ranges[nxt_range][0] > rem_size: nxt_range += 1 |
| 253 | |
| 254 | try: paddrs += [(self.palloc(try_sz:=self.palloc_ranges[nxt_range][0], self.palloc_ranges[nxt_range][1], zero=False), try_sz)] |
| 255 | except MemoryError: |
| 256 | # Move to a smaller size and try again. |
| 257 | nxt_range += 1 |
| 258 | if nxt_range == len(self.palloc_ranges): |
| 259 | for paddr, _ in paddrs: self.pfree(paddr) |
| 260 | raise MemoryError(f"Failed to allocate memory (OOM). Request size={size:#x} ({self.palloc_ranges[nxt_range-1]})") |
| 261 | continue |
| 262 | rem_size -= self.palloc_ranges[nxt_range][0] |
| 263 | |
| 264 | return self.map_range(va, size, paddrs, aspace=AddrSpace.PHYS, uncached=uncached) |
| 265 | |
| 266 | def vfree(self, vm:VirtMapping): |
| 267 | if not getenv("GMMU", 1): return self.pfree(vm.paddrs[0][0]) |
no test coverage detected