~ubuntu-branches/ubuntu/vivid/qemu/vivid

« back to all changes in this revision

Viewing changes to debian/patches/ubuntu/arm64/0064-target-arm-A64-Implement-MRS-MSR-SYS-SYSL.patch

  • Committer: Package Import Robot
  • Author(s): dann frazier
  • Date: 2014-02-11 15:41:53 UTC
  • Revision ID: package-import@ubuntu.com-20140211154153-2d001tf0ium08u81
Tags: 1.7.0+dfsg-3ubuntu2
* Backport changes to enable qemu-user-static support for aarch64
* debian/control: add ppc64el to Architectures
* debian/rules: only install qemu-system-aarch64 on arm64.
  Fixes a FTBFS  when built twice in a row on non-arm64 due to a stale
  debian/qemu-system-aarch64 directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
From 89f9fb84d3bbee4cae1706a4ea73f2a0af8e55b6 Mon Sep 17 00:00:00 2001
 
2
From: Peter Maydell <peter.maydell@linaro.org>
 
3
Date: Sat, 4 Jan 2014 22:15:45 +0000
 
4
Subject: [PATCH 064/158] target-arm: A64: Implement MRS/MSR/SYS/SYSL
 
5
 
 
6
The AArch64 equivalent of the traditional AArch32
 
7
cp15 coprocessor registers is the set of instructions
 
8
MRS/MSR/SYS/SYSL, which cover between them both true
 
9
system registers and the "operations with side effects"
 
10
such as cache maintenance which in AArch32 are mixed
 
11
in with other cp15 registers. Implement these instructions
 
12
to look in the cpregs hashtable for the register or
 
13
operation.
 
14
 
 
15
Since we don't yet populate the cpregs hashtable with
 
16
any registers with the "AA64" bit set, everything will
 
17
still UNDEF at this point.
 
18
 
 
19
MSR/MRS is the first user of is_jmp = DISAS_UPDATE, so
 
20
fix an infelicity in its handling where the main loop
 
21
was requiring the caller to do the update of PC rather
 
22
than just doing it itself.
 
23
 
 
24
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
 
25
Reviewed-by: Richard Henderson <rth@twiddle.net>
 
26
---
 
27
 target-arm/translate-a64.c | 112 +++++++++++++++++++++++++++++++++------------
 
28
 1 file changed, 82 insertions(+), 30 deletions(-)
 
29
 
 
30
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
 
31
index e35d2f3..7a9ee82 100644
 
32
--- a/target-arm/translate-a64.c
 
33
+++ b/target-arm/translate-a64.c
 
34
@@ -733,28 +733,88 @@ static void handle_msr_i(DisasContext *s, uint32_t insn,
 
35
     unsupported_encoding(s, insn);
 
36
 }
 
37
 
 
38
-/* C5.6.204 SYS */
 
