qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio
at jcs-hda-dma 209 lines 6.0 kB view raw
1/* 2 * Software MMU support 3 * 4 * Generate inline load/store functions for one MMU mode and data 5 * size. 6 * 7 * Generate a store function as well as signed and unsigned loads. 8 * 9 * Not used directly but included from cpu_ldst.h. 10 * 11 * Copyright (c) 2003 Fabrice Bellard 12 * 13 * This library is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU Lesser General Public 15 * License as published by the Free Software Foundation; either 16 * version 2 of the License, or (at your option) any later version. 17 * 18 * This library is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 * Lesser General Public License for more details. 22 * 23 * You should have received a copy of the GNU Lesser General Public 24 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 25 */ 26 27#if !defined(SOFTMMU_CODE_ACCESS) 28#include "trace-root.h" 29#endif 30 31#include "trace/mem.h" 32 33#if DATA_SIZE == 8 34#define SUFFIX q 35#define USUFFIX q 36#define DATA_TYPE uint64_t 37#define SHIFT 3 38#elif DATA_SIZE == 4 39#define SUFFIX l 40#define USUFFIX l 41#define DATA_TYPE uint32_t 42#define SHIFT 2 43#elif DATA_SIZE == 2 44#define SUFFIX w 45#define USUFFIX uw 46#define DATA_TYPE uint16_t 47#define DATA_STYPE int16_t 48#define SHIFT 1 49#elif DATA_SIZE == 1 50#define SUFFIX b 51#define USUFFIX ub 52#define DATA_TYPE uint8_t 53#define DATA_STYPE int8_t 54#define SHIFT 0 55#else 56#error unsupported data size 57#endif 58 59#if DATA_SIZE == 8 60#define RES_TYPE uint64_t 61#else 62#define RES_TYPE uint32_t 63#endif 64 65#ifdef SOFTMMU_CODE_ACCESS 66#define ADDR_READ addr_code 67#define MMUSUFFIX _cmmu 68#define URETSUFFIX SUFFIX 69#define SRETSUFFIX SUFFIX 70#else 71#define ADDR_READ addr_read 72#define MMUSUFFIX _mmu 73#define URETSUFFIX USUFFIX 74#define SRETSUFFIX glue(s, SUFFIX) 75#endif 76 77/* generic load/store macros */ 78 79static inline RES_TYPE 80glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, 81 target_ulong ptr, 82 uintptr_t retaddr) 83{ 84 int page_index; 85 RES_TYPE res; 86 target_ulong addr; 87 int mmu_idx; 88 TCGMemOpIdx oi; 89 90#if !defined(SOFTMMU_CODE_ACCESS) 91 trace_guest_mem_before_exec( 92 ENV_GET_CPU(env), ptr, 93 trace_mem_build_info(SHIFT, false, MO_TE, false)); 94#endif 95 96 addr = ptr; 97 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 98 mmu_idx = CPU_MMU_INDEX; 99 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != 100 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { 101 oi = make_memop_idx(SHIFT, mmu_idx); 102 res = glue(glue(helper_ret_ld, URETSUFFIX), MMUSUFFIX)(env, addr, 103 oi, retaddr); 104 } else { 105 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; 106 res = glue(glue(ld, USUFFIX), _p)((uint8_t *)hostaddr); 107 } 108 return res; 109} 110 111static inline RES_TYPE 112glue(glue(cpu_ld, USUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) 113{ 114 return glue(glue(glue(cpu_ld, USUFFIX), MEMSUFFIX), _ra)(env, ptr, 0); 115} 116 117#if DATA_SIZE <= 2 118static inline int 119glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, 120 target_ulong ptr, 121 uintptr_t retaddr) 122{ 123 int res, page_index; 124 target_ulong addr; 125 int mmu_idx; 126 TCGMemOpIdx oi; 127 128#if !defined(SOFTMMU_CODE_ACCESS) 129 trace_guest_mem_before_exec( 130 ENV_GET_CPU(env), ptr, 131 trace_mem_build_info(SHIFT, true, MO_TE, false)); 132#endif 133 134 addr = ptr; 135 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 136 mmu_idx = CPU_MMU_INDEX; 137 if (unlikely(env->tlb_table[mmu_idx][page_index].ADDR_READ != 138 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { 139 oi = make_memop_idx(SHIFT, mmu_idx); 140 res = (DATA_STYPE)glue(glue(helper_ret_ld, SRETSUFFIX), 141 MMUSUFFIX)(env, addr, oi, retaddr); 142 } else { 143 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; 144 res = glue(glue(lds, SUFFIX), _p)((uint8_t *)hostaddr); 145 } 146 return res; 147} 148 149static inline int 150glue(glue(cpu_lds, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr) 151{ 152 return glue(glue(glue(cpu_lds, SUFFIX), MEMSUFFIX), _ra)(env, ptr, 0); 153} 154#endif 155 156#ifndef SOFTMMU_CODE_ACCESS 157 158/* generic store macro */ 159 160static inline void 161glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(CPUArchState *env, 162 target_ulong ptr, 163 RES_TYPE v, uintptr_t retaddr) 164{ 165 int page_index; 166 target_ulong addr; 167 int mmu_idx; 168 TCGMemOpIdx oi; 169 170#if !defined(SOFTMMU_CODE_ACCESS) 171 trace_guest_mem_before_exec( 172 ENV_GET_CPU(env), ptr, 173 trace_mem_build_info(SHIFT, false, MO_TE, true)); 174#endif 175 176 addr = ptr; 177 page_index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); 178 mmu_idx = CPU_MMU_INDEX; 179 if (unlikely(env->tlb_table[mmu_idx][page_index].addr_write != 180 (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))))) { 181 oi = make_memop_idx(SHIFT, mmu_idx); 182 glue(glue(helper_ret_st, SUFFIX), MMUSUFFIX)(env, addr, v, oi, 183 retaddr); 184 } else { 185 uintptr_t hostaddr = addr + env->tlb_table[mmu_idx][page_index].addend; 186 glue(glue(st, SUFFIX), _p)((uint8_t *)hostaddr, v); 187 } 188} 189 190static inline void 191glue(glue(cpu_st, SUFFIX), MEMSUFFIX)(CPUArchState *env, target_ulong ptr, 192 RES_TYPE v) 193{ 194 glue(glue(glue(cpu_st, SUFFIX), MEMSUFFIX), _ra)(env, ptr, v, 0); 195} 196 197#endif /* !SOFTMMU_CODE_ACCESS */ 198 199#undef RES_TYPE 200#undef DATA_TYPE 201#undef DATA_STYPE 202#undef SUFFIX 203#undef USUFFIX 204#undef DATA_SIZE 205#undef MMUSUFFIX 206#undef ADDR_READ 207#undef URETSUFFIX 208#undef SRETSUFFIX 209#undef SHIFT