insn.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2013 Huawei Ltd.
  4. * Author: Jiang Liu <liuj97@gmail.com>
  5. *
  6. * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
  7. */
  8. #include <linux/bitfield.h>
  9. #include <linux/bitops.h>
  10. #include <linux/bug.h>
  11. #include <linux/printk.h>
  12. #include <linux/sizes.h>
  13. #include <linux/types.h>
  14. #include <asm/debug-monitors.h>
  15. #include <asm/errno.h>
  16. #include <asm/insn.h>
  17. #include <asm/kprobes.h>
  18. #define AARCH64_INSN_SF_BIT BIT(31)
  19. #define AARCH64_INSN_N_BIT BIT(22)
  20. #define AARCH64_INSN_LSL_12 BIT(22)
  21. static int __kprobes aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type type,
  22. u32 *maskp, int *shiftp)
  23. {
  24. u32 mask;
  25. int shift;
  26. switch (type) {
  27. case AARCH64_INSN_IMM_26:
  28. mask = BIT(26) - 1;
  29. shift = 0;
  30. break;
  31. case AARCH64_INSN_IMM_19:
  32. mask = BIT(19) - 1;
  33. shift = 5;
  34. break;
  35. case AARCH64_INSN_IMM_16:
  36. mask = BIT(16) - 1;
  37. shift = 5;
  38. break;
  39. case AARCH64_INSN_IMM_14:
  40. mask = BIT(14) - 1;
  41. shift = 5;
  42. break;
  43. case AARCH64_INSN_IMM_12:
  44. mask = BIT(12) - 1;
  45. shift = 10;
  46. break;
  47. case AARCH64_INSN_IMM_9:
  48. mask = BIT(9) - 1;
  49. shift = 12;
  50. break;
  51. case AARCH64_INSN_IMM_7:
  52. mask = BIT(7) - 1;
  53. shift = 15;
  54. break;
  55. case AARCH64_INSN_IMM_6:
  56. case AARCH64_INSN_IMM_S:
  57. mask = BIT(6) - 1;
  58. shift = 10;
  59. break;
  60. case AARCH64_INSN_IMM_R:
  61. mask = BIT(6) - 1;
  62. shift = 16;
  63. break;
  64. case AARCH64_INSN_IMM_N:
  65. mask = 1;
  66. shift = 22;
  67. break;
  68. default:
  69. return -EINVAL;
  70. }
  71. *maskp = mask;
  72. *shiftp = shift;
  73. return 0;
  74. }
  75. #define ADR_IMM_HILOSPLIT 2
  76. #define ADR_IMM_SIZE SZ_2M
  77. #define ADR_IMM_LOMASK ((1 << ADR_IMM_HILOSPLIT) - 1)
  78. #define ADR_IMM_HIMASK ((ADR_IMM_SIZE >> ADR_IMM_HILOSPLIT) - 1)
  79. #define ADR_IMM_LOSHIFT 29
  80. #define ADR_IMM_HISHIFT 5
  81. u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn)
  82. {
  83. u32 immlo, immhi, mask;
  84. int shift;
  85. switch (type) {
  86. case AARCH64_INSN_IMM_ADR:
  87. shift = 0;
  88. immlo = (insn >> ADR_IMM_LOSHIFT) & ADR_IMM_LOMASK;
  89. immhi = (insn >> ADR_IMM_HISHIFT) & ADR_IMM_HIMASK;
  90. insn = (immhi << ADR_IMM_HILOSPLIT) | immlo;
  91. mask = ADR_IMM_SIZE - 1;
  92. break;
  93. default:
  94. if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
  95. pr_err("%s: unknown immediate encoding %d\n", __func__,
  96. type);
  97. return 0;
  98. }
  99. }
  100. return (insn >> shift) & mask;
  101. }
  102. u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
  103. u32 insn, u64 imm)
  104. {
  105. u32 immlo, immhi, mask;
  106. int shift;
  107. if (insn == AARCH64_BREAK_FAULT)
  108. return AARCH64_BREAK_FAULT;
  109. switch (type) {
  110. case AARCH64_INSN_IMM_ADR:
  111. shift = 0;
  112. immlo = (imm & ADR_IMM_LOMASK) << ADR_IMM_LOSHIFT;
  113. imm >>= ADR_IMM_HILOSPLIT;
  114. immhi = (imm & ADR_IMM_HIMASK) << ADR_IMM_HISHIFT;
  115. imm = immlo | immhi;
  116. mask = ((ADR_IMM_LOMASK << ADR_IMM_LOSHIFT) |
  117. (ADR_IMM_HIMASK << ADR_IMM_HISHIFT));
  118. break;
  119. default:
  120. if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
  121. pr_err("%s: unknown immediate encoding %d\n", __func__,
  122. type);
  123. return AARCH64_BREAK_FAULT;
  124. }
  125. }
  126. /* Update the immediate field. */
  127. insn &= ~(mask << shift);
  128. insn |= (imm & mask) << shift;
  129. return insn;
  130. }
  131. u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type,
  132. u32 insn)
  133. {
  134. int shift;
  135. switch (type) {
  136. case AARCH64_INSN_REGTYPE_RT:
  137. case AARCH64_INSN_REGTYPE_RD:
  138. shift = 0;
  139. break;
  140. case AARCH64_INSN_REGTYPE_RN:
  141. shift = 5;
  142. break;
  143. case AARCH64_INSN_REGTYPE_RT2:
  144. case AARCH64_INSN_REGTYPE_RA:
  145. shift = 10;
  146. break;
  147. case AARCH64_INSN_REGTYPE_RM:
  148. shift = 16;
  149. break;
  150. default:
  151. pr_err("%s: unknown register type encoding %d\n", __func__,
  152. type);
  153. return 0;
  154. }
  155. return (insn >> shift) & GENMASK(4, 0);
  156. }
  157. static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
  158. u32 insn,
  159. enum aarch64_insn_register reg)
  160. {
  161. int shift;
  162. if (insn == AARCH64_BREAK_FAULT)
  163. return AARCH64_BREAK_FAULT;
  164. if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
  165. pr_err("%s: unknown register encoding %d\n", __func__, reg);
  166. return AARCH64_BREAK_FAULT;
  167. }
  168. switch (type) {
  169. case AARCH64_INSN_REGTYPE_RT:
  170. case AARCH64_INSN_REGTYPE_RD:
  171. shift = 0;
  172. break;
  173. case AARCH64_INSN_REGTYPE_RN:
  174. shift = 5;
  175. break;
  176. case AARCH64_INSN_REGTYPE_RT2:
  177. case AARCH64_INSN_REGTYPE_RA:
  178. shift = 10;
  179. break;
  180. case AARCH64_INSN_REGTYPE_RM:
  181. case AARCH64_INSN_REGTYPE_RS:
  182. shift = 16;
  183. break;
  184. default:
  185. pr_err("%s: unknown register type encoding %d\n", __func__,
  186. type);
  187. return AARCH64_BREAK_FAULT;
  188. }
  189. insn &= ~(GENMASK(4, 0) << shift);
  190. insn |= reg << shift;
  191. return insn;
  192. }
  193. static const u32 aarch64_insn_ldst_size[] = {
  194. [AARCH64_INSN_SIZE_8] = 0,
  195. [AARCH64_INSN_SIZE_16] = 1,
  196. [AARCH64_INSN_SIZE_32] = 2,
  197. [AARCH64_INSN_SIZE_64] = 3,
  198. };
  199. static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
  200. u32 insn)
  201. {
  202. u32 size;
  203. if (type < AARCH64_INSN_SIZE_8 || type > AARCH64_INSN_SIZE_64) {
  204. pr_err("%s: unknown size encoding %d\n", __func__, type);
  205. return AARCH64_BREAK_FAULT;
  206. }
  207. size = aarch64_insn_ldst_size[type];
  208. insn &= ~GENMASK(31, 30);
  209. insn |= size << 30;
  210. return insn;
  211. }
  212. static inline long label_imm_common(unsigned long pc, unsigned long addr,
  213. long range)
  214. {
  215. long offset;
  216. if ((pc & 0x3) || (addr & 0x3)) {
  217. pr_err("%s: A64 instructions must be word aligned\n", __func__);
  218. return range;
  219. }
  220. offset = ((long)addr - (long)pc);
  221. if (offset < -range || offset >= range) {
  222. pr_err("%s: offset out of range\n", __func__);
  223. return range;
  224. }
  225. return offset;
  226. }
  227. u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
  228. enum aarch64_insn_branch_type type)
  229. {
  230. u32 insn;
  231. long offset;
  232. /*
  233. * B/BL support [-128M, 128M) offset
  234. * ARM64 virtual address arrangement guarantees all kernel and module
  235. * texts are within +/-128M.
  236. */
  237. offset = label_imm_common(pc, addr, SZ_128M);
  238. if (offset >= SZ_128M)
  239. return AARCH64_BREAK_FAULT;
  240. switch (type) {
  241. case AARCH64_INSN_BRANCH_LINK:
  242. insn = aarch64_insn_get_bl_value();
  243. break;
  244. case AARCH64_INSN_BRANCH_NOLINK:
  245. insn = aarch64_insn_get_b_value();
  246. break;
  247. default:
  248. pr_err("%s: unknown branch encoding %d\n", __func__, type);
  249. return AARCH64_BREAK_FAULT;
  250. }
  251. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
  252. offset >> 2);
  253. }
  254. u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
  255. enum aarch64_insn_register reg,
  256. enum aarch64_insn_variant variant,
  257. enum aarch64_insn_branch_type type)
  258. {
  259. u32 insn;
  260. long offset;
  261. offset = label_imm_common(pc, addr, SZ_1M);
  262. if (offset >= SZ_1M)
  263. return AARCH64_BREAK_FAULT;
  264. switch (type) {
  265. case AARCH64_INSN_BRANCH_COMP_ZERO:
  266. insn = aarch64_insn_get_cbz_value();
  267. break;
  268. case AARCH64_INSN_BRANCH_COMP_NONZERO:
  269. insn = aarch64_insn_get_cbnz_value();
  270. break;
  271. default:
  272. pr_err("%s: unknown branch encoding %d\n", __func__, type);
  273. return AARCH64_BREAK_FAULT;
  274. }
  275. switch (variant) {
  276. case AARCH64_INSN_VARIANT_32BIT:
  277. break;
  278. case AARCH64_INSN_VARIANT_64BIT:
  279. insn |= AARCH64_INSN_SF_BIT;
  280. break;
  281. default:
  282. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  283. return AARCH64_BREAK_FAULT;
  284. }
  285. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
  286. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
  287. offset >> 2);
  288. }
  289. u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
  290. enum aarch64_insn_condition cond)
  291. {
  292. u32 insn;
  293. long offset;
  294. offset = label_imm_common(pc, addr, SZ_1M);
  295. insn = aarch64_insn_get_bcond_value();
  296. if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) {
  297. pr_err("%s: unknown condition encoding %d\n", __func__, cond);
  298. return AARCH64_BREAK_FAULT;
  299. }
  300. insn |= cond;
  301. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
  302. offset >> 2);
  303. }
  304. u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
  305. enum aarch64_insn_branch_type type)
  306. {
  307. u32 insn;
  308. switch (type) {
  309. case AARCH64_INSN_BRANCH_NOLINK:
  310. insn = aarch64_insn_get_br_value();
  311. break;
  312. case AARCH64_INSN_BRANCH_LINK:
  313. insn = aarch64_insn_get_blr_value();
  314. break;
  315. case AARCH64_INSN_BRANCH_RETURN:
  316. insn = aarch64_insn_get_ret_value();
  317. break;
  318. default:
  319. pr_err("%s: unknown branch encoding %d\n", __func__, type);
  320. return AARCH64_BREAK_FAULT;
  321. }
  322. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, reg);
  323. }
  324. u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
  325. enum aarch64_insn_register base,
  326. enum aarch64_insn_register offset,
  327. enum aarch64_insn_size_type size,
  328. enum aarch64_insn_ldst_type type)
  329. {
  330. u32 insn;
  331. switch (type) {
  332. case AARCH64_INSN_LDST_LOAD_REG_OFFSET:
  333. insn = aarch64_insn_get_ldr_reg_value();
  334. break;
  335. case AARCH64_INSN_LDST_SIGNED_LOAD_REG_OFFSET:
  336. insn = aarch64_insn_get_signed_ldr_reg_value();
  337. break;
  338. case AARCH64_INSN_LDST_STORE_REG_OFFSET:
  339. insn = aarch64_insn_get_str_reg_value();
  340. break;
  341. default:
  342. pr_err("%s: unknown load/store encoding %d\n", __func__, type);
  343. return AARCH64_BREAK_FAULT;
  344. }
  345. insn = aarch64_insn_encode_ldst_size(size, insn);
  346. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
  347. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  348. base);
  349. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
  350. offset);
  351. }
  352. u32 aarch64_insn_gen_load_store_imm(enum aarch64_insn_register reg,
  353. enum aarch64_insn_register base,
  354. unsigned int imm,
  355. enum aarch64_insn_size_type size,
  356. enum aarch64_insn_ldst_type type)
  357. {
  358. u32 insn;
  359. u32 shift;
  360. if (size < AARCH64_INSN_SIZE_8 || size > AARCH64_INSN_SIZE_64) {
  361. pr_err("%s: unknown size encoding %d\n", __func__, type);
  362. return AARCH64_BREAK_FAULT;
  363. }
  364. shift = aarch64_insn_ldst_size[size];
  365. if (imm & ~(BIT(12 + shift) - BIT(shift))) {
  366. pr_err("%s: invalid imm: %d\n", __func__, imm);
  367. return AARCH64_BREAK_FAULT;
  368. }
  369. imm >>= shift;
  370. switch (type) {
  371. case AARCH64_INSN_LDST_LOAD_IMM_OFFSET:
  372. insn = aarch64_insn_get_ldr_imm_value();
  373. break;
  374. case AARCH64_INSN_LDST_SIGNED_LOAD_IMM_OFFSET:
  375. insn = aarch64_insn_get_signed_load_imm_value();
  376. break;
  377. case AARCH64_INSN_LDST_STORE_IMM_OFFSET:
  378. insn = aarch64_insn_get_str_imm_value();
  379. break;
  380. default:
  381. pr_err("%s: unknown load/store encoding %d\n", __func__, type);
  382. return AARCH64_BREAK_FAULT;
  383. }
  384. insn = aarch64_insn_encode_ldst_size(size, insn);
  385. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
  386. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  387. base);
  388. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
  389. }
  390. u32 aarch64_insn_gen_load_literal(unsigned long pc, unsigned long addr,
  391. enum aarch64_insn_register reg,
  392. bool is64bit)
  393. {
  394. u32 insn;
  395. long offset;
  396. offset = label_imm_common(pc, addr, SZ_1M);
  397. if (offset >= SZ_1M)
  398. return AARCH64_BREAK_FAULT;
  399. insn = aarch64_insn_get_ldr_lit_value();
  400. if (is64bit)
  401. insn |= BIT(30);
  402. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
  403. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
  404. offset >> 2);
  405. }
  406. u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
  407. enum aarch64_insn_register reg2,
  408. enum aarch64_insn_register base,
  409. int offset,
  410. enum aarch64_insn_variant variant,
  411. enum aarch64_insn_ldst_type type)
  412. {
  413. u32 insn;
  414. int shift;
  415. switch (type) {
  416. case AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX:
  417. insn = aarch64_insn_get_ldp_pre_value();
  418. break;
  419. case AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX:
  420. insn = aarch64_insn_get_stp_pre_value();
  421. break;
  422. case AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX:
  423. insn = aarch64_insn_get_ldp_post_value();
  424. break;
  425. case AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX:
  426. insn = aarch64_insn_get_stp_post_value();
  427. break;
  428. default:
  429. pr_err("%s: unknown load/store encoding %d\n", __func__, type);
  430. return AARCH64_BREAK_FAULT;
  431. }
  432. switch (variant) {
  433. case AARCH64_INSN_VARIANT_32BIT:
  434. if ((offset & 0x3) || (offset < -256) || (offset > 252)) {
  435. pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n",
  436. __func__, offset);
  437. return AARCH64_BREAK_FAULT;
  438. }
  439. shift = 2;
  440. break;
  441. case AARCH64_INSN_VARIANT_64BIT:
  442. if ((offset & 0x7) || (offset < -512) || (offset > 504)) {
  443. pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n",
  444. __func__, offset);
  445. return AARCH64_BREAK_FAULT;
  446. }
  447. shift = 3;
  448. insn |= AARCH64_INSN_SF_BIT;
  449. break;
  450. default:
  451. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  452. return AARCH64_BREAK_FAULT;
  453. }
  454. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  455. reg1);
  456. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
  457. reg2);
  458. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  459. base);
  460. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_7, insn,
  461. offset >> shift);
  462. }
  463. u32 aarch64_insn_gen_load_acq_store_rel(enum aarch64_insn_register reg,
  464. enum aarch64_insn_register base,
  465. enum aarch64_insn_size_type size,
  466. enum aarch64_insn_ldst_type type)
  467. {
  468. u32 insn;
  469. switch (type) {
  470. case AARCH64_INSN_LDST_LOAD_ACQ:
  471. insn = aarch64_insn_get_load_acq_value();
  472. break;
  473. case AARCH64_INSN_LDST_STORE_REL:
  474. insn = aarch64_insn_get_store_rel_value();
  475. break;
  476. default:
  477. pr_err("%s: unknown load-acquire/store-release encoding %d\n",
  478. __func__, type);
  479. return AARCH64_BREAK_FAULT;
  480. }
  481. insn = aarch64_insn_encode_ldst_size(size, insn);
  482. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  483. reg);
  484. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  485. base);
  486. }
  487. u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
  488. enum aarch64_insn_register base,
  489. enum aarch64_insn_register state,
  490. enum aarch64_insn_size_type size,
  491. enum aarch64_insn_ldst_type type)
  492. {
  493. u32 insn;
  494. switch (type) {
  495. case AARCH64_INSN_LDST_LOAD_EX:
  496. case AARCH64_INSN_LDST_LOAD_ACQ_EX:
  497. insn = aarch64_insn_get_load_ex_value();
  498. if (type == AARCH64_INSN_LDST_LOAD_ACQ_EX)
  499. insn |= BIT(15);
  500. break;
  501. case AARCH64_INSN_LDST_STORE_EX:
  502. case AARCH64_INSN_LDST_STORE_REL_EX:
  503. insn = aarch64_insn_get_store_ex_value();
  504. if (type == AARCH64_INSN_LDST_STORE_REL_EX)
  505. insn |= BIT(15);
  506. break;
  507. default:
  508. pr_err("%s: unknown load/store exclusive encoding %d\n", __func__, type);
  509. return AARCH64_BREAK_FAULT;
  510. }
  511. insn = aarch64_insn_encode_ldst_size(size, insn);
  512. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  513. reg);
  514. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  515. base);
  516. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
  517. AARCH64_INSN_REG_ZR);
  518. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
  519. state);
  520. }
  521. static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
  522. u32 insn)
  523. {
  524. u32 order;
  525. switch (type) {
  526. case AARCH64_INSN_MEM_ORDER_NONE:
  527. order = 0;
  528. break;
  529. case AARCH64_INSN_MEM_ORDER_ACQ:
  530. order = 2;
  531. break;
  532. case AARCH64_INSN_MEM_ORDER_REL:
  533. order = 1;
  534. break;
  535. case AARCH64_INSN_MEM_ORDER_ACQREL:
  536. order = 3;
  537. break;
  538. default:
  539. pr_err("%s: unknown mem order %d\n", __func__, type);
  540. return AARCH64_BREAK_FAULT;
  541. }
  542. insn &= ~GENMASK(23, 22);
  543. insn |= order << 22;
  544. return insn;
  545. }
  546. u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
  547. enum aarch64_insn_register address,
  548. enum aarch64_insn_register value,
  549. enum aarch64_insn_size_type size,
  550. enum aarch64_insn_mem_atomic_op op,
  551. enum aarch64_insn_mem_order_type order)
  552. {
  553. u32 insn;
  554. switch (op) {
  555. case AARCH64_INSN_MEM_ATOMIC_ADD:
  556. insn = aarch64_insn_get_ldadd_value();
  557. break;
  558. case AARCH64_INSN_MEM_ATOMIC_CLR:
  559. insn = aarch64_insn_get_ldclr_value();
  560. break;
  561. case AARCH64_INSN_MEM_ATOMIC_EOR:
  562. insn = aarch64_insn_get_ldeor_value();
  563. break;
  564. case AARCH64_INSN_MEM_ATOMIC_SET:
  565. insn = aarch64_insn_get_ldset_value();
  566. break;
  567. case AARCH64_INSN_MEM_ATOMIC_SWP:
  568. insn = aarch64_insn_get_swp_value();
  569. break;
  570. default:
  571. pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
  572. return AARCH64_BREAK_FAULT;
  573. }
  574. switch (size) {
  575. case AARCH64_INSN_SIZE_32:
  576. case AARCH64_INSN_SIZE_64:
  577. break;
  578. default:
  579. pr_err("%s: unimplemented size encoding %d\n", __func__, size);
  580. return AARCH64_BREAK_FAULT;
  581. }
  582. insn = aarch64_insn_encode_ldst_size(size, insn);
  583. insn = aarch64_insn_encode_ldst_order(order, insn);
  584. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  585. result);
  586. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  587. address);
  588. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
  589. value);
  590. }
  591. static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
  592. u32 insn)
  593. {
  594. u32 order;
  595. switch (type) {
  596. case AARCH64_INSN_MEM_ORDER_NONE:
  597. order = 0;
  598. break;
  599. case AARCH64_INSN_MEM_ORDER_ACQ:
  600. order = BIT(22);
  601. break;
  602. case AARCH64_INSN_MEM_ORDER_REL:
  603. order = BIT(15);
  604. break;
  605. case AARCH64_INSN_MEM_ORDER_ACQREL:
  606. order = BIT(15) | BIT(22);
  607. break;
  608. default:
  609. pr_err("%s: unknown mem order %d\n", __func__, type);
  610. return AARCH64_BREAK_FAULT;
  611. }
  612. insn &= ~(BIT(15) | BIT(22));
  613. insn |= order;
  614. return insn;
  615. }
  616. u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
  617. enum aarch64_insn_register address,
  618. enum aarch64_insn_register value,
  619. enum aarch64_insn_size_type size,
  620. enum aarch64_insn_mem_order_type order)
  621. {
  622. u32 insn;
  623. switch (size) {
  624. case AARCH64_INSN_SIZE_32:
  625. case AARCH64_INSN_SIZE_64:
  626. break;
  627. default:
  628. pr_err("%s: unimplemented size encoding %d\n", __func__, size);
  629. return AARCH64_BREAK_FAULT;
  630. }
  631. insn = aarch64_insn_get_cas_value();
  632. insn = aarch64_insn_encode_ldst_size(size, insn);
  633. insn = aarch64_insn_encode_cas_order(order, insn);
  634. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  635. result);
  636. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  637. address);
  638. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
  639. value);
  640. }
  641. u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
  642. enum aarch64_insn_register src,
  643. int imm, enum aarch64_insn_variant variant,
  644. enum aarch64_insn_adsb_type type)
  645. {
  646. u32 insn;
  647. switch (type) {
  648. case AARCH64_INSN_ADSB_ADD:
  649. insn = aarch64_insn_get_add_imm_value();
  650. break;
  651. case AARCH64_INSN_ADSB_SUB:
  652. insn = aarch64_insn_get_sub_imm_value();
  653. break;
  654. case AARCH64_INSN_ADSB_ADD_SETFLAGS:
  655. insn = aarch64_insn_get_adds_imm_value();
  656. break;
  657. case AARCH64_INSN_ADSB_SUB_SETFLAGS:
  658. insn = aarch64_insn_get_subs_imm_value();
  659. break;
  660. default:
  661. pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
  662. return AARCH64_BREAK_FAULT;
  663. }
  664. switch (variant) {
  665. case AARCH64_INSN_VARIANT_32BIT:
  666. break;
  667. case AARCH64_INSN_VARIANT_64BIT:
  668. insn |= AARCH64_INSN_SF_BIT;
  669. break;
  670. default:
  671. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  672. return AARCH64_BREAK_FAULT;
  673. }
  674. /* We can't encode more than a 24bit value (12bit + 12bit shift) */
  675. if (imm & ~(BIT(24) - 1))
  676. goto out;
  677. /* If we have something in the top 12 bits... */
  678. if (imm & ~(SZ_4K - 1)) {
  679. /* ... and in the low 12 bits -> error */
  680. if (imm & (SZ_4K - 1))
  681. goto out;
  682. imm >>= 12;
  683. insn |= AARCH64_INSN_LSL_12;
  684. }
  685. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  686. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  687. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
  688. out:
  689. pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
  690. return AARCH64_BREAK_FAULT;
  691. }
  692. u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
  693. enum aarch64_insn_register src,
  694. int immr, int imms,
  695. enum aarch64_insn_variant variant,
  696. enum aarch64_insn_bitfield_type type)
  697. {
  698. u32 insn;
  699. u32 mask;
  700. switch (type) {
  701. case AARCH64_INSN_BITFIELD_MOVE:
  702. insn = aarch64_insn_get_bfm_value();
  703. break;
  704. case AARCH64_INSN_BITFIELD_MOVE_UNSIGNED:
  705. insn = aarch64_insn_get_ubfm_value();
  706. break;
  707. case AARCH64_INSN_BITFIELD_MOVE_SIGNED:
  708. insn = aarch64_insn_get_sbfm_value();
  709. break;
  710. default:
  711. pr_err("%s: unknown bitfield encoding %d\n", __func__, type);
  712. return AARCH64_BREAK_FAULT;
  713. }
  714. switch (variant) {
  715. case AARCH64_INSN_VARIANT_32BIT:
  716. mask = GENMASK(4, 0);
  717. break;
  718. case AARCH64_INSN_VARIANT_64BIT:
  719. insn |= AARCH64_INSN_SF_BIT | AARCH64_INSN_N_BIT;
  720. mask = GENMASK(5, 0);
  721. break;
  722. default:
  723. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  724. return AARCH64_BREAK_FAULT;
  725. }
  726. if (immr & ~mask) {
  727. pr_err("%s: invalid immr encoding %d\n", __func__, immr);
  728. return AARCH64_BREAK_FAULT;
  729. }
  730. if (imms & ~mask) {
  731. pr_err("%s: invalid imms encoding %d\n", __func__, imms);
  732. return AARCH64_BREAK_FAULT;
  733. }
  734. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  735. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  736. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
  737. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
  738. }
  739. u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
  740. int imm, int shift,
  741. enum aarch64_insn_variant variant,
  742. enum aarch64_insn_movewide_type type)
  743. {
  744. u32 insn;
  745. switch (type) {
  746. case AARCH64_INSN_MOVEWIDE_ZERO:
  747. insn = aarch64_insn_get_movz_value();
  748. break;
  749. case AARCH64_INSN_MOVEWIDE_KEEP:
  750. insn = aarch64_insn_get_movk_value();
  751. break;
  752. case AARCH64_INSN_MOVEWIDE_INVERSE:
  753. insn = aarch64_insn_get_movn_value();
  754. break;
  755. default:
  756. pr_err("%s: unknown movewide encoding %d\n", __func__, type);
  757. return AARCH64_BREAK_FAULT;
  758. }
  759. if (imm & ~(SZ_64K - 1)) {
  760. pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
  761. return AARCH64_BREAK_FAULT;
  762. }
  763. switch (variant) {
  764. case AARCH64_INSN_VARIANT_32BIT:
  765. if (shift != 0 && shift != 16) {
  766. pr_err("%s: invalid shift encoding %d\n", __func__,
  767. shift);
  768. return AARCH64_BREAK_FAULT;
  769. }
  770. break;
  771. case AARCH64_INSN_VARIANT_64BIT:
  772. insn |= AARCH64_INSN_SF_BIT;
  773. if (shift != 0 && shift != 16 && shift != 32 && shift != 48) {
  774. pr_err("%s: invalid shift encoding %d\n", __func__,
  775. shift);
  776. return AARCH64_BREAK_FAULT;
  777. }
  778. break;
  779. default:
  780. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  781. return AARCH64_BREAK_FAULT;
  782. }
  783. insn |= (shift >> 4) << 21;
  784. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  785. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm);
  786. }
  787. u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
  788. enum aarch64_insn_register src,
  789. enum aarch64_insn_register reg,
  790. int shift,
  791. enum aarch64_insn_variant variant,
  792. enum aarch64_insn_adsb_type type)
  793. {
  794. u32 insn;
  795. switch (type) {
  796. case AARCH64_INSN_ADSB_ADD:
  797. insn = aarch64_insn_get_add_value();
  798. break;
  799. case AARCH64_INSN_ADSB_SUB:
  800. insn = aarch64_insn_get_sub_value();
  801. break;
  802. case AARCH64_INSN_ADSB_ADD_SETFLAGS:
  803. insn = aarch64_insn_get_adds_value();
  804. break;
  805. case AARCH64_INSN_ADSB_SUB_SETFLAGS:
  806. insn = aarch64_insn_get_subs_value();
  807. break;
  808. default:
  809. pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
  810. return AARCH64_BREAK_FAULT;
  811. }
  812. switch (variant) {
  813. case AARCH64_INSN_VARIANT_32BIT:
  814. if (shift & ~(SZ_32 - 1)) {
  815. pr_err("%s: invalid shift encoding %d\n", __func__,
  816. shift);
  817. return AARCH64_BREAK_FAULT;
  818. }
  819. break;
  820. case AARCH64_INSN_VARIANT_64BIT:
  821. insn |= AARCH64_INSN_SF_BIT;
  822. if (shift & ~(SZ_64 - 1)) {
  823. pr_err("%s: invalid shift encoding %d\n", __func__,
  824. shift);
  825. return AARCH64_BREAK_FAULT;
  826. }
  827. break;
  828. default:
  829. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  830. return AARCH64_BREAK_FAULT;
  831. }
  832. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  833. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  834. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
  835. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
  836. }
  837. u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
  838. enum aarch64_insn_register src,
  839. enum aarch64_insn_variant variant,
  840. enum aarch64_insn_data1_type type)
  841. {
  842. u32 insn;
  843. switch (type) {
  844. case AARCH64_INSN_DATA1_REVERSE_16:
  845. insn = aarch64_insn_get_rev16_value();
  846. break;
  847. case AARCH64_INSN_DATA1_REVERSE_32:
  848. insn = aarch64_insn_get_rev32_value();
  849. break;
  850. case AARCH64_INSN_DATA1_REVERSE_64:
  851. if (variant != AARCH64_INSN_VARIANT_64BIT) {
  852. pr_err("%s: invalid variant for reverse64 %d\n",
  853. __func__, variant);
  854. return AARCH64_BREAK_FAULT;
  855. }
  856. insn = aarch64_insn_get_rev64_value();
  857. break;
  858. default:
  859. pr_err("%s: unknown data1 encoding %d\n", __func__, type);
  860. return AARCH64_BREAK_FAULT;
  861. }
  862. switch (variant) {
  863. case AARCH64_INSN_VARIANT_32BIT:
  864. break;
  865. case AARCH64_INSN_VARIANT_64BIT:
  866. insn |= AARCH64_INSN_SF_BIT;
  867. break;
  868. default:
  869. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  870. return AARCH64_BREAK_FAULT;
  871. }
  872. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  873. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  874. }
  875. u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
  876. enum aarch64_insn_register src,
  877. enum aarch64_insn_register reg,
  878. enum aarch64_insn_variant variant,
  879. enum aarch64_insn_data2_type type)
  880. {
  881. u32 insn;
  882. switch (type) {
  883. case AARCH64_INSN_DATA2_UDIV:
  884. insn = aarch64_insn_get_udiv_value();
  885. break;
  886. case AARCH64_INSN_DATA2_SDIV:
  887. insn = aarch64_insn_get_sdiv_value();
  888. break;
  889. case AARCH64_INSN_DATA2_LSLV:
  890. insn = aarch64_insn_get_lslv_value();
  891. break;
  892. case AARCH64_INSN_DATA2_LSRV:
  893. insn = aarch64_insn_get_lsrv_value();
  894. break;
  895. case AARCH64_INSN_DATA2_ASRV:
  896. insn = aarch64_insn_get_asrv_value();
  897. break;
  898. case AARCH64_INSN_DATA2_RORV:
  899. insn = aarch64_insn_get_rorv_value();
  900. break;
  901. default:
  902. pr_err("%s: unknown data2 encoding %d\n", __func__, type);
  903. return AARCH64_BREAK_FAULT;
  904. }
  905. switch (variant) {
  906. case AARCH64_INSN_VARIANT_32BIT:
  907. break;
  908. case AARCH64_INSN_VARIANT_64BIT:
  909. insn |= AARCH64_INSN_SF_BIT;
  910. break;
  911. default:
  912. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  913. return AARCH64_BREAK_FAULT;
  914. }
  915. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  916. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  917. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
  918. }
  919. u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
  920. enum aarch64_insn_register src,
  921. enum aarch64_insn_register reg1,
  922. enum aarch64_insn_register reg2,
  923. enum aarch64_insn_variant variant,
  924. enum aarch64_insn_data3_type type)
  925. {
  926. u32 insn;
  927. switch (type) {
  928. case AARCH64_INSN_DATA3_MADD:
  929. insn = aarch64_insn_get_madd_value();
  930. break;
  931. case AARCH64_INSN_DATA3_MSUB:
  932. insn = aarch64_insn_get_msub_value();
  933. break;
  934. default:
  935. pr_err("%s: unknown data3 encoding %d\n", __func__, type);
  936. return AARCH64_BREAK_FAULT;
  937. }
  938. switch (variant) {
  939. case AARCH64_INSN_VARIANT_32BIT:
  940. break;
  941. case AARCH64_INSN_VARIANT_64BIT:
  942. insn |= AARCH64_INSN_SF_BIT;
  943. break;
  944. default:
  945. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  946. return AARCH64_BREAK_FAULT;
  947. }
  948. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  949. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RA, insn, src);
  950. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  951. reg1);
  952. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
  953. reg2);
  954. }
  955. u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
  956. enum aarch64_insn_register src,
  957. enum aarch64_insn_register reg,
  958. int shift,
  959. enum aarch64_insn_variant variant,
  960. enum aarch64_insn_logic_type type)
  961. {
  962. u32 insn;
  963. switch (type) {
  964. case AARCH64_INSN_LOGIC_AND:
  965. insn = aarch64_insn_get_and_value();
  966. break;
  967. case AARCH64_INSN_LOGIC_BIC:
  968. insn = aarch64_insn_get_bic_value();
  969. break;
  970. case AARCH64_INSN_LOGIC_ORR:
  971. insn = aarch64_insn_get_orr_value();
  972. break;
  973. case AARCH64_INSN_LOGIC_ORN:
  974. insn = aarch64_insn_get_orn_value();
  975. break;
  976. case AARCH64_INSN_LOGIC_EOR:
  977. insn = aarch64_insn_get_eor_value();
  978. break;
  979. case AARCH64_INSN_LOGIC_EON:
  980. insn = aarch64_insn_get_eon_value();
  981. break;
  982. case AARCH64_INSN_LOGIC_AND_SETFLAGS:
  983. insn = aarch64_insn_get_ands_value();
  984. break;
  985. case AARCH64_INSN_LOGIC_BIC_SETFLAGS:
  986. insn = aarch64_insn_get_bics_value();
  987. break;
  988. default:
  989. pr_err("%s: unknown logical encoding %d\n", __func__, type);
  990. return AARCH64_BREAK_FAULT;
  991. }
  992. switch (variant) {
  993. case AARCH64_INSN_VARIANT_32BIT:
  994. if (shift & ~(SZ_32 - 1)) {
  995. pr_err("%s: invalid shift encoding %d\n", __func__,
  996. shift);
  997. return AARCH64_BREAK_FAULT;
  998. }
  999. break;
  1000. case AARCH64_INSN_VARIANT_64BIT:
  1001. insn |= AARCH64_INSN_SF_BIT;
  1002. if (shift & ~(SZ_64 - 1)) {
  1003. pr_err("%s: invalid shift encoding %d\n", __func__,
  1004. shift);
  1005. return AARCH64_BREAK_FAULT;
  1006. }
  1007. break;
  1008. default:
  1009. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  1010. return AARCH64_BREAK_FAULT;
  1011. }
  1012. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  1013. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  1014. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
  1015. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
  1016. }
  1017. /*
  1018. * MOV (register) is architecturally an alias of ORR (shifted register) where
  1019. * MOV <*d>, <*m> is equivalent to ORR <*d>, <*ZR>, <*m>
  1020. */
  1021. u32 aarch64_insn_gen_move_reg(enum aarch64_insn_register dst,
  1022. enum aarch64_insn_register src,
  1023. enum aarch64_insn_variant variant)
  1024. {
  1025. return aarch64_insn_gen_logical_shifted_reg(dst, AARCH64_INSN_REG_ZR,
  1026. src, 0, variant,
  1027. AARCH64_INSN_LOGIC_ORR);
  1028. }
  1029. u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr,
  1030. enum aarch64_insn_register reg,
  1031. enum aarch64_insn_adr_type type)
  1032. {
  1033. u32 insn;
  1034. s32 offset;
  1035. switch (type) {
  1036. case AARCH64_INSN_ADR_TYPE_ADR:
  1037. insn = aarch64_insn_get_adr_value();
  1038. offset = addr - pc;
  1039. break;
  1040. case AARCH64_INSN_ADR_TYPE_ADRP:
  1041. insn = aarch64_insn_get_adrp_value();
  1042. offset = (addr - ALIGN_DOWN(pc, SZ_4K)) >> 12;
  1043. break;
  1044. default:
  1045. pr_err("%s: unknown adr encoding %d\n", __func__, type);
  1046. return AARCH64_BREAK_FAULT;
  1047. }
  1048. if (offset < -SZ_1M || offset >= SZ_1M)
  1049. return AARCH64_BREAK_FAULT;
  1050. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, reg);
  1051. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, offset);
  1052. }
  1053. /*
  1054. * Decode the imm field of a branch, and return the byte offset as a
  1055. * signed value (so it can be used when computing a new branch
  1056. * target).
  1057. */
  1058. s32 aarch64_get_branch_offset(u32 insn)
  1059. {
  1060. s32 imm;
  1061. if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) {
  1062. imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn);
  1063. return (imm << 6) >> 4;
  1064. }
  1065. if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
  1066. aarch64_insn_is_bcond(insn)) {
  1067. imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn);
  1068. return (imm << 13) >> 11;
  1069. }
  1070. if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) {
  1071. imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn);
  1072. return (imm << 18) >> 16;
  1073. }
  1074. /* Unhandled instruction */
  1075. BUG();
  1076. }
  1077. /*
  1078. * Encode the displacement of a branch in the imm field and return the
  1079. * updated instruction.
  1080. */
  1081. u32 aarch64_set_branch_offset(u32 insn, s32 offset)
  1082. {
  1083. if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn))
  1084. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
  1085. offset >> 2);
  1086. if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
  1087. aarch64_insn_is_bcond(insn))
  1088. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
  1089. offset >> 2);
  1090. if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn))
  1091. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_14, insn,
  1092. offset >> 2);
  1093. /* Unhandled instruction */
  1094. BUG();
  1095. }
  1096. s32 aarch64_insn_adrp_get_offset(u32 insn)
  1097. {
  1098. BUG_ON(!aarch64_insn_is_adrp(insn));
  1099. return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12;
  1100. }
  1101. u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset)
  1102. {
  1103. BUG_ON(!aarch64_insn_is_adrp(insn));
  1104. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn,
  1105. offset >> 12);
  1106. }
  1107. /*
  1108. * Extract the Op/CR data from a msr/mrs instruction.
  1109. */
  1110. u32 aarch64_insn_extract_system_reg(u32 insn)
  1111. {
  1112. return (insn & 0x1FFFE0) >> 5;
  1113. }
  1114. bool aarch32_insn_is_wide(u32 insn)
  1115. {
  1116. return insn >= 0xe800;
  1117. }
  1118. /*
  1119. * Macros/defines for extracting register numbers from instruction.
  1120. */
  1121. u32 aarch32_insn_extract_reg_num(u32 insn, int offset)
  1122. {
  1123. return (insn & (0xf << offset)) >> offset;
  1124. }
  1125. #define OPC2_MASK 0x7
  1126. #define OPC2_OFFSET 5
  1127. u32 aarch32_insn_mcr_extract_opc2(u32 insn)
  1128. {
  1129. return (insn & (OPC2_MASK << OPC2_OFFSET)) >> OPC2_OFFSET;
  1130. }
  1131. #define CRM_MASK 0xf
  1132. u32 aarch32_insn_mcr_extract_crm(u32 insn)
  1133. {
  1134. return insn & CRM_MASK;
  1135. }
  1136. static bool range_of_ones(u64 val)
  1137. {
  1138. /* Doesn't handle full ones or full zeroes */
  1139. u64 sval = val >> __ffs64(val);
  1140. /* One of Sean Eron Anderson's bithack tricks */
  1141. return ((sval + 1) & (sval)) == 0;
  1142. }
  1143. static u32 aarch64_encode_immediate(u64 imm,
  1144. enum aarch64_insn_variant variant,
  1145. u32 insn)
  1146. {
  1147. unsigned int immr, imms, n, ones, ror, esz, tmp;
  1148. u64 mask;
  1149. switch (variant) {
  1150. case AARCH64_INSN_VARIANT_32BIT:
  1151. esz = 32;
  1152. break;
  1153. case AARCH64_INSN_VARIANT_64BIT:
  1154. insn |= AARCH64_INSN_SF_BIT;
  1155. esz = 64;
  1156. break;
  1157. default:
  1158. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  1159. return AARCH64_BREAK_FAULT;
  1160. }
  1161. mask = GENMASK(esz - 1, 0);
  1162. /* Can't encode full zeroes, full ones, or value wider than the mask */
  1163. if (!imm || imm == mask || imm & ~mask)
  1164. return AARCH64_BREAK_FAULT;
  1165. /*
  1166. * Inverse of Replicate(). Try to spot a repeating pattern
  1167. * with a pow2 stride.
  1168. */
  1169. for (tmp = esz / 2; tmp >= 2; tmp /= 2) {
  1170. u64 emask = BIT(tmp) - 1;
  1171. if ((imm & emask) != ((imm >> tmp) & emask))
  1172. break;
  1173. esz = tmp;
  1174. mask = emask;
  1175. }
  1176. /* N is only set if we're encoding a 64bit value */
  1177. n = esz == 64;
  1178. /* Trim imm to the element size */
  1179. imm &= mask;
  1180. /* That's how many ones we need to encode */
  1181. ones = hweight64(imm);
  1182. /*
  1183. * imms is set to (ones - 1), prefixed with a string of ones
  1184. * and a zero if they fit. Cap it to 6 bits.
  1185. */
  1186. imms = ones - 1;
  1187. imms |= 0xf << ffs(esz);
  1188. imms &= BIT(6) - 1;
  1189. /* Compute the rotation */
  1190. if (range_of_ones(imm)) {
  1191. /*
  1192. * Pattern: 0..01..10..0
  1193. *
  1194. * Compute how many rotate we need to align it right
  1195. */
  1196. ror = __ffs64(imm);
  1197. } else {
  1198. /*
  1199. * Pattern: 0..01..10..01..1
  1200. *
  1201. * Fill the unused top bits with ones, and check if
  1202. * the result is a valid immediate (all ones with a
  1203. * contiguous ranges of zeroes).
  1204. */
  1205. imm |= ~mask;
  1206. if (!range_of_ones(~imm))
  1207. return AARCH64_BREAK_FAULT;
  1208. /*
  1209. * Compute the rotation to get a continuous set of
  1210. * ones, with the first bit set at position 0
  1211. */
  1212. ror = fls64(~imm);
  1213. }
  1214. /*
  1215. * immr is the number of bits we need to rotate back to the
  1216. * original set of ones. Note that this is relative to the
  1217. * element size...
  1218. */
  1219. immr = (esz - ror) % esz;
  1220. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, n);
  1221. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
  1222. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
  1223. }
  1224. u32 aarch64_insn_gen_logical_immediate(enum aarch64_insn_logic_type type,
  1225. enum aarch64_insn_variant variant,
  1226. enum aarch64_insn_register Rn,
  1227. enum aarch64_insn_register Rd,
  1228. u64 imm)
  1229. {
  1230. u32 insn;
  1231. switch (type) {
  1232. case AARCH64_INSN_LOGIC_AND:
  1233. insn = aarch64_insn_get_and_imm_value();
  1234. break;
  1235. case AARCH64_INSN_LOGIC_ORR:
  1236. insn = aarch64_insn_get_orr_imm_value();
  1237. break;
  1238. case AARCH64_INSN_LOGIC_EOR:
  1239. insn = aarch64_insn_get_eor_imm_value();
  1240. break;
  1241. case AARCH64_INSN_LOGIC_AND_SETFLAGS:
  1242. insn = aarch64_insn_get_ands_imm_value();
  1243. break;
  1244. default:
  1245. pr_err("%s: unknown logical encoding %d\n", __func__, type);
  1246. return AARCH64_BREAK_FAULT;
  1247. }
  1248. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd);
  1249. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
  1250. return aarch64_encode_immediate(imm, variant, insn);
  1251. }
  1252. u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
  1253. enum aarch64_insn_register Rm,
  1254. enum aarch64_insn_register Rn,
  1255. enum aarch64_insn_register Rd,
  1256. u8 lsb)
  1257. {
  1258. u32 insn;
  1259. insn = aarch64_insn_get_extr_value();
  1260. switch (variant) {
  1261. case AARCH64_INSN_VARIANT_32BIT:
  1262. if (lsb > 31)
  1263. return AARCH64_BREAK_FAULT;
  1264. break;
  1265. case AARCH64_INSN_VARIANT_64BIT:
  1266. if (lsb > 63)
  1267. return AARCH64_BREAK_FAULT;
  1268. insn |= AARCH64_INSN_SF_BIT;
  1269. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, 1);
  1270. break;
  1271. default:
  1272. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  1273. return AARCH64_BREAK_FAULT;
  1274. }
  1275. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, lsb);
  1276. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd);
  1277. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
  1278. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
  1279. }
  1280. static u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type)
  1281. {
  1282. switch (type) {
  1283. case AARCH64_INSN_MB_SY:
  1284. return 0xf;
  1285. case AARCH64_INSN_MB_ST:
  1286. return 0xe;
  1287. case AARCH64_INSN_MB_LD:
  1288. return 0xd;
  1289. case AARCH64_INSN_MB_ISH:
  1290. return 0xb;
  1291. case AARCH64_INSN_MB_ISHST:
  1292. return 0xa;
  1293. case AARCH64_INSN_MB_ISHLD:
  1294. return 0x9;
  1295. case AARCH64_INSN_MB_NSH:
  1296. return 0x7;
  1297. case AARCH64_INSN_MB_NSHST:
  1298. return 0x6;
  1299. case AARCH64_INSN_MB_NSHLD:
  1300. return 0x5;
  1301. default:
  1302. pr_err("%s: unknown barrier type %d\n", __func__, type);
  1303. return AARCH64_BREAK_FAULT;
  1304. }
  1305. }
  1306. u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
  1307. {
  1308. u32 opt;
  1309. u32 insn;
  1310. opt = __get_barrier_crm_val(type);
  1311. if (opt == AARCH64_BREAK_FAULT)
  1312. return AARCH64_BREAK_FAULT;
  1313. insn = aarch64_insn_get_dmb_value();
  1314. insn &= ~GENMASK(11, 8);
  1315. insn |= (opt << 8);
  1316. return insn;
  1317. }
  1318. u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type)
  1319. {
  1320. u32 opt, insn;
  1321. opt = __get_barrier_crm_val(type);
  1322. if (opt == AARCH64_BREAK_FAULT)
  1323. return AARCH64_BREAK_FAULT;
  1324. insn = aarch64_insn_get_dsb_base_value();
  1325. insn &= ~GENMASK(11, 8);
  1326. insn |= (opt << 8);
  1327. return insn;
  1328. }
  1329. u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
  1330. enum aarch64_insn_system_register sysreg)
  1331. {
  1332. u32 insn = aarch64_insn_get_mrs_value();
  1333. insn &= ~GENMASK(19, 0);
  1334. insn |= sysreg << 5;
  1335. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT,
  1336. insn, result);
  1337. }