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 ---