/* * Return true if we freed it, false if we didn't. */ bool cpu_uarea_free(void *va) { #ifdef _LP64 if (!MIPS_XKPHYS_P(va)) return false; paddr_t pa = MIPS_XKPHYS_TO_PHYS(va); #else if (!MIPS_KSEG0_P(va)) return false; paddr_t pa = MIPS_KSEG0_TO_PHYS(va); #endif #ifdef MIPS3_PLUS if (MIPS_CACHE_VIRTUAL_ALIAS) mips_dcache_inv_range((vaddr_t)va, USPACE); #endif for (const paddr_t epa = pa + USPACE; pa < epa; pa += PAGE_SIZE) { struct vm_page * const pg = PHYS_TO_VM_PAGE(pa); KASSERT(pg != NULL); uvm_pagefree(pg); } return true; }
int _kvm_minidump_kvatop(kvm_t *kd, u_long va, off_t *pa) { struct vmstate *vm; pt_entry_t pte; u_long offset, pteindex, a; off_t ofs; pt_entry_t *ptemap; if (ISALIVE(kd)) { _kvm_err(kd, 0, "kvm_kvatop called in live kernel!"); return (0); } offset = va & PAGE_MASK; /* Operate with page-aligned address */ va &= ~PAGE_MASK; vm = kd->vmst; ptemap = vm->ptemap; #if defined(__mips_n64) if (va >= MIPS_XKPHYS_START && va < MIPS_XKPHYS_END) a = (MIPS_XKPHYS_TO_PHYS(va)); else #endif if (va >= (u_long)MIPS_KSEG0_START && va < (u_long)MIPS_KSEG0_END) a = (MIPS_KSEG0_TO_PHYS(va)); else if (va >= (u_long)MIPS_KSEG1_START && va < (u_long)MIPS_KSEG1_END) a = (MIPS_KSEG1_TO_PHYS(va)); else if (va >= vm->hdr.kernbase) { pteindex = (va - vm->hdr.kernbase) >> PAGE_SHIFT; pte = ptemap[pteindex]; if (!pte) { _kvm_err(kd, kd->program, "_kvm_vatop: pte not valid"); goto invalid; } a = TLBLO_PTE_TO_PA(pte); } else {
/* * Map a (kernel) virtual address to a physical address. * * MIPS processor has 3 distinct kernel address ranges: * * - kseg0 kernel "virtual address" for the cached physical address space. * - kseg1 kernel "virtual address" for the uncached physical address space. * - kseg2 normal kernel "virtual address" mapped via the TLB. */ paddr_t kvtophys(vaddr_t kva) { pt_entry_t *pte; paddr_t phys; if (kva >= VM_MIN_KERNEL_ADDRESS) { if (kva >= VM_MAX_KERNEL_ADDRESS) goto overrun; pte = kvtopte(kva); if ((size_t) (pte - Sysmap) >= Sysmapsize) { printf("oops: Sysmap overrun, max %d index %zd\n", Sysmapsize, pte - Sysmap); } if (!mips_pg_v(pte->pt_entry)) { printf("kvtophys: pte not valid for %#"PRIxVADDR"\n", kva); } phys = mips_tlbpfn_to_paddr(pte->pt_entry) | (kva & PGOFSET); return phys; } if (MIPS_KSEG1_P(kva)) return MIPS_KSEG1_TO_PHYS(kva); if (MIPS_KSEG0_P(kva)) return MIPS_KSEG0_TO_PHYS(kva); #ifdef _LP64 if (MIPS_XKPHYS_P(kva)) return MIPS_XKPHYS_TO_PHYS(kva); #endif overrun: printf("Virtual address %#"PRIxVADDR": cannot map to physical\n", kva); #ifdef DDB Debugger(); return 0; /* XXX */ #endif panic("kvtophys"); }
/* * Map a (kernel) virtual address to a physical address. * * MIPS processor has 3 distinct kernel address ranges: * * - kseg0 kernel "virtual address" for the cached physical address space. * - kseg1 kernel "virtual address" for the uncached physical address space. * - kseg2 normal kernel "virtual address" mapped via the TLB. */ paddr_t kvtophys(vaddr_t kva) { paddr_t phys; if (MIPS_KSEG1_P(kva)) return MIPS_KSEG1_TO_PHYS(kva); if (MIPS_KSEG0_P(kva)) return MIPS_KSEG0_TO_PHYS(kva); if (kva >= VM_MIN_KERNEL_ADDRESS) { if (kva >= VM_MAX_KERNEL_ADDRESS) goto overrun; pt_entry_t * const ptep = pmap_pte_lookup(pmap_kernel(), kva); if (ptep == NULL) goto overrun; if (!pte_valid_p(*ptep)) { printf("kvtophys: pte not valid for %#"PRIxVADDR"\n", kva); } phys = pte_to_paddr(*ptep) | (kva & PGOFSET); return phys; } #ifdef _LP64 if (MIPS_XKPHYS_P(kva)) return MIPS_XKPHYS_TO_PHYS(kva); #endif overrun: printf("Virtual address %#"PRIxVADDR": cannot map to physical\n", kva); #ifdef DDB Debugger(); return 0; /* XXX */ #endif panic("kvtophys"); }
static void __BS(unmap)(void *v, bus_space_handle_t h, bus_size_t size, int acct) { #if !defined(_LP64) || defined(CHIP_EXTENT) bus_addr_t addr = 0; /* initialize to appease gcc */ #endif #ifndef _LP64 bool handle_is_km; /* determine if h is addr obtained from uvm_km_alloc */ handle_is_km = !(MIPS_KSEG0_P(h) || MIPS_KSEG1_P(h)); #ifdef __mips_n32 if (handle_is_km == true) handle_is_km = !MIPS_XKPHYS_P(h); #endif if (handle_is_km == true) { paddr_t pa; vaddr_t va = (vaddr_t)trunc_page(h); vsize_t sz = (vsize_t)round_page((h % PAGE_SIZE) + size); int s; s = splhigh(); if (pmap_extract(pmap_kernel(), (vaddr_t)h, &pa) == false) panic("%s: pmap_extract failed", __func__); addr = (bus_addr_t)pa; #if 0 printf("%s:%d: addr %#"PRIxBUSADDR", sz %#"PRIxVSIZE"\n", __func__, __LINE__, addr, sz); #endif /* sanity check: this is why we couldn't map w/ kseg[0,1] */ KASSERT (((addr + sz) & ~MIPS_PHYS_MASK) != 0); pmap_kremove(va, sz); pmap_update(pmap_kernel()); uvm_km_free(kernel_map, va, sz, UVM_KMF_VAONLY); splx(s); } #endif /* _LP64 */ #ifdef CHIP_EXTENT if (acct == 0) return; #ifdef EXTENT_DEBUG printf("%s: freeing handle %#"PRIxBSH" for %#"PRIxBUSSIZE"\n", __S(__BS(unmap)), h, size); #endif #ifdef _LP64 KASSERT(MIPS_XKPHYS_P(h)); addr = MIPS_XKPHYS_TO_PHYS(h); #else if (handle_is_km == false) { if (MIPS_KSEG0_P(h)) addr = MIPS_KSEG0_TO_PHYS(h); #ifdef __mips_n32 else if (MIPS_XKPHYS_P(h)) addr = MIPS_XKPHYS_TO_PHYS(h); #endif else addr = MIPS_KSEG1_TO_PHYS(h); } #endif #ifdef CHIP_W1_BUS_START if (addr >= CHIP_W1_SYS_START(v) && addr <= CHIP_W1_SYS_END(v)) { addr = CHIP_W1_BUS_START(v) + (addr - CHIP_W1_SYS_START(v)); } else #endif #ifdef CHIP_W2_BUS_START if (addr >= CHIP_W2_SYS_START(v) && addr <= CHIP_W2_SYS_END(v)) { addr = CHIP_W2_BUS_START(v) + (addr - CHIP_W2_SYS_START(v)); } else #endif #ifdef CHIP_W3_BUS_START if (addr >= CHIP_W3_SYS_START(v) && addr <= CHIP_W3_SYS_END(v)) { addr = CHIP_W3_BUS_START(v) + (addr - CHIP_W3_SYS_START(v)); } else #endif { printf("\n"); #ifdef CHIP_W1_BUS_START printf("%s: sys window[1]=0x%lx-0x%lx\n", __S(__BS(unmap)), (u_long)CHIP_W1_SYS_START(v), (u_long)CHIP_W1_SYS_END(v)); #endif #ifdef CHIP_W2_BUS_START printf("%s: sys window[2]=0x%lx-0x%lx\n", __S(__BS(unmap)), (u_long)CHIP_W2_SYS_START(v), (u_long)CHIP_W2_SYS_END(v)); #endif #ifdef CHIP_W3_BUS_START printf("%s: sys window[3]=0x%lx-0x%lx\n", __S(__BS(unmap)), (u_long)CHIP_W3_SYS_START(v), (u_long)CHIP_W3_SYS_END(v)); #endif panic("%s: don't know how to unmap %#"PRIxBSH, __S(__BS(unmap)), h); } #ifdef EXTENT_DEBUG printf("%s: freeing %#"PRIxBUSADDR" to %#"PRIxBUSADDR"\n", __S(__BS(unmap)), addr, addr + size - 1); #endif int error = extent_free(CHIP_EXTENT(v), addr, size, EX_NOWAIT | (CHIP_EX_MALLOC_SAFE(v) ? EX_MALLOCOK : 0)); if (error) { printf("%s: WARNING: could not unmap" " %#"PRIxBUSADDR"-%#"PRIxBUSADDR" (error %d)\n", __S(__BS(unmap)), addr, addr + size - 1, error); #ifdef EXTENT_DEBUG extent_print(CHIP_EXTENT(v)); #endif } #endif /* CHIP_EXTENT */ #if !defined(_LP64) || defined(CHIP_EXTENT) __USE(addr); #endif }