summaryrefslogtreecommitdiff
path: root/emulators/qemu-devel/files/patch-z7-bsd-user-tls1-cognet
blob: f3aac00b4908ad0d814d64f6647c2ab29ac7223a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
--- oldqemu-1.3.0/bsd-user/syscall.c	2012-12-13 23:51:09.000000000 +0100
+++ qemu-1.3.0/bsd-user/syscall.c	2012-12-13 23:46:55.000000000 +0100
@@ -258,6 +258,16 @@ static abi_long do_freebsd_sysarch(void 
 #ifdef TARGET_ARM
 static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
 {
+   abi_ulong val;
+
+    switch (op) {
+    case TARGET_FREEBSD_ARM_SET_TP:
+        if (get_user(val, parms, abi_ulong))
+           return -TARGET_EINVAL;
+        cpu_set_tls(env, val);
+        return 0;
+    }
+
     return -TARGET_EINVAL;
 }
 #endif
--- oldqemu-1.3.0/bsd-user/elfload.c	2012-12-13 23:51:09.000000000 +0100
+++ qemu-1.3.0/bsd-user/elfload.c	2012-12-13 23:50:14.000000000 +0100
@@ -948,10 +948,8 @@ static abi_ulong create_elf_tables(abi_u
          * Force 16 byte _final_ alignment here for generality.
          */
         sp = sp &~ (abi_ulong)15;
-#ifdef __FreeBSD__
-	size = 0;
-#else
         size = (DLINFO_ITEMS + 1) * 2;
+#ifndef __FreeBSD__
         if (k_platform)
           size += 2;
 #ifdef DLINFO_ARCH_ITEMS
@@ -964,7 +962,6 @@ static abi_ulong create_elf_tables(abi_u
         if (size & 15)
             sp -= 16 - (size & 15);
 
-#ifndef __FreeBSD__
         /* This is correct because Linux defines
          * elf_addr_t as Elf32_Off / Elf64_Off
          */
@@ -989,8 +986,10 @@ static abi_ulong create_elf_tables(abi_u
         NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
         NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
         NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
+#ifndef __FreeBSD__
         if (k_platform)
             NEW_AUX_ENT(AT_PLATFORM, u_platform);
+#endif
 #ifdef ARCH_DLINFO
         /*
          * ARCH_DLINFO must come last so platform specific code can enforce
@@ -999,7 +998,6 @@ static abi_ulong create_elf_tables(abi_u
         ARCH_DLINFO;
 #endif
 #undef NEW_AUX_ENT
-#endif /* ! __FreeBSD__ */
 
         sp = loader_build_argptr(envc, argc, sp, p, !ibcs);
         return sp;
--- oldqemu-1.3.0/bsd-user/main.c	2012-12-13 23:51:09.000000000 +0100
+++ qemu-1.3.0/bsd-user/main.c	2012-12-13 23:01:30.000000000 +0100
@@ -392,6 +392,84 @@ void cpu_loop(CPUX86State *env)
 #ifdef TARGET_ARM
 // #define DEBUG_ARM
 
+static int do_strex(CPUARMState *env)
+{
+    uint32_t val;
+    int size;
+    int rc = 1;
+    int segv = 0;
+    uint32_t addr;
+    start_exclusive();
+    addr = env->exclusive_addr;
+    if (addr != env->exclusive_test) {
+        goto fail;
+    }
+    size = env->exclusive_info & 0xf;
+    switch (size) {
+    case 0:
+        segv = get_user_u8(val, addr);
+        break;
+    case 1:
+        segv = get_user_u16(val, addr);
+        break;
+    case 2:
+    case 3:
+        segv = get_user_u32(val, addr);
+        break;
+    default:
+        abort();
+    }
+    if (segv) {
+        env->cp15.c6_data = addr;
+        goto done;
+    }
+    if (val != env->exclusive_val) {
+        goto fail;
+    }
+    if (size == 3) {
+        segv = get_user_u32(val, addr + 4);
+        if (segv) {
+            env->cp15.c6_data = addr + 4;
+            goto done;
+        }
+        if (val != env->exclusive_high) {
+            goto fail;
+        }
+    }
+    val = env->regs[(env->exclusive_info >> 8) & 0xf];
+    switch (size) {
+    case 0:
+        segv = put_user_u8(val, addr);
+        break;
+    case 1:
+        segv = put_user_u16(val, addr);
+        break;
+    case 2:
+    case 3:
+        segv = put_user_u32(val, addr);
+        break;
+    }
+    if (segv) {
+        env->cp15.c6_data = addr;
+        goto done;
+    }
+    if (size == 3) {
+        val = env->regs[(env->exclusive_info >> 12) & 0xf];
+        segv = put_user_u32(val, addr + 4);
+        if (segv) {
+            env->cp15.c6_data = addr + 4;
+            goto done;
+        }
+    }
+    rc = 0;
+fail:
+    env->regs[15] += 4;
+    env->regs[(env->exclusive_info >> 4) & 0xf] = rc;
+done:
+    end_exclusive();
+    return segv;
+}
+
 void cpu_loop(CPUARMState *env)
 {
     int trapnr;
@@ -622,6 +700,7 @@ void cpu_loop(CPUARMState *env)
             if (do_kernel_trap(env))
               goto error;
             break;
+#endif
         case EXCP_STREX:
             if (do_strex(env)) {
                 addr = env->cp15.c6_data;
@@ -629,7 +708,6 @@ void cpu_loop(CPUARMState *env)
             }
             break;
         error:
-#endif
         default:
             fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
                     trapnr);
--- oldqemu-1.3.0/bsd-user/arm/syscall.h	2012-12-13 23:51:09.000000000 +0100
+++ qemu-1.3.0/bsd-user/arm/syscall.h	2012-12-13 23:45:22.000000000 +0100
@@ -21,3 +21,5 @@ struct target_pt_regs {
 #define ARM_r0		uregs[0]
 
 #define ARM_SYSCALL_BASE	0 /* XXX: FreeBSD only */
+
+#define TARGET_FREEBSD_ARM_SET_TP	2