cputlb.c (4329d049d5b8d4af71c6b399d64a6d1b98856318) | cputlb.c (6d03226b42247b68ab2f0b3663e0f624335a4055) |
---|---|
1/* 2 * Common CPU TLB handling 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either --- 1499 unchanged lines hidden (view full) --- 1508 tlb_set_dirty(cpu, mem_vaddr); 1509 } 1510} 1511 1512static int probe_access_internal(CPUArchState *env, vaddr addr, 1513 int fault_size, MMUAccessType access_type, 1514 int mmu_idx, bool nonfault, 1515 void **phost, CPUTLBEntryFull **pfull, | 1/* 2 * Common CPU TLB handling 3 * 4 * Copyright (c) 2003 Fabrice Bellard 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either --- 1499 unchanged lines hidden (view full) --- 1508 tlb_set_dirty(cpu, mem_vaddr); 1509 } 1510} 1511 1512static int probe_access_internal(CPUArchState *env, vaddr addr, 1513 int fault_size, MMUAccessType access_type, 1514 int mmu_idx, bool nonfault, 1515 void **phost, CPUTLBEntryFull **pfull, |
1516 uintptr_t retaddr) | 1516 uintptr_t retaddr, bool check_mem_cbs) |
1517{ 1518 uintptr_t index = tlb_index(env, mmu_idx, addr); 1519 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr); 1520 uint64_t tlb_addr = tlb_read_idx(entry, access_type); 1521 vaddr page_addr = addr & TARGET_PAGE_MASK; 1522 int flags = TLB_FLAGS_MASK & ~TLB_FORCE_SLOW; | 1517{ 1518 uintptr_t index = tlb_index(env, mmu_idx, addr); 1519 CPUTLBEntry *entry = tlb_entry(env, mmu_idx, addr); 1520 uint64_t tlb_addr = tlb_read_idx(entry, access_type); 1521 vaddr page_addr = addr & TARGET_PAGE_MASK; 1522 int flags = TLB_FLAGS_MASK & ~TLB_FORCE_SLOW; |
1523 bool force_mmio = check_mem_cbs && cpu_plugin_mem_cbs_enabled(env_cpu(env)); |
|
1523 CPUTLBEntryFull *full; 1524 1525 if (!tlb_hit_page(tlb_addr, page_addr)) { 1526 if (!victim_tlb_hit(env, mmu_idx, index, access_type, page_addr)) { 1527 CPUState *cs = env_cpu(env); 1528 1529 if (!cs->cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type, 1530 mmu_idx, nonfault, retaddr)) { --- 17 unchanged lines hidden (view full) --- 1548 tlb_addr = tlb_read_idx(entry, access_type); 1549 } 1550 flags &= tlb_addr; 1551 1552 *pfull = full = &env_tlb(env)->d[mmu_idx].fulltlb[index]; 1553 flags |= full->slow_flags[access_type]; 1554 1555 /* Fold all "mmio-like" bits into TLB_MMIO. This is not RAM. */ | 1524 CPUTLBEntryFull *full; 1525 1526 if (!tlb_hit_page(tlb_addr, page_addr)) { 1527 if (!victim_tlb_hit(env, mmu_idx, index, access_type, page_addr)) { 1528 CPUState *cs = env_cpu(env); 1529 1530 if (!cs->cc->tcg_ops->tlb_fill(cs, addr, fault_size, access_type, 1531 mmu_idx, nonfault, retaddr)) { --- 17 unchanged lines hidden (view full) --- 1549 tlb_addr = tlb_read_idx(entry, access_type); 1550 } 1551 flags &= tlb_addr; 1552 1553 *pfull = full = &env_tlb(env)->d[mmu_idx].fulltlb[index]; 1554 flags |= full->slow_flags[access_type]; 1555 1556 /* Fold all "mmio-like" bits into TLB_MMIO. This is not RAM. */ |
1556 if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY))) { | 1557 if (unlikely(flags & ~(TLB_WATCHPOINT | TLB_NOTDIRTY)) 1558 || 1559 (access_type != MMU_INST_FETCH && force_mmio)) { |
1557 *phost = NULL; 1558 return TLB_MMIO; 1559 } 1560 1561 /* Everything else is RAM. */ 1562 *phost = (void *)((uintptr_t)addr + entry->addend); 1563 return flags; 1564} 1565 1566int probe_access_full(CPUArchState *env, vaddr addr, int size, 1567 MMUAccessType access_type, int mmu_idx, 1568 bool nonfault, void **phost, CPUTLBEntryFull **pfull, 1569 uintptr_t retaddr) 1570{ 1571 int flags = probe_access_internal(env, addr, size, access_type, mmu_idx, | 1560 *phost = NULL; 1561 return TLB_MMIO; 1562 } 1563 1564 /* Everything else is RAM. */ 1565 *phost = (void *)((uintptr_t)addr + entry->addend); 1566 return flags; 1567} 1568 1569int probe_access_full(CPUArchState *env, vaddr addr, int size, 1570 MMUAccessType access_type, int mmu_idx, 1571 bool nonfault, void **phost, CPUTLBEntryFull **pfull, 1572 uintptr_t retaddr) 1573{ 1574 int flags = probe_access_internal(env, addr, size, access_type, mmu_idx, |
1572 nonfault, phost, pfull, retaddr); | 1575 nonfault, phost, pfull, retaddr, true); |
1573 1574 /* Handle clean RAM pages. */ 1575 if (unlikely(flags & TLB_NOTDIRTY)) { 1576 notdirty_write(env_cpu(env), addr, 1, *pfull, retaddr); 1577 flags &= ~TLB_NOTDIRTY; 1578 } 1579 1580 return flags; 1581} 1582 | 1576 1577 /* Handle clean RAM pages. */ 1578 if (unlikely(flags & TLB_NOTDIRTY)) { 1579 notdirty_write(env_cpu(env), addr, 1, *pfull, retaddr); 1580 flags &= ~TLB_NOTDIRTY; 1581 } 1582 1583 return flags; 1584} 1585 |
1586int probe_access_full_mmu(CPUArchState *env, vaddr addr, int size, 1587 MMUAccessType access_type, int mmu_idx, 1588 void **phost, CPUTLBEntryFull **pfull) 1589{ 1590 void *discard_phost; 1591 CPUTLBEntryFull *discard_tlb; 1592 1593 /* privately handle users that don't need full results */ 1594 phost = phost ? phost : &discard_phost; 1595 pfull = pfull ? pfull : &discard_tlb; 1596 1597 int flags = probe_access_internal(env, addr, size, access_type, mmu_idx, 1598 true, phost, pfull, 0, false); 1599 1600 /* Handle clean RAM pages. */ 1601 if (unlikely(flags & TLB_NOTDIRTY)) { 1602 notdirty_write(env_cpu(env), addr, 1, *pfull, 0); 1603 flags &= ~TLB_NOTDIRTY; 1604 } 1605 1606 return flags; 1607} 1608 |
|
1583int probe_access_flags(CPUArchState *env, vaddr addr, int size, 1584 MMUAccessType access_type, int mmu_idx, 1585 bool nonfault, void **phost, uintptr_t retaddr) 1586{ 1587 CPUTLBEntryFull *full; 1588 int flags; 1589 1590 g_assert(-(addr | TARGET_PAGE_MASK) >= size); 1591 1592 flags = probe_access_internal(env, addr, size, access_type, mmu_idx, | 1609int probe_access_flags(CPUArchState *env, vaddr addr, int size, 1610 MMUAccessType access_type, int mmu_idx, 1611 bool nonfault, void **phost, uintptr_t retaddr) 1612{ 1613 CPUTLBEntryFull *full; 1614 int flags; 1615 1616 g_assert(-(addr | TARGET_PAGE_MASK) >= size); 1617 1618 flags = probe_access_internal(env, addr, size, access_type, mmu_idx, |
1593 nonfault, phost, &full, retaddr); | 1619 nonfault, phost, &full, retaddr, true); |
1594 1595 /* Handle clean RAM pages. */ 1596 if (unlikely(flags & TLB_NOTDIRTY)) { 1597 notdirty_write(env_cpu(env), addr, 1, full, retaddr); 1598 flags &= ~TLB_NOTDIRTY; 1599 } 1600 1601 return flags; --- 4 unchanged lines hidden (view full) --- 1606{ 1607 CPUTLBEntryFull *full; 1608 void *host; 1609 int flags; 1610 1611 g_assert(-(addr | TARGET_PAGE_MASK) >= size); 1612 1613 flags = probe_access_internal(env, addr, size, access_type, mmu_idx, | 1620 1621 /* Handle clean RAM pages. */ 1622 if (unlikely(flags & TLB_NOTDIRTY)) { 1623 notdirty_write(env_cpu(env), addr, 1, full, retaddr); 1624 flags &= ~TLB_NOTDIRTY; 1625 } 1626 1627 return flags; --- 4 unchanged lines hidden (view full) --- 1632{ 1633 CPUTLBEntryFull *full; 1634 void *host; 1635 int flags; 1636 1637 g_assert(-(addr | TARGET_PAGE_MASK) >= size); 1638 1639 flags = probe_access_internal(env, addr, size, access_type, mmu_idx, |
1614 false, &host, &full, retaddr); | 1640 false, &host, &full, retaddr, true); |
1615 1616 /* Per the interface, size == 0 merely faults the access. */ 1617 if (size == 0) { 1618 return NULL; 1619 } 1620 1621 if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) { 1622 /* Handle watchpoints. */ --- 16 unchanged lines hidden (view full) --- 1639void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, 1640 MMUAccessType access_type, int mmu_idx) 1641{ 1642 CPUTLBEntryFull *full; 1643 void *host; 1644 int flags; 1645 1646 flags = probe_access_internal(env, addr, 0, access_type, | 1641 1642 /* Per the interface, size == 0 merely faults the access. */ 1643 if (size == 0) { 1644 return NULL; 1645 } 1646 1647 if (unlikely(flags & (TLB_NOTDIRTY | TLB_WATCHPOINT))) { 1648 /* Handle watchpoints. */ --- 16 unchanged lines hidden (view full) --- 1665void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, 1666 MMUAccessType access_type, int mmu_idx) 1667{ 1668 CPUTLBEntryFull *full; 1669 void *host; 1670 int flags; 1671 1672 flags = probe_access_internal(env, addr, 0, access_type, |
1647 mmu_idx, true, &host, &full, 0); | 1673 mmu_idx, true, &host, &full, 0, false); |
1648 1649 /* No combination of flags are expected by the caller. */ 1650 return flags ? NULL : host; 1651} 1652 1653/* 1654 * Return a ram_addr_t for the virtual address for execution. 1655 * --- 6 unchanged lines hidden (view full) --- 1662 */ 1663tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr, 1664 void **hostp) 1665{ 1666 CPUTLBEntryFull *full; 1667 void *p; 1668 1669 (void)probe_access_internal(env, addr, 1, MMU_INST_FETCH, | 1674 1675 /* No combination of flags are expected by the caller. */ 1676 return flags ? NULL : host; 1677} 1678 1679/* 1680 * Return a ram_addr_t for the virtual address for execution. 1681 * --- 6 unchanged lines hidden (view full) --- 1688 */ 1689tb_page_addr_t get_page_addr_code_hostp(CPUArchState *env, vaddr addr, 1690 void **hostp) 1691{ 1692 CPUTLBEntryFull *full; 1693 void *p; 1694 1695 (void)probe_access_internal(env, addr, 1, MMU_INST_FETCH, |
1670 cpu_mmu_index(env, true), false, &p, &full, 0); | 1696 cpu_mmu_index(env, true), false, 1697 &p, &full, 0, false); |
1671 if (p == NULL) { 1672 return -1; 1673 } 1674 1675 if (full->lg_page_size < TARGET_PAGE_BITS) { 1676 return -1; 1677 } 1678 --- 1456 unchanged lines hidden --- | 1698 if (p == NULL) { 1699 return -1; 1700 } 1701 1702 if (full->lg_page_size < TARGET_PAGE_BITS) { 1703 return -1; 1704 } 1705 --- 1456 unchanged lines hidden --- |