39
-static void handle_sys(DisasContext *s, uint32_t insn, unsigned int l,
 
40
-                       unsigned int op1, unsigned int op2,
 
41
+/* C5.6.129 MRS - move from system register
 
42
+ * C5.6.131 MSR (register) - move to system register
 
43
+ * C5.6.204 SYS
 
44
+ * C5.6.205 SYSL
 
45
+ * These are all essentially the same insn in 'read' and 'write'
 
46
+ * versions, with varying op0 fields.
 
47
+ */
 
48
+static void handle_sys(DisasContext *s, uint32_t insn, bool isread,
 
49
+                       unsigned int op0, unsigned int op1, unsigned int op2,
 
50
                        unsigned int crn, unsigned int crm, unsigned int rt)
 
51
 {
 
52
-    unsupported_encoding(s, insn);
 
53
-}
 
54
+    const ARMCPRegInfo *ri;
 
55
+    TCGv_i64 tcg_rt;
 
56
 
 
57
-/* C5.6.129 MRS - move from system register */
 
58
-static void handle_mrs(DisasContext *s, uint32_t insn, unsigned int op0,
 
59
-                       unsigned int op1, unsigned int op2,
 
60
-                       unsigned int crn, unsigned int crm, unsigned int rt)
 
61
-{
 
62
-    unsupported_encoding(s, insn);
 
63
-}
 
64
+    ri = get_arm_cp_reginfo(s->cp_regs,
 
65
+                            ENCODE_AA64_CP_REG(CP_REG_ARM64_SYSREG_CP,
 
66
+                                               crn, crm, op0, op1, op2));
 
67
 
 
68
-/* C5.6.131 MSR (register) - move to system register */
 
69
-static void handle_msr(DisasContext *s, uint32_t insn, unsigned int op0,
 
70
-                       unsigned int op1, unsigned int op2,
 
71
-                       unsigned int crn, unsigned int crm, unsigned int rt)
 
72
-{
 
73
-    unsupported_encoding(s, insn);
 
74
+    if (!ri) {
 
75
+        /* Unknown register */
 
76
+        unallocated_encoding(s);
 
77
+        return;
 
78
+    }
 
79
+
 
80
+    /* Check access permissions */
 
81
+    if (!cp_access_ok(s->current_pl, ri, isread)) {
 
82
+        unallocated_encoding(s);
 
83
+        return;
 
84
+    }
 
85
+
 
86
+    /* Handle special cases first */
 
87
+    switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
 
88
+    case ARM_CP_NOP:
 
89
+        return;
 
90
+    default:
 
91
+        break;
 
92
+    }
 
93
+
 
94
+    if (use_icount && (ri->type & ARM_CP_IO)) {
 
95
+        gen_io_start();
 
96
+    }
 
97
+
 
98
+    tcg_rt = cpu_reg(s, rt);
 
99
+
 
100
+    if (isread) {
 
101
+        if (ri->type & ARM_CP_CONST) {
 
102
+            tcg_gen_movi_i64(tcg_rt, ri->resetvalue);
 
103
+        } else if (ri->readfn) {
 
104
+            TCGv_ptr tmpptr;
 
105
+            gen_a64_set_pc_im(s->pc - 4);
 
106
+            tmpptr = tcg_const_ptr(ri);
 
107
+            gen_helper_get_cp_reg64(tcg_rt, cpu_env, tmpptr);
 
108
+            tcg_temp_free_ptr(tmpptr);
 
109
+        } else {
 
110
+            tcg_gen_ld_i64(tcg_rt, cpu_env, ri->fieldoffset);
 
111
+        }
 
112
+    } else {
 
113
+        if (ri->type & ARM_CP_CONST) {
 
114
+            /* If not forbidden by access permissions, treat as WI */
 
115
+            return;
 
116
+        } else if (ri->writefn) {
 
117
+            TCGv_ptr tmpptr;
 
118
+            gen_a64_set_pc_im(s->pc - 4);
 
119
+            tmpptr = tcg_const_ptr(ri);
 
120
+            gen_helper_set_cp_reg64(cpu_env, tmpptr, tcg_rt);
 
121
+            tcg_temp_free_ptr(tmpptr);
 
122
+        } else {
 
123
+            tcg_gen_st_i64(tcg_rt, cpu_env, ri->fieldoffset);
 
124
+        }
 
125
+    }
 
126
+
 
127
+    if (use_icount && (ri->type & ARM_CP_IO)) {
 
128
+        /* I/O operations must end the TB here (whether read or write) */
 
129
+        gen_io_end();
 
130
+        s->is_jmp = DISAS_UPDATE;
 
131
+    } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
 
132
+        /* We default to ending the TB on a coprocessor register write,
 
133
+         * but allow this to be suppressed by the register definition
 
134
+         * (usually only necessary to work around guest bugs).
 
135
+         */
 
136
+        s->is_jmp = DISAS_UPDATE;
 
137
+    }
 
138
 }
 
139
 
 
140
 /* C3.2.4 System
 
141
@@ -795,17 +855,7 @@ static void disas_system(DisasContext *s, uint32_t insn)
 
142
         }
 
143
         return;
 
144
     }
 
145
-
 
146
-    if (op0 == 1) {
 
147
-        /* C5.6.204 SYS */
 
148
-        handle_sys(s, insn, l, op1, op2, crn, crm, rt);
 
149
-    } else if (l) { /* op0 > 1 */
 
150
-        /* C5.6.129 MRS - move from system register */
 
151
-        handle_mrs(s, insn, op0, op1, op2, crn, crm, rt);
 
152
-    } else {
 
153
-        /* C5.6.131 MSR (register) - move to system register */
 
154
-        handle_msr(s, insn, op0, op1, op2, crn, crm, rt);
 
155
-    }
 
156
+    handle_sys(s, insn, l, op0, op1, op2, crn, crm, rt);
 
157
 }
 
158
 
 
159
 /* C3.2.3 Exception generation
 
160
@@ -3098,8 +3148,10 @@ void gen_intermediate_code_internal_a64(ARMCPU *cpu,
 
161
             gen_goto_tb(dc, 1, dc->pc);
 
162
             break;
 
163
         default:
 
164
-        case DISAS_JUMP:
 
165
         case DISAS_UPDATE:
 
166
+            gen_a64_set_pc_im(dc->pc);
 
167
+            /* fall through */
 
168
+        case DISAS_JUMP:
 
169
             /* indicate that the hash table must be used to find the next TB */
 
170
             tcg_gen_exit_tb(0);
 
171
             break;
 
172
-- 
 
173
1.9.rc1
 
174