balloon: Don't balloon roms
[qemu.git] / memory_ldst.inc.c
1 /*
2 * Physical memory access templates
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2015 Linaro, Inc.
6 * Copyright (c) 2016 Red Hat, Inc.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 */
21
22 /* warning: addr must be aligned */
23 static inline uint32_t glue(address_space_ldl_internal, SUFFIX)(ARG1_DECL,
24 hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
25 enum device_endian endian)
26 {
27 uint8_t *ptr;
28 uint64_t val;
29 MemoryRegion *mr;
30 hwaddr l = 4;
31 hwaddr addr1;
32 MemTxResult r;
33 bool release_lock = false;
34
35 RCU_READ_LOCK();
36 mr = TRANSLATE(addr, &addr1, &l, false);
37 if (l < 4 || !IS_DIRECT(mr, false)) {
38 release_lock |= prepare_mmio_access(mr);
39
40 /* I/O case */
41 r = memory_region_dispatch_read(mr, addr1, &val, 4, attrs);
42 #if defined(TARGET_WORDS_BIGENDIAN)
43 if (endian == DEVICE_LITTLE_ENDIAN) {
44 val = bswap32(val);
45 }
46 #else
47 if (endian == DEVICE_BIG_ENDIAN) {
48 val = bswap32(val);
49 }
50 #endif
51 } else {
52 /* RAM case */
53 ptr = MAP_RAM(mr, addr1);
54 switch (endian) {
55 case DEVICE_LITTLE_ENDIAN:
56 val = ldl_le_p(ptr);
57 break;
58 case DEVICE_BIG_ENDIAN:
59 val = ldl_be_p(ptr);
60 break;
61 default:
62 val = ldl_p(ptr);
63 break;
64 }
65 r = MEMTX_OK;
66 }
67 if (result) {
68 *result = r;
69 }
70 if (release_lock) {
71 qemu_mutex_unlock_iothread();
72 }
73 RCU_READ_UNLOCK();
74 return val;
75 }
76
77 uint32_t glue(address_space_ldl, SUFFIX)(ARG1_DECL,
78 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
79 {
80 return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result,
81 DEVICE_NATIVE_ENDIAN);
82 }
83
84 uint32_t glue(address_space_ldl_le, SUFFIX)(ARG1_DECL,
85 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
86 {
87 return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result,
88 DEVICE_LITTLE_ENDIAN);
89 }
90
91 uint32_t glue(address_space_ldl_be, SUFFIX)(ARG1_DECL,
92 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
93 {
94 return glue(address_space_ldl_internal, SUFFIX)(ARG1, addr, attrs, result,
95 DEVICE_BIG_ENDIAN);
96 }
97
98 uint32_t glue(ldl_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
99 {
100 return glue(address_space_ldl, SUFFIX)(ARG1, addr,
101 MEMTXATTRS_UNSPECIFIED, NULL);
102 }
103
104 uint32_t glue(ldl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
105 {
106 return glue(address_space_ldl_le, SUFFIX)(ARG1, addr,
107 MEMTXATTRS_UNSPECIFIED, NULL);
108 }
109
110 uint32_t glue(ldl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
111 {
112 return glue(address_space_ldl_be, SUFFIX)(ARG1, addr,
113 MEMTXATTRS_UNSPECIFIED, NULL);
114 }
115
116 /* warning: addr must be aligned */
117 static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL,
118 hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
119 enum device_endian endian)
120 {
121 uint8_t *ptr;
122 uint64_t val;
123 MemoryRegion *mr;
124 hwaddr l = 8;
125 hwaddr addr1;
126 MemTxResult r;
127 bool release_lock = false;
128
129 RCU_READ_LOCK();
130 mr = TRANSLATE(addr, &addr1, &l, false);
131 if (l < 8 || !IS_DIRECT(mr, false)) {
132 release_lock |= prepare_mmio_access(mr);
133
134 /* I/O case */
135 r = memory_region_dispatch_read(mr, addr1, &val, 8, attrs);
136 #if defined(TARGET_WORDS_BIGENDIAN)
137 if (endian == DEVICE_LITTLE_ENDIAN) {
138 val = bswap64(val);
139 }
140 #else
141 if (endian == DEVICE_BIG_ENDIAN) {
142 val = bswap64(val);
143 }
144 #endif
145 } else {
146 /* RAM case */
147 ptr = MAP_RAM(mr, addr1);
148 switch (endian) {
149 case DEVICE_LITTLE_ENDIAN:
150 val = ldq_le_p(ptr);
151 break;
152 case DEVICE_BIG_ENDIAN:
153 val = ldq_be_p(ptr);
154 break;
155 default:
156 val = ldq_p(ptr);
157 break;
158 }
159 r = MEMTX_OK;
160 }
161 if (result) {
162 *result = r;
163 }
164 if (release_lock) {
165 qemu_mutex_unlock_iothread();
166 }
167 RCU_READ_UNLOCK();
168 return val;
169 }
170
171 uint64_t glue(address_space_ldq, SUFFIX)(ARG1_DECL,
172 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
173 {
174 return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result,
175 DEVICE_NATIVE_ENDIAN);
176 }
177
178 uint64_t glue(address_space_ldq_le, SUFFIX)(ARG1_DECL,
179 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
180 {
181 return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result,
182 DEVICE_LITTLE_ENDIAN);
183 }
184
185 uint64_t glue(address_space_ldq_be, SUFFIX)(ARG1_DECL,
186 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
187 {
188 return glue(address_space_ldq_internal, SUFFIX)(ARG1, addr, attrs, result,
189 DEVICE_BIG_ENDIAN);
190 }
191
192 uint64_t glue(ldq_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
193 {
194 return glue(address_space_ldq, SUFFIX)(ARG1, addr,
195 MEMTXATTRS_UNSPECIFIED, NULL);
196 }
197
198 uint64_t glue(ldq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
199 {
200 return glue(address_space_ldq_le, SUFFIX)(ARG1, addr,
201 MEMTXATTRS_UNSPECIFIED, NULL);
202 }
203
204 uint64_t glue(ldq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
205 {
206 return glue(address_space_ldq_be, SUFFIX)(ARG1, addr,
207 MEMTXATTRS_UNSPECIFIED, NULL);
208 }
209
210 uint32_t glue(address_space_ldub, SUFFIX)(ARG1_DECL,
211 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
212 {
213 uint8_t *ptr;
214 uint64_t val;
215 MemoryRegion *mr;
216 hwaddr l = 1;
217 hwaddr addr1;
218 MemTxResult r;
219 bool release_lock = false;
220
221 RCU_READ_LOCK();
222 mr = TRANSLATE(addr, &addr1, &l, false);
223 if (!IS_DIRECT(mr, false)) {
224 release_lock |= prepare_mmio_access(mr);
225
226 /* I/O case */
227 r = memory_region_dispatch_read(mr, addr1, &val, 1, attrs);
228 } else {
229 /* RAM case */
230 ptr = MAP_RAM(mr, addr1);
231 val = ldub_p(ptr);
232 r = MEMTX_OK;
233 }
234 if (result) {
235 *result = r;
236 }
237 if (release_lock) {
238 qemu_mutex_unlock_iothread();
239 }
240 RCU_READ_UNLOCK();
241 return val;
242 }
243
244 uint32_t glue(ldub_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
245 {
246 return glue(address_space_ldub, SUFFIX)(ARG1, addr,
247 MEMTXATTRS_UNSPECIFIED, NULL);
248 }
249
250 /* warning: addr must be aligned */
251 static inline uint32_t glue(address_space_lduw_internal, SUFFIX)(ARG1_DECL,
252 hwaddr addr, MemTxAttrs attrs, MemTxResult *result,
253 enum device_endian endian)
254 {
255 uint8_t *ptr;
256 uint64_t val;
257 MemoryRegion *mr;
258 hwaddr l = 2;
259 hwaddr addr1;
260 MemTxResult r;
261 bool release_lock = false;
262
263 RCU_READ_LOCK();
264 mr = TRANSLATE(addr, &addr1, &l, false);
265 if (l < 2 || !IS_DIRECT(mr, false)) {
266 release_lock |= prepare_mmio_access(mr);
267
268 /* I/O case */
269 r = memory_region_dispatch_read(mr, addr1, &val, 2, attrs);
270 #if defined(TARGET_WORDS_BIGENDIAN)
271 if (endian == DEVICE_LITTLE_ENDIAN) {
272 val = bswap16(val);
273 }
274 #else
275 if (endian == DEVICE_BIG_ENDIAN) {
276 val = bswap16(val);
277 }
278 #endif
279 } else {
280 /* RAM case */
281 ptr = MAP_RAM(mr, addr1);
282 switch (endian) {
283 case DEVICE_LITTLE_ENDIAN:
284 val = lduw_le_p(ptr);
285 break;
286 case DEVICE_BIG_ENDIAN:
287 val = lduw_be_p(ptr);
288 break;
289 default:
290 val = lduw_p(ptr);
291 break;
292 }
293 r = MEMTX_OK;
294 }
295 if (result) {
296 *result = r;
297 }
298 if (release_lock) {
299 qemu_mutex_unlock_iothread();
300 }
301 RCU_READ_UNLOCK();
302 return val;
303 }
304
305 uint32_t glue(address_space_lduw, SUFFIX)(ARG1_DECL,
306 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
307 {
308 return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result,
309 DEVICE_NATIVE_ENDIAN);
310 }
311
312 uint32_t glue(address_space_lduw_le, SUFFIX)(ARG1_DECL,
313 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
314 {
315 return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result,
316 DEVICE_LITTLE_ENDIAN);
317 }
318
319 uint32_t glue(address_space_lduw_be, SUFFIX)(ARG1_DECL,
320 hwaddr addr, MemTxAttrs attrs, MemTxResult *result)
321 {
322 return glue(address_space_lduw_internal, SUFFIX)(ARG1, addr, attrs, result,
323 DEVICE_BIG_ENDIAN);
324 }
325
326 uint32_t glue(lduw_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
327 {
328 return glue(address_space_lduw, SUFFIX)(ARG1, addr,
329 MEMTXATTRS_UNSPECIFIED, NULL);
330 }
331
332 uint32_t glue(lduw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
333 {
334 return glue(address_space_lduw_le, SUFFIX)(ARG1, addr,
335 MEMTXATTRS_UNSPECIFIED, NULL);
336 }
337
338 uint32_t glue(lduw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr)
339 {
340 return glue(address_space_lduw_be, SUFFIX)(ARG1, addr,
341 MEMTXATTRS_UNSPECIFIED, NULL);
342 }
343
344 /* warning: addr must be aligned. The ram page is not masked as dirty
345 and the code inside is not invalidated. It is useful if the dirty
346 bits are used to track modified PTEs */
347 void glue(address_space_stl_notdirty, SUFFIX)(ARG1_DECL,
348 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
349 {
350 uint8_t *ptr;
351 MemoryRegion *mr;
352 hwaddr l = 4;
353 hwaddr addr1;
354 MemTxResult r;
355 uint8_t dirty_log_mask;
356 bool release_lock = false;
357
358 RCU_READ_LOCK();
359 mr = TRANSLATE(addr, &addr1, &l, true);
360 if (l < 4 || !IS_DIRECT(mr, true)) {
361 release_lock |= prepare_mmio_access(mr);
362
363 r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
364 } else {
365 ptr = MAP_RAM(mr, addr1);
366 stl_p(ptr, val);
367
368 dirty_log_mask = memory_region_get_dirty_log_mask(mr);
369 dirty_log_mask &= ~(1 << DIRTY_MEMORY_CODE);
370 cpu_physical_memory_set_dirty_range(memory_region_get_ram_addr(mr) + addr,
371 4, dirty_log_mask);
372 r = MEMTX_OK;
373 }
374 if (result) {
375 *result = r;
376 }
377 if (release_lock) {
378 qemu_mutex_unlock_iothread();
379 }
380 RCU_READ_UNLOCK();
381 }
382
383 void glue(stl_phys_notdirty, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
384 {
385 glue(address_space_stl_notdirty, SUFFIX)(ARG1, addr, val,
386 MEMTXATTRS_UNSPECIFIED, NULL);
387 }
388
389 /* warning: addr must be aligned */
390 static inline void glue(address_space_stl_internal, SUFFIX)(ARG1_DECL,
391 hwaddr addr, uint32_t val, MemTxAttrs attrs,
392 MemTxResult *result, enum device_endian endian)
393 {
394 uint8_t *ptr;
395 MemoryRegion *mr;
396 hwaddr l = 4;
397 hwaddr addr1;
398 MemTxResult r;
399 bool release_lock = false;
400
401 RCU_READ_LOCK();
402 mr = TRANSLATE(addr, &addr1, &l, true);
403 if (l < 4 || !IS_DIRECT(mr, true)) {
404 release_lock |= prepare_mmio_access(mr);
405
406 #if defined(TARGET_WORDS_BIGENDIAN)
407 if (endian == DEVICE_LITTLE_ENDIAN) {
408 val = bswap32(val);
409 }
410 #else
411 if (endian == DEVICE_BIG_ENDIAN) {
412 val = bswap32(val);
413 }
414 #endif
415 r = memory_region_dispatch_write(mr, addr1, val, 4, attrs);
416 } else {
417 /* RAM case */
418 ptr = MAP_RAM(mr, addr1);
419 switch (endian) {
420 case DEVICE_LITTLE_ENDIAN:
421 stl_le_p(ptr, val);
422 break;
423 case DEVICE_BIG_ENDIAN:
424 stl_be_p(ptr, val);
425 break;
426 default:
427 stl_p(ptr, val);
428 break;
429 }
430 INVALIDATE(mr, addr1, 4);
431 r = MEMTX_OK;
432 }
433 if (result) {
434 *result = r;
435 }
436 if (release_lock) {
437 qemu_mutex_unlock_iothread();
438 }
439 RCU_READ_UNLOCK();
440 }
441
442 void glue(address_space_stl, SUFFIX)(ARG1_DECL,
443 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
444 {
445 glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs,
446 result, DEVICE_NATIVE_ENDIAN);
447 }
448
449 void glue(address_space_stl_le, SUFFIX)(ARG1_DECL,
450 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
451 {
452 glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs,
453 result, DEVICE_LITTLE_ENDIAN);
454 }
455
456 void glue(address_space_stl_be, SUFFIX)(ARG1_DECL,
457 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
458 {
459 glue(address_space_stl_internal, SUFFIX)(ARG1, addr, val, attrs,
460 result, DEVICE_BIG_ENDIAN);
461 }
462
463 void glue(stl_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
464 {
465 glue(address_space_stl, SUFFIX)(ARG1, addr, val,
466 MEMTXATTRS_UNSPECIFIED, NULL);
467 }
468
469 void glue(stl_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
470 {
471 glue(address_space_stl_le, SUFFIX)(ARG1, addr, val,
472 MEMTXATTRS_UNSPECIFIED, NULL);
473 }
474
475 void glue(stl_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
476 {
477 glue(address_space_stl_be, SUFFIX)(ARG1, addr, val,
478 MEMTXATTRS_UNSPECIFIED, NULL);
479 }
480
481 void glue(address_space_stb, SUFFIX)(ARG1_DECL,
482 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
483 {
484 uint8_t *ptr;
485 MemoryRegion *mr;
486 hwaddr l = 1;
487 hwaddr addr1;
488 MemTxResult r;
489 bool release_lock = false;
490
491 RCU_READ_LOCK();
492 mr = TRANSLATE(addr, &addr1, &l, true);
493 if (!IS_DIRECT(mr, true)) {
494 release_lock |= prepare_mmio_access(mr);
495 r = memory_region_dispatch_write(mr, addr1, val, 1, attrs);
496 } else {
497 /* RAM case */
498 ptr = MAP_RAM(mr, addr1);
499 stb_p(ptr, val);
500 INVALIDATE(mr, addr1, 1);
501 r = MEMTX_OK;
502 }
503 if (result) {
504 *result = r;
505 }
506 if (release_lock) {
507 qemu_mutex_unlock_iothread();
508 }
509 RCU_READ_UNLOCK();
510 }
511
512 void glue(stb_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
513 {
514 glue(address_space_stb, SUFFIX)(ARG1, addr, val,
515 MEMTXATTRS_UNSPECIFIED, NULL);
516 }
517
518 /* warning: addr must be aligned */
519 static inline void glue(address_space_stw_internal, SUFFIX)(ARG1_DECL,
520 hwaddr addr, uint32_t val, MemTxAttrs attrs,
521 MemTxResult *result, enum device_endian endian)
522 {
523 uint8_t *ptr;
524 MemoryRegion *mr;
525 hwaddr l = 2;
526 hwaddr addr1;
527 MemTxResult r;
528 bool release_lock = false;
529
530 RCU_READ_LOCK();
531 mr = TRANSLATE(addr, &addr1, &l, true);
532 if (l < 2 || !IS_DIRECT(mr, true)) {
533 release_lock |= prepare_mmio_access(mr);
534
535 #if defined(TARGET_WORDS_BIGENDIAN)
536 if (endian == DEVICE_LITTLE_ENDIAN) {
537 val = bswap16(val);
538 }
539 #else
540 if (endian == DEVICE_BIG_ENDIAN) {
541 val = bswap16(val);
542 }
543 #endif
544 r = memory_region_dispatch_write(mr, addr1, val, 2, attrs);
545 } else {
546 /* RAM case */
547 ptr = MAP_RAM(mr, addr1);
548 switch (endian) {
549 case DEVICE_LITTLE_ENDIAN:
550 stw_le_p(ptr, val);
551 break;
552 case DEVICE_BIG_ENDIAN:
553 stw_be_p(ptr, val);
554 break;
555 default:
556 stw_p(ptr, val);
557 break;
558 }
559 INVALIDATE(mr, addr1, 2);
560 r = MEMTX_OK;
561 }
562 if (result) {
563 *result = r;
564 }
565 if (release_lock) {
566 qemu_mutex_unlock_iothread();
567 }
568 RCU_READ_UNLOCK();
569 }
570
571 void glue(address_space_stw, SUFFIX)(ARG1_DECL,
572 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
573 {
574 glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result,
575 DEVICE_NATIVE_ENDIAN);
576 }
577
578 void glue(address_space_stw_le, SUFFIX)(ARG1_DECL,
579 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
580 {
581 glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result,
582 DEVICE_LITTLE_ENDIAN);
583 }
584
585 void glue(address_space_stw_be, SUFFIX)(ARG1_DECL,
586 hwaddr addr, uint32_t val, MemTxAttrs attrs, MemTxResult *result)
587 {
588 glue(address_space_stw_internal, SUFFIX)(ARG1, addr, val, attrs, result,
589 DEVICE_BIG_ENDIAN);
590 }
591
592 void glue(stw_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
593 {
594 glue(address_space_stw, SUFFIX)(ARG1, addr, val,
595 MEMTXATTRS_UNSPECIFIED, NULL);
596 }
597
598 void glue(stw_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
599 {
600 glue(address_space_stw_le, SUFFIX)(ARG1, addr, val,
601 MEMTXATTRS_UNSPECIFIED, NULL);
602 }
603
604 void glue(stw_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint32_t val)
605 {
606 glue(address_space_stw_be, SUFFIX)(ARG1, addr, val,
607 MEMTXATTRS_UNSPECIFIED, NULL);
608 }
609
610 static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL,
611 hwaddr addr, uint64_t val, MemTxAttrs attrs,
612 MemTxResult *result, enum device_endian endian)
613 {
614 uint8_t *ptr;
615 MemoryRegion *mr;
616 hwaddr l = 8;
617 hwaddr addr1;
618 MemTxResult r;
619 bool release_lock = false;
620
621 RCU_READ_LOCK();
622 mr = TRANSLATE(addr, &addr1, &l, true);
623 if (l < 8 || !IS_DIRECT(mr, true)) {
624 release_lock |= prepare_mmio_access(mr);
625
626 #if defined(TARGET_WORDS_BIGENDIAN)
627 if (endian == DEVICE_LITTLE_ENDIAN) {
628 val = bswap64(val);
629 }
630 #else
631 if (endian == DEVICE_BIG_ENDIAN) {
632 val = bswap64(val);
633 }
634 #endif
635 r = memory_region_dispatch_write(mr, addr1, val, 8, attrs);
636 } else {
637 /* RAM case */
638 ptr = MAP_RAM(mr, addr1);
639 switch (endian) {
640 case DEVICE_LITTLE_ENDIAN:
641 stq_le_p(ptr, val);
642 break;
643 case DEVICE_BIG_ENDIAN:
644 stq_be_p(ptr, val);
645 break;
646 default:
647 stq_p(ptr, val);
648 break;
649 }
650 INVALIDATE(mr, addr1, 8);
651 r = MEMTX_OK;
652 }
653 if (result) {
654 *result = r;
655 }
656 if (release_lock) {
657 qemu_mutex_unlock_iothread();
658 }
659 RCU_READ_UNLOCK();
660 }
661
662 void glue(address_space_stq, SUFFIX)(ARG1_DECL,
663 hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result)
664 {
665 glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result,
666 DEVICE_NATIVE_ENDIAN);
667 }
668
669 void glue(address_space_stq_le, SUFFIX)(ARG1_DECL,
670 hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result)
671 {
672 glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result,
673 DEVICE_LITTLE_ENDIAN);
674 }
675
676 void glue(address_space_stq_be, SUFFIX)(ARG1_DECL,
677 hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result)
678 {
679 glue(address_space_stq_internal, SUFFIX)(ARG1, addr, val, attrs, result,
680 DEVICE_BIG_ENDIAN);
681 }
682
683 void glue(stq_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
684 {
685 glue(address_space_stq, SUFFIX)(ARG1, addr, val,
686 MEMTXATTRS_UNSPECIFIED, NULL);
687 }
688
689 void glue(stq_le_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
690 {
691 glue(address_space_stq_le, SUFFIX)(ARG1, addr, val,
692 MEMTXATTRS_UNSPECIFIED, NULL);
693 }
694
695 void glue(stq_be_phys, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val)
696 {
697 glue(address_space_stq_be, SUFFIX)(ARG1, addr, val,
698 MEMTXATTRS_UNSPECIFIED, NULL);
699 }
700
701 #undef ARG1_DECL
702 #undef ARG1
703 #undef SUFFIX
704 #undef TRANSLATE
705 #undef IS_DIRECT
706 #undef MAP_RAM
707 #undef INVALIDATE
708 #undef RCU_READ_LOCK
709 #undef RCU_READ_UNLOCK