xref: /qemu/include/semihosting/uaccess.h (revision 23482ccd6bff4398643a90ca1c890f91f003e2c1)
16b3a45ccSpbrook /*
26b3a45ccSpbrook  * Helper routines to provide target memory access for semihosting
36b3a45ccSpbrook  * syscalls in system emulation mode.
46b3a45ccSpbrook  *
56b3a45ccSpbrook  * Copyright (c) 2007 CodeSourcery.
66b3a45ccSpbrook  *
78e31bf38SMatthew Fernandez  * This code is licensed under the GPL
86b3a45ccSpbrook  */
9175de524SMarkus Armbruster 
10f14eced5SPhilippe Mathieu-Daudé #ifndef SEMIHOSTING_UACCESS_H
11f14eced5SPhilippe Mathieu-Daudé #define SEMIHOSTING_UACCESS_H
12f14eced5SPhilippe Mathieu-Daudé 
13f14eced5SPhilippe Mathieu-Daudé #ifdef CONFIG_USER_ONLY
14f14eced5SPhilippe Mathieu-Daudé #error Cannot include semihosting/uaccess.h from user emulation
15f14eced5SPhilippe Mathieu-Daudé #endif
166b3a45ccSpbrook 
173aac8abaSPhilippe Mathieu-Daudé #include "exec/cpu-common.h"
183aac8abaSPhilippe Mathieu-Daudé #include "exec/cpu-defs.h"
193aac8abaSPhilippe Mathieu-Daudé #include "exec/tswap.h"
2074781c08SPhilippe Mathieu-Daudé #include "exec/page-protection.h"
21ec150c7eSMarkus Armbruster 
22*23482ccdSPhilippe Mathieu-Daudé /**
23*23482ccdSPhilippe Mathieu-Daudé  * get_user_u64:
24*23482ccdSPhilippe Mathieu-Daudé  *
25*23482ccdSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error.
26*23482ccdSPhilippe Mathieu-Daudé  */
278ce5c644SRichard Henderson #define get_user_u64(val, addr)                                         \
288ce5c644SRichard Henderson     ({ uint64_t val_ = 0;                                               \
298ce5c644SRichard Henderson        int ret_ = cpu_memory_rw_debug(env_cpu(env), (addr),             \
308ce5c644SRichard Henderson                                       &val_, sizeof(val_), 0);          \
318ce5c644SRichard Henderson        (val) = tswap64(val_); ret_; })
3244d4a499SPeter Maydell 
33*23482ccdSPhilippe Mathieu-Daudé /**
34*23482ccdSPhilippe Mathieu-Daudé  * get_user_u32:
35*23482ccdSPhilippe Mathieu-Daudé  *
36*23482ccdSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error.
37*23482ccdSPhilippe Mathieu-Daudé  */
388ce5c644SRichard Henderson #define get_user_u32(val, addr)                                         \
398ce5c644SRichard Henderson     ({ uint32_t val_ = 0;                                               \
408ce5c644SRichard Henderson        int ret_ = cpu_memory_rw_debug(env_cpu(env), (addr),             \
418ce5c644SRichard Henderson                                       &val_, sizeof(val_), 0);          \
428ce5c644SRichard Henderson        (val) = tswap32(val_); ret_; })
4344d4a499SPeter Maydell 
44*23482ccdSPhilippe Mathieu-Daudé /**
45*23482ccdSPhilippe Mathieu-Daudé  * get_user_u8:
46*23482ccdSPhilippe Mathieu-Daudé  *
47*23482ccdSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error.
48*23482ccdSPhilippe Mathieu-Daudé  */
498ce5c644SRichard Henderson #define get_user_u8(val, addr)                                          \
508ce5c644SRichard Henderson     ({ uint8_t val_ = 0;                                                \
518ce5c644SRichard Henderson        int ret_ = cpu_memory_rw_debug(env_cpu(env), (addr),             \
528ce5c644SRichard Henderson                                       &val_, sizeof(val_), 0);          \
538ce5c644SRichard Henderson        (val) = val_; ret_; })
546b3a45ccSpbrook 
55*23482ccdSPhilippe Mathieu-Daudé /**
56*23482ccdSPhilippe Mathieu-Daudé  * get_user_ual:
57*23482ccdSPhilippe Mathieu-Daudé  *
58*23482ccdSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error.
59*23482ccdSPhilippe Mathieu-Daudé  */
602f619698Sbellard #define get_user_ual(arg, p) get_user_u32(arg, p)
616b3a45ccSpbrook 
62*23482ccdSPhilippe Mathieu-Daudé /**
63*23482ccdSPhilippe Mathieu-Daudé  * put_user_u64:
64*23482ccdSPhilippe Mathieu-Daudé  *
65*23482ccdSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error.
66*23482ccdSPhilippe Mathieu-Daudé  */
678ce5c644SRichard Henderson #define put_user_u64(val, addr)                                         \
688ce5c644SRichard Henderson     ({ uint64_t val_ = tswap64(val);                                    \
698ce5c644SRichard Henderson        cpu_memory_rw_debug(env_cpu(env), (addr), &val_, sizeof(val_), 1); })
7044d4a499SPeter Maydell 
71*23482ccdSPhilippe Mathieu-Daudé /**
72*23482ccdSPhilippe Mathieu-Daudé  * put_user_u32:
73*23482ccdSPhilippe Mathieu-Daudé  *
74*23482ccdSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error.
75*23482ccdSPhilippe Mathieu-Daudé  */
768ce5c644SRichard Henderson #define put_user_u32(val, addr)                                         \
778ce5c644SRichard Henderson     ({ uint32_t val_ = tswap32(val);                                    \
788ce5c644SRichard Henderson        cpu_memory_rw_debug(env_cpu(env), (addr), &val_, sizeof(val_), 1); })
798ce5c644SRichard Henderson 
80*23482ccdSPhilippe Mathieu-Daudé /**
81*23482ccdSPhilippe Mathieu-Daudé  * put_user_ual:
82*23482ccdSPhilippe Mathieu-Daudé  *
83*23482ccdSPhilippe Mathieu-Daudé  * Returns: 0 on success, -1 on error.
84*23482ccdSPhilippe Mathieu-Daudé  */
852f619698Sbellard #define put_user_ual(arg, p) put_user_u32(arg, p)
866b3a45ccSpbrook 
87*23482ccdSPhilippe Mathieu-Daudé /**
88*23482ccdSPhilippe Mathieu-Daudé  * uaccess_lock_user:
89*23482ccdSPhilippe Mathieu-Daudé  *
90*23482ccdSPhilippe Mathieu-Daudé  * The returned pointer should be freed using uaccess_unlock_user().
91*23482ccdSPhilippe Mathieu-Daudé  */
92f14eced5SPhilippe Mathieu-Daudé void *uaccess_lock_user(CPUArchState *env, target_ulong addr,
930a922181SRichard Henderson                         target_ulong len, bool copy);
94*23482ccdSPhilippe Mathieu-Daudé /**
95*23482ccdSPhilippe Mathieu-Daudé  * lock_user:
96*23482ccdSPhilippe Mathieu-Daudé  *
97*23482ccdSPhilippe Mathieu-Daudé  * The returned pointer should be freed using unlock_user().
98*23482ccdSPhilippe Mathieu-Daudé  */
99f14eced5SPhilippe Mathieu-Daudé #define lock_user(type, p, len, copy) uaccess_lock_user(env, p, len, copy)
1008ce5c644SRichard Henderson 
101*23482ccdSPhilippe Mathieu-Daudé /**
102*23482ccdSPhilippe Mathieu-Daudé  * uaccess_lock_user_string:
103*23482ccdSPhilippe Mathieu-Daudé  *
104*23482ccdSPhilippe Mathieu-Daudé  * The returned string should be freed using uaccess_unlock_user().
105*23482ccdSPhilippe Mathieu-Daudé  */
106f14eced5SPhilippe Mathieu-Daudé char *uaccess_lock_user_string(CPUArchState *env, target_ulong addr);
107*23482ccdSPhilippe Mathieu-Daudé /**
108*23482ccdSPhilippe Mathieu-Daudé  * uaccess_lock_user_string:
109*23482ccdSPhilippe Mathieu-Daudé  *
110*23482ccdSPhilippe Mathieu-Daudé  * The returned string should be freed using unlock_user().
111*23482ccdSPhilippe Mathieu-Daudé  */
112f14eced5SPhilippe Mathieu-Daudé #define lock_user_string(p) uaccess_lock_user_string(env, p)
1138ce5c644SRichard Henderson 
114f14eced5SPhilippe Mathieu-Daudé void uaccess_unlock_user(CPUArchState *env, void *p,
1150a922181SRichard Henderson                          target_ulong addr, target_ulong len);
116f14eced5SPhilippe Mathieu-Daudé #define unlock_user(s, args, len) uaccess_unlock_user(env, s, args, len)
117cb9c377fSPaolo Bonzini 
118f14eced5SPhilippe Mathieu-Daudé ssize_t uaccess_strlen_user(CPUArchState *env, target_ulong addr);
119f14eced5SPhilippe Mathieu-Daudé #define target_strlen(p) uaccess_strlen_user(env, p)
1205f9ca6f3SRichard Henderson 
121c89a14adSRichard Henderson #endif /* SEMIHOSTING_SOFTMMU_UACCESS_H */
122