1 | /* |
2 | * Helper routines to provide target memory access for semihosting |
3 | * syscalls in system emulation mode. |
4 | * |
5 | * Copyright (c) 2007 CodeSourcery. |
6 | * |
7 | * This code is licensed under the GPL |
8 | */ |
9 | |
10 | #ifndef SOFTMMU_SEMI_H |
11 | #define SOFTMMU_SEMI_H |
12 | |
13 | #include "cpu.h" |
14 | |
15 | static inline uint64_t softmmu_tget64(CPUArchState *env, target_ulong addr) |
16 | { |
17 | uint64_t val; |
18 | |
19 | cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 8, 0); |
20 | return tswap64(val); |
21 | } |
22 | |
23 | static inline uint32_t softmmu_tget32(CPUArchState *env, target_ulong addr) |
24 | { |
25 | uint32_t val; |
26 | |
27 | cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 4, 0); |
28 | return tswap32(val); |
29 | } |
30 | |
31 | static inline uint32_t softmmu_tget8(CPUArchState *env, target_ulong addr) |
32 | { |
33 | uint8_t val; |
34 | |
35 | cpu_memory_rw_debug(env_cpu(env), addr, &val, 1, 0); |
36 | return val; |
37 | } |
38 | |
39 | #define get_user_u64(arg, p) ({ arg = softmmu_tget64(env, p); 0; }) |
40 | #define get_user_u32(arg, p) ({ arg = softmmu_tget32(env, p) ; 0; }) |
41 | #define get_user_u8(arg, p) ({ arg = softmmu_tget8(env, p) ; 0; }) |
42 | #define get_user_ual(arg, p) get_user_u32(arg, p) |
43 | |
44 | static inline void softmmu_tput64(CPUArchState *env, |
45 | target_ulong addr, uint64_t val) |
46 | { |
47 | val = tswap64(val); |
48 | cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 8, 1); |
49 | } |
50 | |
51 | static inline void softmmu_tput32(CPUArchState *env, |
52 | target_ulong addr, uint32_t val) |
53 | { |
54 | val = tswap32(val); |
55 | cpu_memory_rw_debug(env_cpu(env), addr, (uint8_t *)&val, 4, 1); |
56 | } |
57 | #define put_user_u64(arg, p) ({ softmmu_tput64(env, p, arg) ; 0; }) |
58 | #define put_user_u32(arg, p) ({ softmmu_tput32(env, p, arg) ; 0; }) |
59 | #define put_user_ual(arg, p) put_user_u32(arg, p) |
60 | |
61 | static void *softmmu_lock_user(CPUArchState *env, |
62 | target_ulong addr, target_ulong len, int copy) |
63 | { |
64 | uint8_t *p; |
65 | /* TODO: Make this something that isn't fixed size. */ |
66 | p = malloc(len); |
67 | if (p && copy) { |
68 | cpu_memory_rw_debug(env_cpu(env), addr, p, len, 0); |
69 | } |
70 | return p; |
71 | } |
72 | #define lock_user(type, p, len, copy) softmmu_lock_user(env, p, len, copy) |
73 | static char *softmmu_lock_user_string(CPUArchState *env, target_ulong addr) |
74 | { |
75 | char *p; |
76 | char *s; |
77 | uint8_t c; |
78 | /* TODO: Make this something that isn't fixed size. */ |
79 | s = p = malloc(1024); |
80 | if (!s) { |
81 | return NULL; |
82 | } |
83 | do { |
84 | cpu_memory_rw_debug(env_cpu(env), addr, &c, 1, 0); |
85 | addr++; |
86 | *(p++) = c; |
87 | } while (c); |
88 | return s; |
89 | } |
90 | #define lock_user_string(p) softmmu_lock_user_string(env, p) |
91 | static void softmmu_unlock_user(CPUArchState *env, void *p, target_ulong addr, |
92 | target_ulong len) |
93 | { |
94 | if (len) { |
95 | cpu_memory_rw_debug(env_cpu(env), addr, p, len, 1); |
96 | } |
97 | free(p); |
98 | } |
99 | #define unlock_user(s, args, len) softmmu_unlock_user(env, s, args, len) |
100 | |
101 | #endif |
102 | |