1*0ccebcdcSBALATON Zoltan/* 2*0ccebcdcSBALATON Zoltan * Physical memory access templates 3*0ccebcdcSBALATON Zoltan * 4*0ccebcdcSBALATON Zoltan * Copyright (c) 2003 Fabrice Bellard 5*0ccebcdcSBALATON Zoltan * Copyright (c) 2015 Linaro, Inc. 6*0ccebcdcSBALATON Zoltan * Copyright (c) 2016 Red Hat, Inc. 7*0ccebcdcSBALATON Zoltan * 8*0ccebcdcSBALATON Zoltan * This library is free software; you can redistribute it and/or 9*0ccebcdcSBALATON Zoltan * modify it under the terms of the GNU Lesser General Public 10*0ccebcdcSBALATON Zoltan * License as published by the Free Software Foundation; either 11*0ccebcdcSBALATON Zoltan * version 2.1 of the License, or (at your option) any later version. 12*0ccebcdcSBALATON Zoltan * 13*0ccebcdcSBALATON Zoltan * This library is distributed in the hope that it will be useful, 14*0ccebcdcSBALATON Zoltan * but WITHOUT ANY WARRANTY; without even the implied warranty of 15*0ccebcdcSBALATON Zoltan * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16*0ccebcdcSBALATON Zoltan * Lesser General Public License for more details. 17*0ccebcdcSBALATON Zoltan * 18*0ccebcdcSBALATON Zoltan * You should have received a copy of the GNU Lesser General Public 19*0ccebcdcSBALATON Zoltan * License along with this library; if not, see <http://www.gnu.org/licenses/>. 20*0ccebcdcSBALATON Zoltan */ 21*0ccebcdcSBALATON Zoltan 22*0ccebcdcSBALATON Zoltan/* warning: addr must be aligned */ 23*0ccebcdcSBALATON Zoltanstatic inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL, 24*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result, 25*0ccebcdcSBALATON Zoltan enum device_endian endian) 26*0ccebcdcSBALATON Zoltan{ 27*0ccebcdcSBALATON Zoltan uint8_t *ptr; 28*0ccebcdcSBALATON Zoltan uint64_t val; 29*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 30*0ccebcdcSBALATON Zoltan hwaddr l = 4; 31*0ccebcdcSBALATON Zoltan hwaddr addr1; 32*0ccebcdcSBALATON Zoltan MemTxResult r; 33*0ccebcdcSBALATON Zoltan bool release_lock = false; 34*0ccebcdcSBALATON Zoltan 35*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 36*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, false, attrs); 37*0ccebcdcSBALATON Zoltan if (l < 4 || !memory_access_is_direct(mr, false)) { 38*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 39*0ccebcdcSBALATON Zoltan 40*0ccebcdcSBALATON Zoltan /* I/O case */ 41*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_read(mr, addr1, &val, 42*0ccebcdcSBALATON Zoltan MO_32 | devend_memop(endian), attrs); 43*0ccebcdcSBALATON Zoltan } else { 44*0ccebcdcSBALATON Zoltan /* RAM case */ 45*0ccebcdcSBALATON Zoltan fuzz_dma_read_cb(addr, 4, mr); 46*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 47*0ccebcdcSBALATON Zoltan switch (endian) { 48*0ccebcdcSBALATON Zoltan case DEVICE_LITTLE_ENDIAN: 49*0ccebcdcSBALATON Zoltan val = ldl_le_p(ptr); 50*0ccebcdcSBALATON Zoltan break; 51*0ccebcdcSBALATON Zoltan case DEVICE_BIG_ENDIAN: 52*0ccebcdcSBALATON Zoltan val = ldl_be_p(ptr); 53*0ccebcdcSBALATON Zoltan break; 54*0ccebcdcSBALATON Zoltan default: 55*0ccebcdcSBALATON Zoltan val = ldl_p(ptr); 56*0ccebcdcSBALATON Zoltan break; 57*0ccebcdcSBALATON Zoltan } 58*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 59*0ccebcdcSBALATON Zoltan } 60*0ccebcdcSBALATON Zoltan if (result) { 61*0ccebcdcSBALATON Zoltan *result = r; 62*0ccebcdcSBALATON Zoltan } 63*0ccebcdcSBALATON Zoltan if (release_lock) { 64*0ccebcdcSBALATON Zoltan bql_unlock(); 65*0ccebcdcSBALATON Zoltan } 66*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 67*0ccebcdcSBALATON Zoltan return val; 68*0ccebcdcSBALATON Zoltan} 69*0ccebcdcSBALATON Zoltan 70*0ccebcdcSBALATON Zoltanuint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL, 71*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 72*0ccebcdcSBALATON Zoltan{ 73*0ccebcdcSBALATON Zoltan return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result, 74*0ccebcdcSBALATON Zoltan DEVICE_NATIVE_ENDIAN); 75*0ccebcdcSBALATON Zoltan} 76*0ccebcdcSBALATON Zoltan 77*0ccebcdcSBALATON Zoltanuint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL, 78*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 79*0ccebcdcSBALATON Zoltan{ 80*0ccebcdcSBALATON Zoltan return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result, 81*0ccebcdcSBALATON Zoltan DEVICE_LITTLE_ENDIAN); 82*0ccebcdcSBALATON Zoltan} 83*0ccebcdcSBALATON Zoltan 84*0ccebcdcSBALATON Zoltanuint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL, 85*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 86*0ccebcdcSBALATON Zoltan{ 87*0ccebcdcSBALATON Zoltan return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result, 88*0ccebcdcSBALATON Zoltan DEVICE_BIG_ENDIAN); 89*0ccebcdcSBALATON Zoltan} 90*0ccebcdcSBALATON Zoltan 91*0ccebcdcSBALATON Zoltan/* warning: addr must be aligned */ 92*0ccebcdcSBALATON Zoltanstatic inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL, 93*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result, 94*0ccebcdcSBALATON Zoltan enum device_endian endian) 95*0ccebcdcSBALATON Zoltan{ 96*0ccebcdcSBALATON Zoltan uint8_t *ptr; 97*0ccebcdcSBALATON Zoltan uint64_t val; 98*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 99*0ccebcdcSBALATON Zoltan hwaddr l = 8; 100*0ccebcdcSBALATON Zoltan hwaddr addr1; 101*0ccebcdcSBALATON Zoltan MemTxResult r; 102*0ccebcdcSBALATON Zoltan bool release_lock = false; 103*0ccebcdcSBALATON Zoltan 104*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 105*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, false, attrs); 106*0ccebcdcSBALATON Zoltan if (l < 8 || !memory_access_is_direct(mr, false)) { 107*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 108*0ccebcdcSBALATON Zoltan 109*0ccebcdcSBALATON Zoltan /* I/O case */ 110*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_read(mr, addr1, &val, 111*0ccebcdcSBALATON Zoltan MO_64 | devend_memop(endian), attrs); 112*0ccebcdcSBALATON Zoltan } else { 113*0ccebcdcSBALATON Zoltan /* RAM case */ 114*0ccebcdcSBALATON Zoltan fuzz_dma_read_cb(addr, 8, mr); 115*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 116*0ccebcdcSBALATON Zoltan switch (endian) { 117*0ccebcdcSBALATON Zoltan case DEVICE_LITTLE_ENDIAN: 118*0ccebcdcSBALATON Zoltan val = ldq_le_p(ptr); 119*0ccebcdcSBALATON Zoltan break; 120*0ccebcdcSBALATON Zoltan case DEVICE_BIG_ENDIAN: 121*0ccebcdcSBALATON Zoltan val = ldq_be_p(ptr); 122*0ccebcdcSBALATON Zoltan break; 123*0ccebcdcSBALATON Zoltan default: 124*0ccebcdcSBALATON Zoltan val = ldq_p(ptr); 125*0ccebcdcSBALATON Zoltan break; 126*0ccebcdcSBALATON Zoltan } 127*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 128*0ccebcdcSBALATON Zoltan } 129*0ccebcdcSBALATON Zoltan if (result) { 130*0ccebcdcSBALATON Zoltan *result = r; 131*0ccebcdcSBALATON Zoltan } 132*0ccebcdcSBALATON Zoltan if (release_lock) { 133*0ccebcdcSBALATON Zoltan bql_unlock(); 134*0ccebcdcSBALATON Zoltan } 135*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 136*0ccebcdcSBALATON Zoltan return val; 137*0ccebcdcSBALATON Zoltan} 138*0ccebcdcSBALATON Zoltan 139*0ccebcdcSBALATON Zoltanuint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL, 140*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 141*0ccebcdcSBALATON Zoltan{ 142*0ccebcdcSBALATON Zoltan return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result, 143*0ccebcdcSBALATON Zoltan DEVICE_NATIVE_ENDIAN); 144*0ccebcdcSBALATON Zoltan} 145*0ccebcdcSBALATON Zoltan 146*0ccebcdcSBALATON Zoltanuint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL, 147*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 148*0ccebcdcSBALATON Zoltan{ 149*0ccebcdcSBALATON Zoltan return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result, 150*0ccebcdcSBALATON Zoltan DEVICE_LITTLE_ENDIAN); 151*0ccebcdcSBALATON Zoltan} 152*0ccebcdcSBALATON Zoltan 153*0ccebcdcSBALATON Zoltanuint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL, 154*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 155*0ccebcdcSBALATON Zoltan{ 156*0ccebcdcSBALATON Zoltan return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result, 157*0ccebcdcSBALATON Zoltan DEVICE_BIG_ENDIAN); 158*0ccebcdcSBALATON Zoltan} 159*0ccebcdcSBALATON Zoltan 160*0ccebcdcSBALATON Zoltanuint8_t glue(address_space_ldub, SUFFIX)(ARG1_DECL, 161*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 162*0ccebcdcSBALATON Zoltan{ 163*0ccebcdcSBALATON Zoltan uint8_t *ptr; 164*0ccebcdcSBALATON Zoltan uint64_t val; 165*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 166*0ccebcdcSBALATON Zoltan hwaddr l = 1; 167*0ccebcdcSBALATON Zoltan hwaddr addr1; 168*0ccebcdcSBALATON Zoltan MemTxResult r; 169*0ccebcdcSBALATON Zoltan bool release_lock = false; 170*0ccebcdcSBALATON Zoltan 171*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 172*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, false, attrs); 173*0ccebcdcSBALATON Zoltan if (!memory_access_is_direct(mr, false)) { 174*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 175*0ccebcdcSBALATON Zoltan 176*0ccebcdcSBALATON Zoltan /* I/O case */ 177*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_read(mr, addr1, &val, MO_8, attrs); 178*0ccebcdcSBALATON Zoltan } else { 179*0ccebcdcSBALATON Zoltan /* RAM case */ 180*0ccebcdcSBALATON Zoltan fuzz_dma_read_cb(addr, 1, mr); 181*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 182*0ccebcdcSBALATON Zoltan val = ldub_p(ptr); 183*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 184*0ccebcdcSBALATON Zoltan } 185*0ccebcdcSBALATON Zoltan if (result) { 186*0ccebcdcSBALATON Zoltan *result = r; 187*0ccebcdcSBALATON Zoltan } 188*0ccebcdcSBALATON Zoltan if (release_lock) { 189*0ccebcdcSBALATON Zoltan bql_unlock(); 190*0ccebcdcSBALATON Zoltan } 191*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 192*0ccebcdcSBALATON Zoltan return val; 193*0ccebcdcSBALATON Zoltan} 194*0ccebcdcSBALATON Zoltan 195*0ccebcdcSBALATON Zoltan/* warning: addr must be aligned */ 196*0ccebcdcSBALATON Zoltanstatic inline uint16_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL, 197*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result, 198*0ccebcdcSBALATON Zoltan enum device_endian endian) 199*0ccebcdcSBALATON Zoltan{ 200*0ccebcdcSBALATON Zoltan uint8_t *ptr; 201*0ccebcdcSBALATON Zoltan uint64_t val; 202*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 203*0ccebcdcSBALATON Zoltan hwaddr l = 2; 204*0ccebcdcSBALATON Zoltan hwaddr addr1; 205*0ccebcdcSBALATON Zoltan MemTxResult r; 206*0ccebcdcSBALATON Zoltan bool release_lock = false; 207*0ccebcdcSBALATON Zoltan 208*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 209*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, false, attrs); 210*0ccebcdcSBALATON Zoltan if (l < 2 || !memory_access_is_direct(mr, false)) { 211*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 212*0ccebcdcSBALATON Zoltan 213*0ccebcdcSBALATON Zoltan /* I/O case */ 214*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_read(mr, addr1, &val, 215*0ccebcdcSBALATON Zoltan MO_16 | devend_memop(endian), attrs); 216*0ccebcdcSBALATON Zoltan } else { 217*0ccebcdcSBALATON Zoltan /* RAM case */ 218*0ccebcdcSBALATON Zoltan fuzz_dma_read_cb(addr, 2, mr); 219*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 220*0ccebcdcSBALATON Zoltan switch (endian) { 221*0ccebcdcSBALATON Zoltan case DEVICE_LITTLE_ENDIAN: 222*0ccebcdcSBALATON Zoltan val = lduw_le_p(ptr); 223*0ccebcdcSBALATON Zoltan break; 224*0ccebcdcSBALATON Zoltan case DEVICE_BIG_ENDIAN: 225*0ccebcdcSBALATON Zoltan val = lduw_be_p(ptr); 226*0ccebcdcSBALATON Zoltan break; 227*0ccebcdcSBALATON Zoltan default: 228*0ccebcdcSBALATON Zoltan val = lduw_p(ptr); 229*0ccebcdcSBALATON Zoltan break; 230*0ccebcdcSBALATON Zoltan } 231*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 232*0ccebcdcSBALATON Zoltan } 233*0ccebcdcSBALATON Zoltan if (result) { 234*0ccebcdcSBALATON Zoltan *result = r; 235*0ccebcdcSBALATON Zoltan } 236*0ccebcdcSBALATON Zoltan if (release_lock) { 237*0ccebcdcSBALATON Zoltan bql_unlock(); 238*0ccebcdcSBALATON Zoltan } 239*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 240*0ccebcdcSBALATON Zoltan return val; 241*0ccebcdcSBALATON Zoltan} 242*0ccebcdcSBALATON Zoltan 243*0ccebcdcSBALATON Zoltanuint16_t glue(address_space_lduw, SUFFIX)(ARG1_DECL, 244*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 245*0ccebcdcSBALATON Zoltan{ 246*0ccebcdcSBALATON Zoltan return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result, 247*0ccebcdcSBALATON Zoltan DEVICE_NATIVE_ENDIAN); 248*0ccebcdcSBALATON Zoltan} 249*0ccebcdcSBALATON Zoltan 250*0ccebcdcSBALATON Zoltanuint16_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL, 251*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 252*0ccebcdcSBALATON Zoltan{ 253*0ccebcdcSBALATON Zoltan return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result, 254*0ccebcdcSBALATON Zoltan DEVICE_LITTLE_ENDIAN); 255*0ccebcdcSBALATON Zoltan} 256*0ccebcdcSBALATON Zoltan 257*0ccebcdcSBALATON Zoltanuint16_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL, 258*0ccebcdcSBALATON Zoltan hwaddr addr, MemTxAttrs attrs, MemTxResult *result) 259*0ccebcdcSBALATON Zoltan{ 260*0ccebcdcSBALATON Zoltan return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result, 261*0ccebcdcSBALATON Zoltan DEVICE_BIG_ENDIAN); 262*0ccebcdcSBALATON Zoltan} 263*0ccebcdcSBALATON Zoltan 264*0ccebcdcSBALATON Zoltan/* warning: addr must be aligned. The ram page is not masked as dirty 265*0ccebcdcSBALATON Zoltan and the code inside is not invalidated. It is useful if the dirty 266*0ccebcdcSBALATON Zoltan bits are used to track modified PTEs */ 267*0ccebcdcSBALATON Zoltanvoid glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL, 268*0ccebcdcSBALATON Zoltan hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) 269*0ccebcdcSBALATON Zoltan{ 270*0ccebcdcSBALATON Zoltan uint8_t *ptr; 271*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 272*0ccebcdcSBALATON Zoltan hwaddr l = 4; 273*0ccebcdcSBALATON Zoltan hwaddr addr1; 274*0ccebcdcSBALATON Zoltan MemTxResult r; 275*0ccebcdcSBALATON Zoltan uint8_t dirty_log_mask; 276*0ccebcdcSBALATON Zoltan bool release_lock = false; 277*0ccebcdcSBALATON Zoltan 278*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 279*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, true, attrs); 280*0ccebcdcSBALATON Zoltan if (l < 4 || !memory_access_is_direct(mr, true)) { 281*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 282*0ccebcdcSBALATON Zoltan 283*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_write(mr, addr1, val, MO_32, attrs); 284*0ccebcdcSBALATON Zoltan } else { 285*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 286*0ccebcdcSBALATON Zoltan stl_p(ptr, val); 287*0ccebcdcSBALATON Zoltan 288*0ccebcdcSBALATON Zoltan dirty_log_mask = memory_region_get_dirty_log_mask(mr); 289*0ccebcdcSBALATON Zoltan dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE); 290*0ccebcdcSBALATON Zoltan cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr) + addr, 291*0ccebcdcSBALATON Zoltan 4, dirty_log_mask); 292*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 293*0ccebcdcSBALATON Zoltan } 294*0ccebcdcSBALATON Zoltan if (result) { 295*0ccebcdcSBALATON Zoltan *result = r; 296*0ccebcdcSBALATON Zoltan } 297*0ccebcdcSBALATON Zoltan if (release_lock) { 298*0ccebcdcSBALATON Zoltan bql_unlock(); 299*0ccebcdcSBALATON Zoltan } 300*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 301*0ccebcdcSBALATON Zoltan} 302*0ccebcdcSBALATON Zoltan 303*0ccebcdcSBALATON Zoltan/* warning: addr must be aligned */ 304*0ccebcdcSBALATON Zoltanstatic inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL, 305*0ccebcdcSBALATON Zoltan hwaddr addr, uint32_t val, MemTxAttrs attrs, 306*0ccebcdcSBALATON Zoltan MemTxResult *result, enum device_endian endian) 307*0ccebcdcSBALATON Zoltan{ 308*0ccebcdcSBALATON Zoltan uint8_t *ptr; 309*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 310*0ccebcdcSBALATON Zoltan hwaddr l = 4; 311*0ccebcdcSBALATON Zoltan hwaddr addr1; 312*0ccebcdcSBALATON Zoltan MemTxResult r; 313*0ccebcdcSBALATON Zoltan bool release_lock = false; 314*0ccebcdcSBALATON Zoltan 315*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 316*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, true, attrs); 317*0ccebcdcSBALATON Zoltan if (l < 4 || !memory_access_is_direct(mr, true)) { 318*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 319*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_write(mr, addr1, val, 320*0ccebcdcSBALATON Zoltan MO_32 | devend_memop(endian), attrs); 321*0ccebcdcSBALATON Zoltan } else { 322*0ccebcdcSBALATON Zoltan /* RAM case */ 323*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 324*0ccebcdcSBALATON Zoltan switch (endian) { 325*0ccebcdcSBALATON Zoltan case DEVICE_LITTLE_ENDIAN: 326*0ccebcdcSBALATON Zoltan stl_le_p(ptr, val); 327*0ccebcdcSBALATON Zoltan break; 328*0ccebcdcSBALATON Zoltan case DEVICE_BIG_ENDIAN: 329*0ccebcdcSBALATON Zoltan stl_be_p(ptr, val); 330*0ccebcdcSBALATON Zoltan break; 331*0ccebcdcSBALATON Zoltan default: 332*0ccebcdcSBALATON Zoltan stl_p(ptr, val); 333*0ccebcdcSBALATON Zoltan break; 334*0ccebcdcSBALATON Zoltan } 335*0ccebcdcSBALATON Zoltan invalidate_and_set_dirty(mr, addr1, 4); 336*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 337*0ccebcdcSBALATON Zoltan } 338*0ccebcdcSBALATON Zoltan if (result) { 339*0ccebcdcSBALATON Zoltan *result = r; 340*0ccebcdcSBALATON Zoltan } 341*0ccebcdcSBALATON Zoltan if (release_lock) { 342*0ccebcdcSBALATON Zoltan bql_unlock(); 343*0ccebcdcSBALATON Zoltan } 344*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 345*0ccebcdcSBALATON Zoltan} 346*0ccebcdcSBALATON Zoltan 347*0ccebcdcSBALATON Zoltanvoid glue(address_space_stl, SUFFIX)(ARG1_DECL, 348*0ccebcdcSBALATON Zoltan hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) 349*0ccebcdcSBALATON Zoltan{ 350*0ccebcdcSBALATON Zoltan glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs, 351*0ccebcdcSBALATON Zoltan result, DEVICE_NATIVE_ENDIAN); 352*0ccebcdcSBALATON Zoltan} 353*0ccebcdcSBALATON Zoltan 354*0ccebcdcSBALATON Zoltanvoid glue(address_space_stl_le, SUFFIX)(ARG1_DECL, 355*0ccebcdcSBALATON Zoltan hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) 356*0ccebcdcSBALATON Zoltan{ 357*0ccebcdcSBALATON Zoltan glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs, 358*0ccebcdcSBALATON Zoltan result, DEVICE_LITTLE_ENDIAN); 359*0ccebcdcSBALATON Zoltan} 360*0ccebcdcSBALATON Zoltan 361*0ccebcdcSBALATON Zoltanvoid glue(address_space_stl_be, SUFFIX)(ARG1_DECL, 362*0ccebcdcSBALATON Zoltan hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result) 363*0ccebcdcSBALATON Zoltan{ 364*0ccebcdcSBALATON Zoltan glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs, 365*0ccebcdcSBALATON Zoltan result, DEVICE_BIG_ENDIAN); 366*0ccebcdcSBALATON Zoltan} 367*0ccebcdcSBALATON Zoltan 368*0ccebcdcSBALATON Zoltanvoid glue(address_space_stb, SUFFIX)(ARG1_DECL, 369*0ccebcdcSBALATON Zoltan hwaddr addr, uint8_t val, MemTxAttrs attrs, MemTxResult *result) 370*0ccebcdcSBALATON Zoltan{ 371*0ccebcdcSBALATON Zoltan uint8_t *ptr; 372*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 373*0ccebcdcSBALATON Zoltan hwaddr l = 1; 374*0ccebcdcSBALATON Zoltan hwaddr addr1; 375*0ccebcdcSBALATON Zoltan MemTxResult r; 376*0ccebcdcSBALATON Zoltan bool release_lock = false; 377*0ccebcdcSBALATON Zoltan 378*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 379*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, true, attrs); 380*0ccebcdcSBALATON Zoltan if (!memory_access_is_direct(mr, true)) { 381*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 382*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_write(mr, addr1, val, MO_8, attrs); 383*0ccebcdcSBALATON Zoltan } else { 384*0ccebcdcSBALATON Zoltan /* RAM case */ 385*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 386*0ccebcdcSBALATON Zoltan stb_p(ptr, val); 387*0ccebcdcSBALATON Zoltan invalidate_and_set_dirty(mr, addr1, 1); 388*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 389*0ccebcdcSBALATON Zoltan } 390*0ccebcdcSBALATON Zoltan if (result) { 391*0ccebcdcSBALATON Zoltan *result = r; 392*0ccebcdcSBALATON Zoltan } 393*0ccebcdcSBALATON Zoltan if (release_lock) { 394*0ccebcdcSBALATON Zoltan bql_unlock(); 395*0ccebcdcSBALATON Zoltan } 396*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 397*0ccebcdcSBALATON Zoltan} 398*0ccebcdcSBALATON Zoltan 399*0ccebcdcSBALATON Zoltan/* warning: addr must be aligned */ 400*0ccebcdcSBALATON Zoltanstatic inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL, 401*0ccebcdcSBALATON Zoltan hwaddr addr, uint16_t val, MemTxAttrs attrs, 402*0ccebcdcSBALATON Zoltan MemTxResult *result, enum device_endian endian) 403*0ccebcdcSBALATON Zoltan{ 404*0ccebcdcSBALATON Zoltan uint8_t *ptr; 405*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 406*0ccebcdcSBALATON Zoltan hwaddr l = 2; 407*0ccebcdcSBALATON Zoltan hwaddr addr1; 408*0ccebcdcSBALATON Zoltan MemTxResult r; 409*0ccebcdcSBALATON Zoltan bool release_lock = false; 410*0ccebcdcSBALATON Zoltan 411*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 412*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, true, attrs); 413*0ccebcdcSBALATON Zoltan if (l < 2 || !memory_access_is_direct(mr, true)) { 414*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 415*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_write(mr, addr1, val, 416*0ccebcdcSBALATON Zoltan MO_16 | devend_memop(endian), attrs); 417*0ccebcdcSBALATON Zoltan } else { 418*0ccebcdcSBALATON Zoltan /* RAM case */ 419*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 420*0ccebcdcSBALATON Zoltan switch (endian) { 421*0ccebcdcSBALATON Zoltan case DEVICE_LITTLE_ENDIAN: 422*0ccebcdcSBALATON Zoltan stw_le_p(ptr, val); 423*0ccebcdcSBALATON Zoltan break; 424*0ccebcdcSBALATON Zoltan case DEVICE_BIG_ENDIAN: 425*0ccebcdcSBALATON Zoltan stw_be_p(ptr, val); 426*0ccebcdcSBALATON Zoltan break; 427*0ccebcdcSBALATON Zoltan default: 428*0ccebcdcSBALATON Zoltan stw_p(ptr, val); 429*0ccebcdcSBALATON Zoltan break; 430*0ccebcdcSBALATON Zoltan } 431*0ccebcdcSBALATON Zoltan invalidate_and_set_dirty(mr, addr1, 2); 432*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 433*0ccebcdcSBALATON Zoltan } 434*0ccebcdcSBALATON Zoltan if (result) { 435*0ccebcdcSBALATON Zoltan *result = r; 436*0ccebcdcSBALATON Zoltan } 437*0ccebcdcSBALATON Zoltan if (release_lock) { 438*0ccebcdcSBALATON Zoltan bql_unlock(); 439*0ccebcdcSBALATON Zoltan } 440*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 441*0ccebcdcSBALATON Zoltan} 442*0ccebcdcSBALATON Zoltan 443*0ccebcdcSBALATON Zoltanvoid glue(address_space_stw, SUFFIX)(ARG1_DECL, 444*0ccebcdcSBALATON Zoltan hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result) 445*0ccebcdcSBALATON Zoltan{ 446*0ccebcdcSBALATON Zoltan glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result, 447*0ccebcdcSBALATON Zoltan DEVICE_NATIVE_ENDIAN); 448*0ccebcdcSBALATON Zoltan} 449*0ccebcdcSBALATON Zoltan 450*0ccebcdcSBALATON Zoltanvoid glue(address_space_stw_le, SUFFIX)(ARG1_DECL, 451*0ccebcdcSBALATON Zoltan hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result) 452*0ccebcdcSBALATON Zoltan{ 453*0ccebcdcSBALATON Zoltan glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result, 454*0ccebcdcSBALATON Zoltan DEVICE_LITTLE_ENDIAN); 455*0ccebcdcSBALATON Zoltan} 456*0ccebcdcSBALATON Zoltan 457*0ccebcdcSBALATON Zoltanvoid glue(address_space_stw_be, SUFFIX)(ARG1_DECL, 458*0ccebcdcSBALATON Zoltan hwaddr addr, uint16_t val, MemTxAttrs attrs, MemTxResult *result) 459*0ccebcdcSBALATON Zoltan{ 460*0ccebcdcSBALATON Zoltan glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result, 461*0ccebcdcSBALATON Zoltan DEVICE_BIG_ENDIAN); 462*0ccebcdcSBALATON Zoltan} 463*0ccebcdcSBALATON Zoltan 464*0ccebcdcSBALATON Zoltanstatic void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL, 465*0ccebcdcSBALATON Zoltan hwaddr addr, uint64_t val, MemTxAttrs attrs, 466*0ccebcdcSBALATON Zoltan MemTxResult *result, enum device_endian endian) 467*0ccebcdcSBALATON Zoltan{ 468*0ccebcdcSBALATON Zoltan uint8_t *ptr; 469*0ccebcdcSBALATON Zoltan MemoryRegion *mr; 470*0ccebcdcSBALATON Zoltan hwaddr l = 8; 471*0ccebcdcSBALATON Zoltan hwaddr addr1; 472*0ccebcdcSBALATON Zoltan MemTxResult r; 473*0ccebcdcSBALATON Zoltan bool release_lock = false; 474*0ccebcdcSBALATON Zoltan 475*0ccebcdcSBALATON Zoltan RCU_READ_LOCK(); 476*0ccebcdcSBALATON Zoltan mr = TRANSLATE(addr, &addr1, &l, true, attrs); 477*0ccebcdcSBALATON Zoltan if (l < 8 || !memory_access_is_direct(mr, true)) { 478*0ccebcdcSBALATON Zoltan release_lock |= prepare_mmio_access(mr); 479*0ccebcdcSBALATON Zoltan r = memory_region_dispatch_write(mr, addr1, val, 480*0ccebcdcSBALATON Zoltan MO_64 | devend_memop(endian), attrs); 481*0ccebcdcSBALATON Zoltan } else { 482*0ccebcdcSBALATON Zoltan /* RAM case */ 483*0ccebcdcSBALATON Zoltan ptr = qemu_map_ram_ptr(mr->ram_block, addr1); 484*0ccebcdcSBALATON Zoltan switch (endian) { 485*0ccebcdcSBALATON Zoltan case DEVICE_LITTLE_ENDIAN: 486*0ccebcdcSBALATON Zoltan stq_le_p(ptr, val); 487*0ccebcdcSBALATON Zoltan break; 488*0ccebcdcSBALATON Zoltan case DEVICE_BIG_ENDIAN: 489*0ccebcdcSBALATON Zoltan stq_be_p(ptr, val); 490*0ccebcdcSBALATON Zoltan break; 491*0ccebcdcSBALATON Zoltan default: 492*0ccebcdcSBALATON Zoltan stq_p(ptr, val); 493*0ccebcdcSBALATON Zoltan break; 494*0ccebcdcSBALATON Zoltan } 495*0ccebcdcSBALATON Zoltan invalidate_and_set_dirty(mr, addr1, 8); 496*0ccebcdcSBALATON Zoltan r = MEMTX_OK; 497*0ccebcdcSBALATON Zoltan } 498*0ccebcdcSBALATON Zoltan if (result) { 499*0ccebcdcSBALATON Zoltan *result = r; 500*0ccebcdcSBALATON Zoltan } 501*0ccebcdcSBALATON Zoltan if (release_lock) { 502*0ccebcdcSBALATON Zoltan bql_unlock(); 503*0ccebcdcSBALATON Zoltan } 504*0ccebcdcSBALATON Zoltan RCU_READ_UNLOCK(); 505*0ccebcdcSBALATON Zoltan} 506*0ccebcdcSBALATON Zoltan 507*0ccebcdcSBALATON Zoltanvoid glue(address_space_stq, SUFFIX)(ARG1_DECL, 508*0ccebcdcSBALATON Zoltan hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result) 509*0ccebcdcSBALATON Zoltan{ 510*0ccebcdcSBALATON Zoltan glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result, 511*0ccebcdcSBALATON Zoltan DEVICE_NATIVE_ENDIAN); 512*0ccebcdcSBALATON Zoltan} 513*0ccebcdcSBALATON Zoltan 514*0ccebcdcSBALATON Zoltanvoid glue(address_space_stq_le, SUFFIX)(ARG1_DECL, 515*0ccebcdcSBALATON Zoltan hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result) 516*0ccebcdcSBALATON Zoltan{ 517*0ccebcdcSBALATON Zoltan glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result, 518*0ccebcdcSBALATON Zoltan DEVICE_LITTLE_ENDIAN); 519*0ccebcdcSBALATON Zoltan} 520*0ccebcdcSBALATON Zoltan 521*0ccebcdcSBALATON Zoltanvoid glue(address_space_stq_be, SUFFIX)(ARG1_DECL, 522*0ccebcdcSBALATON Zoltan hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result) 523*0ccebcdcSBALATON Zoltan{ 524*0ccebcdcSBALATON Zoltan glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result, 525*0ccebcdcSBALATON Zoltan DEVICE_BIG_ENDIAN); 526*0ccebcdcSBALATON Zoltan} 527*0ccebcdcSBALATON Zoltan 528*0ccebcdcSBALATON Zoltan#undef ARG1_DECL 529*0ccebcdcSBALATON Zoltan#undef ARG1 530*0ccebcdcSBALATON Zoltan#undef SUFFIX 531*0ccebcdcSBALATON Zoltan#undef TRANSLATE 532*0ccebcdcSBALATON Zoltan#undef RCU_READ_LOCK 533*0ccebcdcSBALATON Zoltan#undef RCU_READ_UNLOCK 534