Merge tag 'mfd-for-linus-3.20' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[pandora-kernel.git] / arch / arm64 / kernel / insn.c
1 /*
2  * Copyright (C) 2013 Huawei Ltd.
3  * Author: Jiang Liu <liuj97@gmail.com>
4  *
5  * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19 #include <linux/bitops.h>
20 #include <linux/bug.h>
21 #include <linux/compiler.h>
22 #include <linux/kernel.h>
23 #include <linux/mm.h>
24 #include <linux/smp.h>
25 #include <linux/spinlock.h>
26 #include <linux/stop_machine.h>
27 #include <linux/types.h>
28 #include <linux/uaccess.h>
29
30 #include <asm/cacheflush.h>
31 #include <asm/debug-monitors.h>
32 #include <asm/fixmap.h>
33 #include <asm/insn.h>
34
35 #define AARCH64_INSN_SF_BIT     BIT(31)
36 #define AARCH64_INSN_N_BIT      BIT(22)
37
38 static int aarch64_insn_encoding_class[] = {
39         AARCH64_INSN_CLS_UNKNOWN,
40         AARCH64_INSN_CLS_UNKNOWN,
41         AARCH64_INSN_CLS_UNKNOWN,
42         AARCH64_INSN_CLS_UNKNOWN,
43         AARCH64_INSN_CLS_LDST,
44         AARCH64_INSN_CLS_DP_REG,
45         AARCH64_INSN_CLS_LDST,
46         AARCH64_INSN_CLS_DP_FPSIMD,
47         AARCH64_INSN_CLS_DP_IMM,
48         AARCH64_INSN_CLS_DP_IMM,
49         AARCH64_INSN_CLS_BR_SYS,
50         AARCH64_INSN_CLS_BR_SYS,
51         AARCH64_INSN_CLS_LDST,
52         AARCH64_INSN_CLS_DP_REG,
53         AARCH64_INSN_CLS_LDST,
54         AARCH64_INSN_CLS_DP_FPSIMD,
55 };
56
57 enum aarch64_insn_encoding_class __kprobes aarch64_get_insn_class(u32 insn)
58 {
59         return aarch64_insn_encoding_class[(insn >> 25) & 0xf];
60 }
61
62 /* NOP is an alias of HINT */
63 bool __kprobes aarch64_insn_is_nop(u32 insn)
64 {
65         if (!aarch64_insn_is_hint(insn))
66                 return false;
67
68         switch (insn & 0xFE0) {
69         case AARCH64_INSN_HINT_YIELD:
70         case AARCH64_INSN_HINT_WFE:
71         case AARCH64_INSN_HINT_WFI:
72         case AARCH64_INSN_HINT_SEV:
73         case AARCH64_INSN_HINT_SEVL:
74                 return false;
75         default:
76                 return true;
77         }
78 }
79
80 static DEFINE_SPINLOCK(patch_lock);
81
82 static void __kprobes *patch_map(void *addr, int fixmap)
83 {
84         unsigned long uintaddr = (uintptr_t) addr;
85         bool module = !core_kernel_text(uintaddr);
86         struct page *page;
87
88         if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX))
89                 page = vmalloc_to_page(addr);
90         else
91                 page = virt_to_page(addr);
92
93         BUG_ON(!page);
94         set_fixmap(fixmap, page_to_phys(page));
95
96         return (void *) (__fix_to_virt(fixmap) + (uintaddr & ~PAGE_MASK));
97 }
98
99 static void __kprobes patch_unmap(int fixmap)
100 {
101         clear_fixmap(fixmap);
102 }
103 /*
104  * In ARMv8-A, A64 instructions have a fixed length of 32 bits and are always
105  * little-endian.
106  */
107 int __kprobes aarch64_insn_read(void *addr, u32 *insnp)
108 {
109         int ret;
110         u32 val;
111
112         ret = probe_kernel_read(&val, addr, AARCH64_INSN_SIZE);
113         if (!ret)
114                 *insnp = le32_to_cpu(val);
115
116         return ret;
117 }
118
119 static int __kprobes __aarch64_insn_write(void *addr, u32 insn)
120 {
121         void *waddr = addr;
122         unsigned long flags = 0;
123         int ret;
124
125         spin_lock_irqsave(&patch_lock, flags);
126         waddr = patch_map(addr, FIX_TEXT_POKE0);
127
128         ret = probe_kernel_write(waddr, &insn, AARCH64_INSN_SIZE);
129
130         patch_unmap(FIX_TEXT_POKE0);
131         spin_unlock_irqrestore(&patch_lock, flags);
132
133         return ret;
134 }
135
136 int __kprobes aarch64_insn_write(void *addr, u32 insn)
137 {
138         insn = cpu_to_le32(insn);
139         return __aarch64_insn_write(addr, insn);
140 }
141
142 static bool __kprobes __aarch64_insn_hotpatch_safe(u32 insn)
143 {
144         if (aarch64_get_insn_class(insn) != AARCH64_INSN_CLS_BR_SYS)
145                 return false;
146
147         return  aarch64_insn_is_b(insn) ||
148                 aarch64_insn_is_bl(insn) ||
149                 aarch64_insn_is_svc(insn) ||
150                 aarch64_insn_is_hvc(insn) ||
151                 aarch64_insn_is_smc(insn) ||
152                 aarch64_insn_is_brk(insn) ||
153                 aarch64_insn_is_nop(insn);
154 }
155
156 /*
157  * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
158  * Section B2.6.5 "Concurrent modification and execution of instructions":
159  * Concurrent modification and execution of instructions can lead to the
160  * resulting instruction performing any behavior that can be achieved by
161  * executing any sequence of instructions that can be executed from the
162  * same Exception level, except where the instruction before modification
163  * and the instruction after modification is a B, BL, NOP, BKPT, SVC, HVC,
164  * or SMC instruction.
165  */
166 bool __kprobes aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn)
167 {
168         return __aarch64_insn_hotpatch_safe(old_insn) &&
169                __aarch64_insn_hotpatch_safe(new_insn);
170 }
171
172 int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn)
173 {
174         u32 *tp = addr;
175         int ret;
176
177         /* A64 instructions must be word aligned */
178         if ((uintptr_t)tp & 0x3)
179                 return -EINVAL;
180
181         ret = aarch64_insn_write(tp, insn);
182         if (ret == 0)
183                 flush_icache_range((uintptr_t)tp,
184                                    (uintptr_t)tp + AARCH64_INSN_SIZE);
185
186         return ret;
187 }
188
189 struct aarch64_insn_patch {
190         void            **text_addrs;
191         u32             *new_insns;
192         int             insn_cnt;
193         atomic_t        cpu_count;
194 };
195
196 static int __kprobes aarch64_insn_patch_text_cb(void *arg)
197 {
198         int i, ret = 0;
199         struct aarch64_insn_patch *pp = arg;
200
201         /* The first CPU becomes master */
202         if (atomic_inc_return(&pp->cpu_count) == 1) {
203                 for (i = 0; ret == 0 && i < pp->insn_cnt; i++)
204                         ret = aarch64_insn_patch_text_nosync(pp->text_addrs[i],
205                                                              pp->new_insns[i]);
206                 /*
207                  * aarch64_insn_patch_text_nosync() calls flush_icache_range(),
208                  * which ends with "dsb; isb" pair guaranteeing global
209                  * visibility.
210                  */
211                 /* Notify other processors with an additional increment. */
212                 atomic_inc(&pp->cpu_count);
213         } else {
214                 while (atomic_read(&pp->cpu_count) <= num_online_cpus())
215                         cpu_relax();
216                 isb();
217         }
218
219         return ret;
220 }
221
222 int __kprobes aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt)
223 {
224         struct aarch64_insn_patch patch = {
225                 .text_addrs = addrs,
226                 .new_insns = insns,
227                 .insn_cnt = cnt,
228                 .cpu_count = ATOMIC_INIT(0),
229         };
230
231         if (cnt <= 0)
232                 return -EINVAL;
233
234         return stop_machine(aarch64_insn_patch_text_cb, &patch,
235                             cpu_online_mask);
236 }
237
238 int __kprobes aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt)
239 {
240         int ret;
241         u32 insn;
242
243         /* Unsafe to patch multiple instructions without synchronizaiton */
244         if (cnt == 1) {
245                 ret = aarch64_insn_read(addrs[0], &insn);
246                 if (ret)
247                         return ret;
248
249                 if (aarch64_insn_hotpatch_safe(insn, insns[0])) {
250                         /*
251                          * ARMv8 architecture doesn't guarantee all CPUs see
252                          * the new instruction after returning from function
253                          * aarch64_insn_patch_text_nosync(). So send IPIs to
254                          * all other CPUs to achieve instruction
255                          * synchronization.
256                          */
257                         ret = aarch64_insn_patch_text_nosync(addrs[0], insns[0]);
258                         kick_all_cpus_sync();
259                         return ret;
260                 }
261         }
262
263         return aarch64_insn_patch_text_sync(addrs, insns, cnt);
264 }
265
266 u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
267                                   u32 insn, u64 imm)
268 {
269         u32 immlo, immhi, lomask, himask, mask;
270         int shift;
271
272         switch (type) {
273         case AARCH64_INSN_IMM_ADR:
274                 lomask = 0x3;
275                 himask = 0x7ffff;
276                 immlo = imm & lomask;
277                 imm >>= 2;
278                 immhi = imm & himask;
279                 imm = (immlo << 24) | (immhi);
280                 mask = (lomask << 24) | (himask);
281                 shift = 5;
282                 break;
283         case AARCH64_INSN_IMM_26:
284                 mask = BIT(26) - 1;
285                 shift = 0;
286                 break;
287         case AARCH64_INSN_IMM_19:
288                 mask = BIT(19) - 1;
289                 shift = 5;
290                 break;
291         case AARCH64_INSN_IMM_16:
292                 mask = BIT(16) - 1;
293                 shift = 5;
294                 break;
295         case AARCH64_INSN_IMM_14:
296                 mask = BIT(14) - 1;
297                 shift = 5;
298                 break;
299         case AARCH64_INSN_IMM_12:
300                 mask = BIT(12) - 1;
301                 shift = 10;
302                 break;
303         case AARCH64_INSN_IMM_9:
304                 mask = BIT(9) - 1;
305                 shift = 12;
306                 break;
307         case AARCH64_INSN_IMM_7:
308                 mask = BIT(7) - 1;
309                 shift = 15;
310                 break;
311         case AARCH64_INSN_IMM_6:
312         case AARCH64_INSN_IMM_S:
313                 mask = BIT(6) - 1;
314                 shift = 10;
315                 break;
316         case AARCH64_INSN_IMM_R:
317                 mask = BIT(6) - 1;
318                 shift = 16;
319                 break;
320         default:
321                 pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n",
322                         type);
323                 return 0;
324         }
325
326         /* Update the immediate field. */
327         insn &= ~(mask << shift);
328         insn |= (imm & mask) << shift;
329
330         return insn;
331 }
332
333 static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
334                                         u32 insn,
335                                         enum aarch64_insn_register reg)
336 {
337         int shift;
338
339         if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
340                 pr_err("%s: unknown register encoding %d\n", __func__, reg);
341                 return 0;
342         }
343
344         switch (type) {
345         case AARCH64_INSN_REGTYPE_RT:
346         case AARCH64_INSN_REGTYPE_RD:
347                 shift = 0;
348                 break;
349         case AARCH64_INSN_REGTYPE_RN:
350                 shift = 5;
351                 break;
352         case AARCH64_INSN_REGTYPE_RT2:
353         case AARCH64_INSN_REGTYPE_RA:
354                 shift = 10;
355                 break;
356         case AARCH64_INSN_REGTYPE_RM:
357                 shift = 16;
358                 break;
359         default:
360                 pr_err("%s: unknown register type encoding %d\n", __func__,
361                        type);
362                 return 0;
363         }
364
365         insn &= ~(GENMASK(4, 0) << shift);
366         insn |= reg << shift;
367
368         return insn;
369 }
370
371 static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
372                                          u32 insn)
373 {
374         u32 size;
375
376         switch (type) {
377         case AARCH64_INSN_SIZE_8:
378                 size = 0;
379                 break;
380         case AARCH64_INSN_SIZE_16:
381                 size = 1;
382                 break;
383         case AARCH64_INSN_SIZE_32:
384                 size = 2;
385                 break;
386         case AARCH64_INSN_SIZE_64:
387                 size = 3;
388                 break;
389         default:
390                 pr_err("%s: unknown size encoding %d\n", __func__, type);
391                 return 0;
392         }
393
394         insn &= ~GENMASK(31, 30);
395         insn |= size << 30;
396
397         return insn;
398 }
399
400 static inline long branch_imm_common(unsigned long pc, unsigned long addr,
401                                      long range)
402 {
403         long offset;
404
405         /*
406          * PC: A 64-bit Program Counter holding the address of the current
407          * instruction. A64 instructions must be word-aligned.
408          */
409         BUG_ON((pc & 0x3) || (addr & 0x3));
410
411         offset = ((long)addr - (long)pc);
412         BUG_ON(offset < -range || offset >= range);
413
414         return offset;
415 }
416
417 u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
418                                           enum aarch64_insn_branch_type type)
419 {
420         u32 insn;
421         long offset;
422
423         /*
424          * B/BL support [-128M, 128M) offset
425          * ARM64 virtual address arrangement guarantees all kernel and module
426          * texts are within +/-128M.
427          */
428         offset = branch_imm_common(pc, addr, SZ_128M);
429
430         switch (type) {
431         case AARCH64_INSN_BRANCH_LINK:
432                 insn = aarch64_insn_get_bl_value();
433                 break;
434         case AARCH64_INSN_BRANCH_NOLINK:
435                 insn = aarch64_insn_get_b_value();
436                 break;
437         default:
438                 BUG_ON(1);
439                 return AARCH64_BREAK_FAULT;
440         }
441
442         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
443                                              offset >> 2);
444 }
445
446 u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
447                                      enum aarch64_insn_register reg,
448                                      enum aarch64_insn_variant variant,
449                                      enum aarch64_insn_branch_type type)
450 {
451         u32 insn;
452         long offset;
453
454         offset = branch_imm_common(pc, addr, SZ_1M);
455
456         switch (type) {
457         case AARCH64_INSN_BRANCH_COMP_ZERO:
458                 insn = aarch64_insn_get_cbz_value();
459                 break;
460         case AARCH64_INSN_BRANCH_COMP_NONZERO:
461                 insn = aarch64_insn_get_cbnz_value();
462                 break;
463         default:
464                 BUG_ON(1);
465                 return AARCH64_BREAK_FAULT;
466         }
467
468         switch (variant) {
469         case AARCH64_INSN_VARIANT_32BIT:
470                 break;
471         case AARCH64_INSN_VARIANT_64BIT:
472                 insn |= AARCH64_INSN_SF_BIT;
473                 break;
474         default:
475                 BUG_ON(1);
476                 return AARCH64_BREAK_FAULT;
477         }
478
479         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
480
481         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
482                                              offset >> 2);
483 }
484
485 u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
486                                      enum aarch64_insn_condition cond)
487 {
488         u32 insn;
489         long offset;
490
491         offset = branch_imm_common(pc, addr, SZ_1M);
492
493         insn = aarch64_insn_get_bcond_value();
494
495         BUG_ON(cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL);
496         insn |= cond;
497
498         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
499                                              offset >> 2);
500 }
501
502 u32 __kprobes aarch64_insn_gen_hint(enum aarch64_insn_hint_op op)
503 {
504         return aarch64_insn_get_hint_value() | op;
505 }
506
507 u32 __kprobes aarch64_insn_gen_nop(void)
508 {
509         return aarch64_insn_gen_hint(AARCH64_INSN_HINT_NOP);
510 }
511
512 u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
513                                 enum aarch64_insn_branch_type type)
514 {
515         u32 insn;
516
517         switch (type) {
518         case AARCH64_INSN_BRANCH_NOLINK:
519                 insn = aarch64_insn_get_br_value();
520                 break;
521         case AARCH64_INSN_BRANCH_LINK:
522                 insn = aarch64_insn_get_blr_value();
523                 break;
524         case AARCH64_INSN_BRANCH_RETURN:
525                 insn = aarch64_insn_get_ret_value();
526                 break;
527         default:
528                 BUG_ON(1);
529                 return AARCH64_BREAK_FAULT;
530         }
531
532         return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, reg);
533 }
534
535 u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
536                                     enum aarch64_insn_register base,
537                                     enum aarch64_insn_register offset,
538                                     enum aarch64_insn_size_type size,
539                                     enum aarch64_insn_ldst_type type)
540 {
541         u32 insn;
542
543         switch (type) {
544         case AARCH64_INSN_LDST_LOAD_REG_OFFSET:
545                 insn = aarch64_insn_get_ldr_reg_value();
546                 break;
547         case AARCH64_INSN_LDST_STORE_REG_OFFSET:
548                 insn = aarch64_insn_get_str_reg_value();
549                 break;
550         default:
551                 BUG_ON(1);
552                 return AARCH64_BREAK_FAULT;
553         }
554
555         insn = aarch64_insn_encode_ldst_size(size, insn);
556
557         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
558
559         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
560                                             base);
561
562         return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
563                                             offset);
564 }
565
566 u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
567                                      enum aarch64_insn_register reg2,
568                                      enum aarch64_insn_register base,
569                                      int offset,
570                                      enum aarch64_insn_variant variant,
571                                      enum aarch64_insn_ldst_type type)
572 {
573         u32 insn;
574         int shift;
575
576         switch (type) {
577         case AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX:
578                 insn = aarch64_insn_get_ldp_pre_value();
579                 break;
580         case AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX:
581                 insn = aarch64_insn_get_stp_pre_value();
582                 break;
583         case AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX:
584                 insn = aarch64_insn_get_ldp_post_value();
585                 break;
586         case AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX:
587                 insn = aarch64_insn_get_stp_post_value();
588                 break;
589         default:
590                 BUG_ON(1);
591                 return AARCH64_BREAK_FAULT;
592         }
593
594         switch (variant) {
595         case AARCH64_INSN_VARIANT_32BIT:
596                 /* offset must be multiples of 4 in the range [-256, 252] */
597                 BUG_ON(offset & 0x3);
598                 BUG_ON(offset < -256 || offset > 252);
599                 shift = 2;
600                 break;
601         case AARCH64_INSN_VARIANT_64BIT:
602                 /* offset must be multiples of 8 in the range [-512, 504] */
603                 BUG_ON(offset & 0x7);
604                 BUG_ON(offset < -512 || offset > 504);
605                 shift = 3;
606                 insn |= AARCH64_INSN_SF_BIT;
607                 break;
608         default:
609                 BUG_ON(1);
610                 return AARCH64_BREAK_FAULT;
611         }
612
613         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
614                                             reg1);
615
616         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
617                                             reg2);
618
619         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
620                                             base);
621
622         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_7, insn,
623                                              offset >> shift);
624 }
625
626 u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
627                                  enum aarch64_insn_register src,
628                                  int imm, enum aarch64_insn_variant variant,
629                                  enum aarch64_insn_adsb_type type)
630 {
631         u32 insn;
632
633         switch (type) {
634         case AARCH64_INSN_ADSB_ADD:
635                 insn = aarch64_insn_get_add_imm_value();
636                 break;
637         case AARCH64_INSN_ADSB_SUB:
638                 insn = aarch64_insn_get_sub_imm_value();
639                 break;
640         case AARCH64_INSN_ADSB_ADD_SETFLAGS:
641                 insn = aarch64_insn_get_adds_imm_value();
642                 break;
643         case AARCH64_INSN_ADSB_SUB_SETFLAGS:
644                 insn = aarch64_insn_get_subs_imm_value();
645                 break;
646         default:
647                 BUG_ON(1);
648                 return AARCH64_BREAK_FAULT;
649         }
650
651         switch (variant) {
652         case AARCH64_INSN_VARIANT_32BIT:
653                 break;
654         case AARCH64_INSN_VARIANT_64BIT:
655                 insn |= AARCH64_INSN_SF_BIT;
656                 break;
657         default:
658                 BUG_ON(1);
659                 return AARCH64_BREAK_FAULT;
660         }
661
662         BUG_ON(imm & ~(SZ_4K - 1));
663
664         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
665
666         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
667
668         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
669 }
670
671 u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
672                               enum aarch64_insn_register src,
673                               int immr, int imms,
674                               enum aarch64_insn_variant variant,
675                               enum aarch64_insn_bitfield_type type)
676 {
677         u32 insn;
678         u32 mask;
679
680         switch (type) {
681         case AARCH64_INSN_BITFIELD_MOVE:
682                 insn = aarch64_insn_get_bfm_value();
683                 break;
684         case AARCH64_INSN_BITFIELD_MOVE_UNSIGNED:
685                 insn = aarch64_insn_get_ubfm_value();
686                 break;
687         case AARCH64_INSN_BITFIELD_MOVE_SIGNED:
688                 insn = aarch64_insn_get_sbfm_value();
689                 break;
690         default:
691                 BUG_ON(1);
692                 return AARCH64_BREAK_FAULT;
693         }
694
695         switch (variant) {
696         case AARCH64_INSN_VARIANT_32BIT:
697                 mask = GENMASK(4, 0);
698                 break;
699         case AARCH64_INSN_VARIANT_64BIT:
700                 insn |= AARCH64_INSN_SF_BIT | AARCH64_INSN_N_BIT;
701                 mask = GENMASK(5, 0);
702                 break;
703         default:
704                 BUG_ON(1);
705                 return AARCH64_BREAK_FAULT;
706         }
707
708         BUG_ON(immr & ~mask);
709         BUG_ON(imms & ~mask);
710
711         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
712
713         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
714
715         insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
716
717         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
718 }
719
720 u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
721                               int imm, int shift,
722                               enum aarch64_insn_variant variant,
723                               enum aarch64_insn_movewide_type type)
724 {
725         u32 insn;
726
727         switch (type) {
728         case AARCH64_INSN_MOVEWIDE_ZERO:
729                 insn = aarch64_insn_get_movz_value();
730                 break;
731         case AARCH64_INSN_MOVEWIDE_KEEP:
732                 insn = aarch64_insn_get_movk_value();
733                 break;
734         case AARCH64_INSN_MOVEWIDE_INVERSE:
735                 insn = aarch64_insn_get_movn_value();
736                 break;
737         default:
738                 BUG_ON(1);
739                 return AARCH64_BREAK_FAULT;
740         }
741
742         BUG_ON(imm & ~(SZ_64K - 1));
743
744         switch (variant) {
745         case AARCH64_INSN_VARIANT_32BIT:
746                 BUG_ON(shift != 0 && shift != 16);
747                 break;
748         case AARCH64_INSN_VARIANT_64BIT:
749                 insn |= AARCH64_INSN_SF_BIT;
750                 BUG_ON(shift != 0 && shift != 16 && shift != 32 &&
751                        shift != 48);
752                 break;
753         default:
754                 BUG_ON(1);
755                 return AARCH64_BREAK_FAULT;
756         }
757
758         insn |= (shift >> 4) << 21;
759
760         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
761
762         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm);
763 }
764
765 u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
766                                          enum aarch64_insn_register src,
767                                          enum aarch64_insn_register reg,
768                                          int shift,
769                                          enum aarch64_insn_variant variant,
770                                          enum aarch64_insn_adsb_type type)
771 {
772         u32 insn;
773
774         switch (type) {
775         case AARCH64_INSN_ADSB_ADD:
776                 insn = aarch64_insn_get_add_value();
777                 break;
778         case AARCH64_INSN_ADSB_SUB:
779                 insn = aarch64_insn_get_sub_value();
780                 break;
781         case AARCH64_INSN_ADSB_ADD_SETFLAGS:
782                 insn = aarch64_insn_get_adds_value();
783                 break;
784         case AARCH64_INSN_ADSB_SUB_SETFLAGS:
785                 insn = aarch64_insn_get_subs_value();
786                 break;
787         default:
788                 BUG_ON(1);
789                 return AARCH64_BREAK_FAULT;
790         }
791
792         switch (variant) {
793         case AARCH64_INSN_VARIANT_32BIT:
794                 BUG_ON(shift & ~(SZ_32 - 1));
795                 break;
796         case AARCH64_INSN_VARIANT_64BIT:
797                 insn |= AARCH64_INSN_SF_BIT;
798                 BUG_ON(shift & ~(SZ_64 - 1));
799                 break;
800         default:
801                 BUG_ON(1);
802                 return AARCH64_BREAK_FAULT;
803         }
804
805
806         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
807
808         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
809
810         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
811
812         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
813 }
814
815 u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
816                            enum aarch64_insn_register src,
817                            enum aarch64_insn_variant variant,
818                            enum aarch64_insn_data1_type type)
819 {
820         u32 insn;
821
822         switch (type) {
823         case AARCH64_INSN_DATA1_REVERSE_16:
824                 insn = aarch64_insn_get_rev16_value();
825                 break;
826         case AARCH64_INSN_DATA1_REVERSE_32:
827                 insn = aarch64_insn_get_rev32_value();
828                 break;
829         case AARCH64_INSN_DATA1_REVERSE_64:
830                 BUG_ON(variant != AARCH64_INSN_VARIANT_64BIT);
831                 insn = aarch64_insn_get_rev64_value();
832                 break;
833         default:
834                 BUG_ON(1);
835                 return AARCH64_BREAK_FAULT;
836         }
837
838         switch (variant) {
839         case AARCH64_INSN_VARIANT_32BIT:
840                 break;
841         case AARCH64_INSN_VARIANT_64BIT:
842                 insn |= AARCH64_INSN_SF_BIT;
843                 break;
844         default:
845                 BUG_ON(1);
846                 return AARCH64_BREAK_FAULT;
847         }
848
849         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
850
851         return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
852 }
853
854 u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
855                            enum aarch64_insn_register src,
856                            enum aarch64_insn_register reg,
857                            enum aarch64_insn_variant variant,
858                            enum aarch64_insn_data2_type type)
859 {
860         u32 insn;
861
862         switch (type) {
863         case AARCH64_INSN_DATA2_UDIV:
864                 insn = aarch64_insn_get_udiv_value();
865                 break;
866         case AARCH64_INSN_DATA2_SDIV:
867                 insn = aarch64_insn_get_sdiv_value();
868                 break;
869         case AARCH64_INSN_DATA2_LSLV:
870                 insn = aarch64_insn_get_lslv_value();
871                 break;
872         case AARCH64_INSN_DATA2_LSRV:
873                 insn = aarch64_insn_get_lsrv_value();
874                 break;
875         case AARCH64_INSN_DATA2_ASRV:
876                 insn = aarch64_insn_get_asrv_value();
877                 break;
878         case AARCH64_INSN_DATA2_RORV:
879                 insn = aarch64_insn_get_rorv_value();
880                 break;
881         default:
882                 BUG_ON(1);
883                 return AARCH64_BREAK_FAULT;
884         }
885
886         switch (variant) {
887         case AARCH64_INSN_VARIANT_32BIT:
888                 break;
889         case AARCH64_INSN_VARIANT_64BIT:
890                 insn |= AARCH64_INSN_SF_BIT;
891                 break;
892         default:
893                 BUG_ON(1);
894                 return AARCH64_BREAK_FAULT;
895         }
896
897         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
898
899         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
900
901         return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
902 }
903
904 u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
905                            enum aarch64_insn_register src,
906                            enum aarch64_insn_register reg1,
907                            enum aarch64_insn_register reg2,
908                            enum aarch64_insn_variant variant,
909                            enum aarch64_insn_data3_type type)
910 {
911         u32 insn;
912
913         switch (type) {
914         case AARCH64_INSN_DATA3_MADD:
915                 insn = aarch64_insn_get_madd_value();
916                 break;
917         case AARCH64_INSN_DATA3_MSUB:
918                 insn = aarch64_insn_get_msub_value();
919                 break;
920         default:
921                 BUG_ON(1);
922                 return AARCH64_BREAK_FAULT;
923         }
924
925         switch (variant) {
926         case AARCH64_INSN_VARIANT_32BIT:
927                 break;
928         case AARCH64_INSN_VARIANT_64BIT:
929                 insn |= AARCH64_INSN_SF_BIT;
930                 break;
931         default:
932                 BUG_ON(1);
933                 return AARCH64_BREAK_FAULT;
934         }
935
936         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
937
938         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RA, insn, src);
939
940         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
941                                             reg1);
942
943         return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
944                                             reg2);
945 }
946
947 u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
948                                          enum aarch64_insn_register src,
949                                          enum aarch64_insn_register reg,
950                                          int shift,
951                                          enum aarch64_insn_variant variant,
952                                          enum aarch64_insn_logic_type type)
953 {
954         u32 insn;
955
956         switch (type) {
957         case AARCH64_INSN_LOGIC_AND:
958                 insn = aarch64_insn_get_and_value();
959                 break;
960         case AARCH64_INSN_LOGIC_BIC:
961                 insn = aarch64_insn_get_bic_value();
962                 break;
963         case AARCH64_INSN_LOGIC_ORR:
964                 insn = aarch64_insn_get_orr_value();
965                 break;
966         case AARCH64_INSN_LOGIC_ORN:
967                 insn = aarch64_insn_get_orn_value();
968                 break;
969         case AARCH64_INSN_LOGIC_EOR:
970                 insn = aarch64_insn_get_eor_value();
971                 break;
972         case AARCH64_INSN_LOGIC_EON:
973                 insn = aarch64_insn_get_eon_value();
974                 break;
975         case AARCH64_INSN_LOGIC_AND_SETFLAGS:
976                 insn = aarch64_insn_get_ands_value();
977                 break;
978         case AARCH64_INSN_LOGIC_BIC_SETFLAGS:
979                 insn = aarch64_insn_get_bics_value();
980                 break;
981         default:
982                 BUG_ON(1);
983                 return AARCH64_BREAK_FAULT;
984         }
985
986         switch (variant) {
987         case AARCH64_INSN_VARIANT_32BIT:
988                 BUG_ON(shift & ~(SZ_32 - 1));
989                 break;
990         case AARCH64_INSN_VARIANT_64BIT:
991                 insn |= AARCH64_INSN_SF_BIT;
992                 BUG_ON(shift & ~(SZ_64 - 1));
993                 break;
994         default:
995                 BUG_ON(1);
996                 return AARCH64_BREAK_FAULT;
997         }
998
999
1000         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
1001
1002         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
1003
1004         insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
1005
1006         return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
1007 }
1008
1009 bool aarch32_insn_is_wide(u32 insn)
1010 {
1011         return insn >= 0xe800;
1012 }
1013
1014 /*
1015  * Macros/defines for extracting register numbers from instruction.
1016  */
1017 u32 aarch32_insn_extract_reg_num(u32 insn, int offset)
1018 {
1019         return (insn & (0xf << offset)) >> offset;
1020 }
1021
1022 #define OPC2_MASK       0x7
1023 #define OPC2_OFFSET     5
1024 u32 aarch32_insn_mcr_extract_opc2(u32 insn)
1025 {
1026         return (insn & (OPC2_MASK << OPC2_OFFSET)) >> OPC2_OFFSET;
1027 }
1028
1029 #define CRM_MASK        0xf
1030 u32 aarch32_insn_mcr_extract_crm(u32 insn)
1031 {
1032         return insn & CRM_MASK;
1033 }