diff --git a/arch/alpha/vtophys.cc b/arch/alpha/vtophys.cc index a1afdb05b..5e14b06d3 100644 --- a/arch/alpha/vtophys.cc +++ b/arch/alpha/vtophys.cc @@ -96,18 +96,19 @@ vtophys(ExecContext *xc, Addr vaddr) { Addr ptbr = xc->regs.ipr[AlphaISA::IPR_PALtemp20]; Addr paddr = 0; - if (vaddr < ALPHA_K0SEG_BASE) { - DPRINTF(VtoPhys, "vtophys: invalid vaddr %#x", vaddr); - } else if (vaddr < ALPHA_K1SEG_BASE) { - paddr = ALPHA_K0SEG_TO_PHYS(vaddr); + if (PC_PAL(vaddr)) { + paddr = vaddr & ~ULL(1); + } else if (!ptbr) { + paddr = vaddr; } else { - if (!ptbr) - panic("vtophys: ptbr is not set on virtual lookup"); - - Addr pte = kernel_pte_lookup(xc->physmem, ptbr, vaddr); - uint64_t entry = xc->physmem->phys_read_qword(pte); - if (pte && entry_valid(entry)) - paddr = PMAP_PTE_PA(entry) | (vaddr & PGOFSET); + if (vaddr >= ALPHA_K0SEG_BASE && vaddr <= ALPHA_K0SEG_END) { + paddr = ALPHA_K0SEG_TO_PHYS(vaddr); + } else { + Addr pte = kernel_pte_lookup(xc->physmem, ptbr, vaddr); + uint64_t entry = xc->physmem->phys_read_qword(pte); + if (pte && entry_valid(entry)) + paddr = PMAP_PTE_PA(entry) | (vaddr & PGOFSET); + } } DPRINTF(VtoPhys, "vtophys(%#x) -> %#x\n", vaddr, paddr); @@ -115,6 +116,12 @@ vtophys(ExecContext *xc, Addr vaddr) return paddr; } +uint8_t * +ptomem(ExecContext *xc, Addr paddr, size_t len) +{ + return xc->physmem->dma_addr(paddr, len); +} + uint8_t * vtomem(ExecContext *xc, Addr vaddr, size_t len) { diff --git a/arch/alpha/vtophys.hh b/arch/alpha/vtophys.hh index 47ee538a6..f5696e9c8 100644 --- a/arch/alpha/vtophys.hh +++ b/arch/alpha/vtophys.hh @@ -42,6 +42,7 @@ Addr kernel_pte_lookup(PhysicalMemory *pmem, Addr ptbr, Addr vaddr); Addr vtophys(PhysicalMemory *xc, Addr vaddr); Addr vtophys(ExecContext *xc, Addr vaddr); uint8_t *vtomem(ExecContext *xc, Addr vaddr, size_t len); +uint8_t *ptomem(ExecContext *xc, Addr paddr, size_t len); void CopyData(ExecContext *xc, void *dst, Addr vaddr, size_t len); void CopyString(ExecContext *xc, char *dst, Addr vaddr, size_t maxlen);