insn.c 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542
  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_store_ex(enum aarch64_insn_register reg,
  464. enum aarch64_insn_register base,
  465. enum aarch64_insn_register state,
  466. enum aarch64_insn_size_type size,
  467. enum aarch64_insn_ldst_type type)
  468. {
  469. u32 insn;
  470. switch (type) {
  471. case AARCH64_INSN_LDST_LOAD_EX:
  472. case AARCH64_INSN_LDST_LOAD_ACQ_EX:
  473. insn = aarch64_insn_get_load_ex_value();
  474. if (type == AARCH64_INSN_LDST_LOAD_ACQ_EX)
  475. insn |= BIT(15);
  476. break;
  477. case AARCH64_INSN_LDST_STORE_EX:
  478. case AARCH64_INSN_LDST_STORE_REL_EX:
  479. insn = aarch64_insn_get_store_ex_value();
  480. if (type == AARCH64_INSN_LDST_STORE_REL_EX)
  481. insn |= BIT(15);
  482. break;
  483. default:
  484. pr_err("%s: unknown load/store exclusive encoding %d\n", __func__, type);
  485. return AARCH64_BREAK_FAULT;
  486. }
  487. insn = aarch64_insn_encode_ldst_size(size, insn);
  488. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  489. reg);
  490. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  491. base);
  492. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
  493. AARCH64_INSN_REG_ZR);
  494. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
  495. state);
  496. }
  497. #ifdef CONFIG_ARM64_LSE_ATOMICS
  498. static u32 aarch64_insn_encode_ldst_order(enum aarch64_insn_mem_order_type type,
  499. u32 insn)
  500. {
  501. u32 order;
  502. switch (type) {
  503. case AARCH64_INSN_MEM_ORDER_NONE:
  504. order = 0;
  505. break;
  506. case AARCH64_INSN_MEM_ORDER_ACQ:
  507. order = 2;
  508. break;
  509. case AARCH64_INSN_MEM_ORDER_REL:
  510. order = 1;
  511. break;
  512. case AARCH64_INSN_MEM_ORDER_ACQREL:
  513. order = 3;
  514. break;
  515. default:
  516. pr_err("%s: unknown mem order %d\n", __func__, type);
  517. return AARCH64_BREAK_FAULT;
  518. }
  519. insn &= ~GENMASK(23, 22);
  520. insn |= order << 22;
  521. return insn;
  522. }
  523. u32 aarch64_insn_gen_atomic_ld_op(enum aarch64_insn_register result,
  524. enum aarch64_insn_register address,
  525. enum aarch64_insn_register value,
  526. enum aarch64_insn_size_type size,
  527. enum aarch64_insn_mem_atomic_op op,
  528. enum aarch64_insn_mem_order_type order)
  529. {
  530. u32 insn;
  531. switch (op) {
  532. case AARCH64_INSN_MEM_ATOMIC_ADD:
  533. insn = aarch64_insn_get_ldadd_value();
  534. break;
  535. case AARCH64_INSN_MEM_ATOMIC_CLR:
  536. insn = aarch64_insn_get_ldclr_value();
  537. break;
  538. case AARCH64_INSN_MEM_ATOMIC_EOR:
  539. insn = aarch64_insn_get_ldeor_value();
  540. break;
  541. case AARCH64_INSN_MEM_ATOMIC_SET:
  542. insn = aarch64_insn_get_ldset_value();
  543. break;
  544. case AARCH64_INSN_MEM_ATOMIC_SWP:
  545. insn = aarch64_insn_get_swp_value();
  546. break;
  547. default:
  548. pr_err("%s: unimplemented mem atomic op %d\n", __func__, op);
  549. return AARCH64_BREAK_FAULT;
  550. }
  551. switch (size) {
  552. case AARCH64_INSN_SIZE_32:
  553. case AARCH64_INSN_SIZE_64:
  554. break;
  555. default:
  556. pr_err("%s: unimplemented size encoding %d\n", __func__, size);
  557. return AARCH64_BREAK_FAULT;
  558. }
  559. insn = aarch64_insn_encode_ldst_size(size, insn);
  560. insn = aarch64_insn_encode_ldst_order(order, insn);
  561. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  562. result);
  563. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  564. address);
  565. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
  566. value);
  567. }
  568. static u32 aarch64_insn_encode_cas_order(enum aarch64_insn_mem_order_type type,
  569. u32 insn)
  570. {
  571. u32 order;
  572. switch (type) {
  573. case AARCH64_INSN_MEM_ORDER_NONE:
  574. order = 0;
  575. break;
  576. case AARCH64_INSN_MEM_ORDER_ACQ:
  577. order = BIT(22);
  578. break;
  579. case AARCH64_INSN_MEM_ORDER_REL:
  580. order = BIT(15);
  581. break;
  582. case AARCH64_INSN_MEM_ORDER_ACQREL:
  583. order = BIT(15) | BIT(22);
  584. break;
  585. default:
  586. pr_err("%s: unknown mem order %d\n", __func__, type);
  587. return AARCH64_BREAK_FAULT;
  588. }
  589. insn &= ~(BIT(15) | BIT(22));
  590. insn |= order;
  591. return insn;
  592. }
  593. u32 aarch64_insn_gen_cas(enum aarch64_insn_register result,
  594. enum aarch64_insn_register address,
  595. enum aarch64_insn_register value,
  596. enum aarch64_insn_size_type size,
  597. enum aarch64_insn_mem_order_type order)
  598. {
  599. u32 insn;
  600. switch (size) {
  601. case AARCH64_INSN_SIZE_32:
  602. case AARCH64_INSN_SIZE_64:
  603. break;
  604. default:
  605. pr_err("%s: unimplemented size encoding %d\n", __func__, size);
  606. return AARCH64_BREAK_FAULT;
  607. }
  608. insn = aarch64_insn_get_cas_value();
  609. insn = aarch64_insn_encode_ldst_size(size, insn);
  610. insn = aarch64_insn_encode_cas_order(order, insn);
  611. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
  612. result);
  613. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  614. address);
  615. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
  616. value);
  617. }
  618. #endif
  619. u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
  620. enum aarch64_insn_register src,
  621. int imm, enum aarch64_insn_variant variant,
  622. enum aarch64_insn_adsb_type type)
  623. {
  624. u32 insn;
  625. switch (type) {
  626. case AARCH64_INSN_ADSB_ADD:
  627. insn = aarch64_insn_get_add_imm_value();
  628. break;
  629. case AARCH64_INSN_ADSB_SUB:
  630. insn = aarch64_insn_get_sub_imm_value();
  631. break;
  632. case AARCH64_INSN_ADSB_ADD_SETFLAGS:
  633. insn = aarch64_insn_get_adds_imm_value();
  634. break;
  635. case AARCH64_INSN_ADSB_SUB_SETFLAGS:
  636. insn = aarch64_insn_get_subs_imm_value();
  637. break;
  638. default:
  639. pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
  640. return AARCH64_BREAK_FAULT;
  641. }
  642. switch (variant) {
  643. case AARCH64_INSN_VARIANT_32BIT:
  644. break;
  645. case AARCH64_INSN_VARIANT_64BIT:
  646. insn |= AARCH64_INSN_SF_BIT;
  647. break;
  648. default:
  649. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  650. return AARCH64_BREAK_FAULT;
  651. }
  652. /* We can't encode more than a 24bit value (12bit + 12bit shift) */
  653. if (imm & ~(BIT(24) - 1))
  654. goto out;
  655. /* If we have something in the top 12 bits... */
  656. if (imm & ~(SZ_4K - 1)) {
  657. /* ... and in the low 12 bits -> error */
  658. if (imm & (SZ_4K - 1))
  659. goto out;
  660. imm >>= 12;
  661. insn |= AARCH64_INSN_LSL_12;
  662. }
  663. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  664. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  665. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
  666. out:
  667. pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
  668. return AARCH64_BREAK_FAULT;
  669. }
  670. u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
  671. enum aarch64_insn_register src,
  672. int immr, int imms,
  673. enum aarch64_insn_variant variant,
  674. enum aarch64_insn_bitfield_type type)
  675. {
  676. u32 insn;
  677. u32 mask;
  678. switch (type) {
  679. case AARCH64_INSN_BITFIELD_MOVE:
  680. insn = aarch64_insn_get_bfm_value();
  681. break;
  682. case AARCH64_INSN_BITFIELD_MOVE_UNSIGNED:
  683. insn = aarch64_insn_get_ubfm_value();
  684. break;
  685. case AARCH64_INSN_BITFIELD_MOVE_SIGNED:
  686. insn = aarch64_insn_get_sbfm_value();
  687. break;
  688. default:
  689. pr_err("%s: unknown bitfield encoding %d\n", __func__, type);
  690. return AARCH64_BREAK_FAULT;
  691. }
  692. switch (variant) {
  693. case AARCH64_INSN_VARIANT_32BIT:
  694. mask = GENMASK(4, 0);
  695. break;
  696. case AARCH64_INSN_VARIANT_64BIT:
  697. insn |= AARCH64_INSN_SF_BIT | AARCH64_INSN_N_BIT;
  698. mask = GENMASK(5, 0);
  699. break;
  700. default:
  701. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  702. return AARCH64_BREAK_FAULT;
  703. }
  704. if (immr & ~mask) {
  705. pr_err("%s: invalid immr encoding %d\n", __func__, immr);
  706. return AARCH64_BREAK_FAULT;
  707. }
  708. if (imms & ~mask) {
  709. pr_err("%s: invalid imms encoding %d\n", __func__, imms);
  710. return AARCH64_BREAK_FAULT;
  711. }
  712. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  713. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  714. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
  715. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
  716. }
  717. u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
  718. int imm, int shift,
  719. enum aarch64_insn_variant variant,
  720. enum aarch64_insn_movewide_type type)
  721. {
  722. u32 insn;
  723. switch (type) {
  724. case AARCH64_INSN_MOVEWIDE_ZERO:
  725. insn = aarch64_insn_get_movz_value();
  726. break;
  727. case AARCH64_INSN_MOVEWIDE_KEEP:
  728. insn = aarch64_insn_get_movk_value();
  729. break;
  730. case AARCH64_INSN_MOVEWIDE_INVERSE:
  731. insn = aarch64_insn_get_movn_value();
  732. break;
  733. default:
  734. pr_err("%s: unknown movewide encoding %d\n", __func__, type);
  735. return AARCH64_BREAK_FAULT;
  736. }
  737. if (imm & ~(SZ_64K - 1)) {
  738. pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
  739. return AARCH64_BREAK_FAULT;
  740. }
  741. switch (variant) {
  742. case AARCH64_INSN_VARIANT_32BIT:
  743. if (shift != 0 && shift != 16) {
  744. pr_err("%s: invalid shift encoding %d\n", __func__,
  745. shift);
  746. return AARCH64_BREAK_FAULT;
  747. }
  748. break;
  749. case AARCH64_INSN_VARIANT_64BIT:
  750. insn |= AARCH64_INSN_SF_BIT;
  751. if (shift != 0 && shift != 16 && shift != 32 && shift != 48) {
  752. pr_err("%s: invalid shift encoding %d\n", __func__,
  753. shift);
  754. return AARCH64_BREAK_FAULT;
  755. }
  756. break;
  757. default:
  758. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  759. return AARCH64_BREAK_FAULT;
  760. }
  761. insn |= (shift >> 4) << 21;
  762. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  763. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm);
  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. switch (type) {
  774. case AARCH64_INSN_ADSB_ADD:
  775. insn = aarch64_insn_get_add_value();
  776. break;
  777. case AARCH64_INSN_ADSB_SUB:
  778. insn = aarch64_insn_get_sub_value();
  779. break;
  780. case AARCH64_INSN_ADSB_ADD_SETFLAGS:
  781. insn = aarch64_insn_get_adds_value();
  782. break;
  783. case AARCH64_INSN_ADSB_SUB_SETFLAGS:
  784. insn = aarch64_insn_get_subs_value();
  785. break;
  786. default:
  787. pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
  788. return AARCH64_BREAK_FAULT;
  789. }
  790. switch (variant) {
  791. case AARCH64_INSN_VARIANT_32BIT:
  792. if (shift & ~(SZ_32 - 1)) {
  793. pr_err("%s: invalid shift encoding %d\n", __func__,
  794. shift);
  795. return AARCH64_BREAK_FAULT;
  796. }
  797. break;
  798. case AARCH64_INSN_VARIANT_64BIT:
  799. insn |= AARCH64_INSN_SF_BIT;
  800. if (shift & ~(SZ_64 - 1)) {
  801. pr_err("%s: invalid shift encoding %d\n", __func__,
  802. shift);
  803. return AARCH64_BREAK_FAULT;
  804. }
  805. break;
  806. default:
  807. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  808. return AARCH64_BREAK_FAULT;
  809. }
  810. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  811. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  812. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
  813. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
  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. switch (type) {
  822. case AARCH64_INSN_DATA1_REVERSE_16:
  823. insn = aarch64_insn_get_rev16_value();
  824. break;
  825. case AARCH64_INSN_DATA1_REVERSE_32:
  826. insn = aarch64_insn_get_rev32_value();
  827. break;
  828. case AARCH64_INSN_DATA1_REVERSE_64:
  829. if (variant != AARCH64_INSN_VARIANT_64BIT) {
  830. pr_err("%s: invalid variant for reverse64 %d\n",
  831. __func__, variant);
  832. return AARCH64_BREAK_FAULT;
  833. }
  834. insn = aarch64_insn_get_rev64_value();
  835. break;
  836. default:
  837. pr_err("%s: unknown data1 encoding %d\n", __func__, type);
  838. return AARCH64_BREAK_FAULT;
  839. }
  840. switch (variant) {
  841. case AARCH64_INSN_VARIANT_32BIT:
  842. break;
  843. case AARCH64_INSN_VARIANT_64BIT:
  844. insn |= AARCH64_INSN_SF_BIT;
  845. break;
  846. default:
  847. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  848. return AARCH64_BREAK_FAULT;
  849. }
  850. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  851. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  852. }
  853. u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
  854. enum aarch64_insn_register src,
  855. enum aarch64_insn_register reg,
  856. enum aarch64_insn_variant variant,
  857. enum aarch64_insn_data2_type type)
  858. {
  859. u32 insn;
  860. switch (type) {
  861. case AARCH64_INSN_DATA2_UDIV:
  862. insn = aarch64_insn_get_udiv_value();
  863. break;
  864. case AARCH64_INSN_DATA2_SDIV:
  865. insn = aarch64_insn_get_sdiv_value();
  866. break;
  867. case AARCH64_INSN_DATA2_LSLV:
  868. insn = aarch64_insn_get_lslv_value();
  869. break;
  870. case AARCH64_INSN_DATA2_LSRV:
  871. insn = aarch64_insn_get_lsrv_value();
  872. break;
  873. case AARCH64_INSN_DATA2_ASRV:
  874. insn = aarch64_insn_get_asrv_value();
  875. break;
  876. case AARCH64_INSN_DATA2_RORV:
  877. insn = aarch64_insn_get_rorv_value();
  878. break;
  879. default:
  880. pr_err("%s: unknown data2 encoding %d\n", __func__, type);
  881. return AARCH64_BREAK_FAULT;
  882. }
  883. switch (variant) {
  884. case AARCH64_INSN_VARIANT_32BIT:
  885. break;
  886. case AARCH64_INSN_VARIANT_64BIT:
  887. insn |= AARCH64_INSN_SF_BIT;
  888. break;
  889. default:
  890. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  891. return AARCH64_BREAK_FAULT;
  892. }
  893. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  894. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  895. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
  896. }
  897. u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
  898. enum aarch64_insn_register src,
  899. enum aarch64_insn_register reg1,
  900. enum aarch64_insn_register reg2,
  901. enum aarch64_insn_variant variant,
  902. enum aarch64_insn_data3_type type)
  903. {
  904. u32 insn;
  905. switch (type) {
  906. case AARCH64_INSN_DATA3_MADD:
  907. insn = aarch64_insn_get_madd_value();
  908. break;
  909. case AARCH64_INSN_DATA3_MSUB:
  910. insn = aarch64_insn_get_msub_value();
  911. break;
  912. default:
  913. pr_err("%s: unknown data3 encoding %d\n", __func__, type);
  914. return AARCH64_BREAK_FAULT;
  915. }
  916. switch (variant) {
  917. case AARCH64_INSN_VARIANT_32BIT:
  918. break;
  919. case AARCH64_INSN_VARIANT_64BIT:
  920. insn |= AARCH64_INSN_SF_BIT;
  921. break;
  922. default:
  923. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  924. return AARCH64_BREAK_FAULT;
  925. }
  926. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  927. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RA, insn, src);
  928. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
  929. reg1);
  930. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
  931. reg2);
  932. }
  933. u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
  934. enum aarch64_insn_register src,
  935. enum aarch64_insn_register reg,
  936. int shift,
  937. enum aarch64_insn_variant variant,
  938. enum aarch64_insn_logic_type type)
  939. {
  940. u32 insn;
  941. switch (type) {
  942. case AARCH64_INSN_LOGIC_AND:
  943. insn = aarch64_insn_get_and_value();
  944. break;
  945. case AARCH64_INSN_LOGIC_BIC:
  946. insn = aarch64_insn_get_bic_value();
  947. break;
  948. case AARCH64_INSN_LOGIC_ORR:
  949. insn = aarch64_insn_get_orr_value();
  950. break;
  951. case AARCH64_INSN_LOGIC_ORN:
  952. insn = aarch64_insn_get_orn_value();
  953. break;
  954. case AARCH64_INSN_LOGIC_EOR:
  955. insn = aarch64_insn_get_eor_value();
  956. break;
  957. case AARCH64_INSN_LOGIC_EON:
  958. insn = aarch64_insn_get_eon_value();
  959. break;
  960. case AARCH64_INSN_LOGIC_AND_SETFLAGS:
  961. insn = aarch64_insn_get_ands_value();
  962. break;
  963. case AARCH64_INSN_LOGIC_BIC_SETFLAGS:
  964. insn = aarch64_insn_get_bics_value();
  965. break;
  966. default:
  967. pr_err("%s: unknown logical encoding %d\n", __func__, type);
  968. return AARCH64_BREAK_FAULT;
  969. }
  970. switch (variant) {
  971. case AARCH64_INSN_VARIANT_32BIT:
  972. if (shift & ~(SZ_32 - 1)) {
  973. pr_err("%s: invalid shift encoding %d\n", __func__,
  974. shift);
  975. return AARCH64_BREAK_FAULT;
  976. }
  977. break;
  978. case AARCH64_INSN_VARIANT_64BIT:
  979. insn |= AARCH64_INSN_SF_BIT;
  980. if (shift & ~(SZ_64 - 1)) {
  981. pr_err("%s: invalid shift encoding %d\n", __func__,
  982. shift);
  983. return AARCH64_BREAK_FAULT;
  984. }
  985. break;
  986. default:
  987. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  988. return AARCH64_BREAK_FAULT;
  989. }
  990. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
  991. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
  992. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
  993. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
  994. }
  995. /*
  996. * MOV (register) is architecturally an alias of ORR (shifted register) where
  997. * MOV <*d>, <*m> is equivalent to ORR <*d>, <*ZR>, <*m>
  998. */
  999. u32 aarch64_insn_gen_move_reg(enum aarch64_insn_register dst,
  1000. enum aarch64_insn_register src,
  1001. enum aarch64_insn_variant variant)
  1002. {
  1003. return aarch64_insn_gen_logical_shifted_reg(dst, AARCH64_INSN_REG_ZR,
  1004. src, 0, variant,
  1005. AARCH64_INSN_LOGIC_ORR);
  1006. }
  1007. u32 aarch64_insn_gen_adr(unsigned long pc, unsigned long addr,
  1008. enum aarch64_insn_register reg,
  1009. enum aarch64_insn_adr_type type)
  1010. {
  1011. u32 insn;
  1012. s32 offset;
  1013. switch (type) {
  1014. case AARCH64_INSN_ADR_TYPE_ADR:
  1015. insn = aarch64_insn_get_adr_value();
  1016. offset = addr - pc;
  1017. break;
  1018. case AARCH64_INSN_ADR_TYPE_ADRP:
  1019. insn = aarch64_insn_get_adrp_value();
  1020. offset = (addr - ALIGN_DOWN(pc, SZ_4K)) >> 12;
  1021. break;
  1022. default:
  1023. pr_err("%s: unknown adr encoding %d\n", __func__, type);
  1024. return AARCH64_BREAK_FAULT;
  1025. }
  1026. if (offset < -SZ_1M || offset >= SZ_1M)
  1027. return AARCH64_BREAK_FAULT;
  1028. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, reg);
  1029. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn, offset);
  1030. }
  1031. /*
  1032. * Decode the imm field of a branch, and return the byte offset as a
  1033. * signed value (so it can be used when computing a new branch
  1034. * target).
  1035. */
  1036. s32 aarch64_get_branch_offset(u32 insn)
  1037. {
  1038. s32 imm;
  1039. if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) {
  1040. imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn);
  1041. return (imm << 6) >> 4;
  1042. }
  1043. if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
  1044. aarch64_insn_is_bcond(insn)) {
  1045. imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn);
  1046. return (imm << 13) >> 11;
  1047. }
  1048. if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) {
  1049. imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn);
  1050. return (imm << 18) >> 16;
  1051. }
  1052. /* Unhandled instruction */
  1053. BUG();
  1054. }
  1055. /*
  1056. * Encode the displacement of a branch in the imm field and return the
  1057. * updated instruction.
  1058. */
  1059. u32 aarch64_set_branch_offset(u32 insn, s32 offset)
  1060. {
  1061. if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn))
  1062. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
  1063. offset >> 2);
  1064. if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
  1065. aarch64_insn_is_bcond(insn))
  1066. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
  1067. offset >> 2);
  1068. if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn))
  1069. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_14, insn,
  1070. offset >> 2);
  1071. /* Unhandled instruction */
  1072. BUG();
  1073. }
  1074. s32 aarch64_insn_adrp_get_offset(u32 insn)
  1075. {
  1076. BUG_ON(!aarch64_insn_is_adrp(insn));
  1077. return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12;
  1078. }
  1079. u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset)
  1080. {
  1081. BUG_ON(!aarch64_insn_is_adrp(insn));
  1082. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn,
  1083. offset >> 12);
  1084. }
  1085. /*
  1086. * Extract the Op/CR data from a msr/mrs instruction.
  1087. */
  1088. u32 aarch64_insn_extract_system_reg(u32 insn)
  1089. {
  1090. return (insn & 0x1FFFE0) >> 5;
  1091. }
  1092. bool aarch32_insn_is_wide(u32 insn)
  1093. {
  1094. return insn >= 0xe800;
  1095. }
  1096. /*
  1097. * Macros/defines for extracting register numbers from instruction.
  1098. */
  1099. u32 aarch32_insn_extract_reg_num(u32 insn, int offset)
  1100. {
  1101. return (insn & (0xf << offset)) >> offset;
  1102. }
  1103. #define OPC2_MASK 0x7
  1104. #define OPC2_OFFSET 5
  1105. u32 aarch32_insn_mcr_extract_opc2(u32 insn)
  1106. {
  1107. return (insn & (OPC2_MASK << OPC2_OFFSET)) >> OPC2_OFFSET;
  1108. }
  1109. #define CRM_MASK 0xf
  1110. u32 aarch32_insn_mcr_extract_crm(u32 insn)
  1111. {
  1112. return insn & CRM_MASK;
  1113. }
  1114. static bool range_of_ones(u64 val)
  1115. {
  1116. /* Doesn't handle full ones or full zeroes */
  1117. u64 sval = val >> __ffs64(val);
  1118. /* One of Sean Eron Anderson's bithack tricks */
  1119. return ((sval + 1) & (sval)) == 0;
  1120. }
  1121. static u32 aarch64_encode_immediate(u64 imm,
  1122. enum aarch64_insn_variant variant,
  1123. u32 insn)
  1124. {
  1125. unsigned int immr, imms, n, ones, ror, esz, tmp;
  1126. u64 mask;
  1127. switch (variant) {
  1128. case AARCH64_INSN_VARIANT_32BIT:
  1129. esz = 32;
  1130. break;
  1131. case AARCH64_INSN_VARIANT_64BIT:
  1132. insn |= AARCH64_INSN_SF_BIT;
  1133. esz = 64;
  1134. break;
  1135. default:
  1136. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  1137. return AARCH64_BREAK_FAULT;
  1138. }
  1139. mask = GENMASK(esz - 1, 0);
  1140. /* Can't encode full zeroes, full ones, or value wider than the mask */
  1141. if (!imm || imm == mask || imm & ~mask)
  1142. return AARCH64_BREAK_FAULT;
  1143. /*
  1144. * Inverse of Replicate(). Try to spot a repeating pattern
  1145. * with a pow2 stride.
  1146. */
  1147. for (tmp = esz / 2; tmp >= 2; tmp /= 2) {
  1148. u64 emask = BIT(tmp) - 1;
  1149. if ((imm & emask) != ((imm >> tmp) & emask))
  1150. break;
  1151. esz = tmp;
  1152. mask = emask;
  1153. }
  1154. /* N is only set if we're encoding a 64bit value */
  1155. n = esz == 64;
  1156. /* Trim imm to the element size */
  1157. imm &= mask;
  1158. /* That's how many ones we need to encode */
  1159. ones = hweight64(imm);
  1160. /*
  1161. * imms is set to (ones - 1), prefixed with a string of ones
  1162. * and a zero if they fit. Cap it to 6 bits.
  1163. */
  1164. imms = ones - 1;
  1165. imms |= 0xf << ffs(esz);
  1166. imms &= BIT(6) - 1;
  1167. /* Compute the rotation */
  1168. if (range_of_ones(imm)) {
  1169. /*
  1170. * Pattern: 0..01..10..0
  1171. *
  1172. * Compute how many rotate we need to align it right
  1173. */
  1174. ror = __ffs64(imm);
  1175. } else {
  1176. /*
  1177. * Pattern: 0..01..10..01..1
  1178. *
  1179. * Fill the unused top bits with ones, and check if
  1180. * the result is a valid immediate (all ones with a
  1181. * contiguous ranges of zeroes).
  1182. */
  1183. imm |= ~mask;
  1184. if (!range_of_ones(~imm))
  1185. return AARCH64_BREAK_FAULT;
  1186. /*
  1187. * Compute the rotation to get a continuous set of
  1188. * ones, with the first bit set at position 0
  1189. */
  1190. ror = fls64(~imm);
  1191. }
  1192. /*
  1193. * immr is the number of bits we need to rotate back to the
  1194. * original set of ones. Note that this is relative to the
  1195. * element size...
  1196. */
  1197. immr = (esz - ror) % esz;
  1198. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, n);
  1199. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
  1200. return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
  1201. }
  1202. u32 aarch64_insn_gen_logical_immediate(enum aarch64_insn_logic_type type,
  1203. enum aarch64_insn_variant variant,
  1204. enum aarch64_insn_register Rn,
  1205. enum aarch64_insn_register Rd,
  1206. u64 imm)
  1207. {
  1208. u32 insn;
  1209. switch (type) {
  1210. case AARCH64_INSN_LOGIC_AND:
  1211. insn = aarch64_insn_get_and_imm_value();
  1212. break;
  1213. case AARCH64_INSN_LOGIC_ORR:
  1214. insn = aarch64_insn_get_orr_imm_value();
  1215. break;
  1216. case AARCH64_INSN_LOGIC_EOR:
  1217. insn = aarch64_insn_get_eor_imm_value();
  1218. break;
  1219. case AARCH64_INSN_LOGIC_AND_SETFLAGS:
  1220. insn = aarch64_insn_get_ands_imm_value();
  1221. break;
  1222. default:
  1223. pr_err("%s: unknown logical encoding %d\n", __func__, type);
  1224. return AARCH64_BREAK_FAULT;
  1225. }
  1226. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd);
  1227. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
  1228. return aarch64_encode_immediate(imm, variant, insn);
  1229. }
  1230. u32 aarch64_insn_gen_extr(enum aarch64_insn_variant variant,
  1231. enum aarch64_insn_register Rm,
  1232. enum aarch64_insn_register Rn,
  1233. enum aarch64_insn_register Rd,
  1234. u8 lsb)
  1235. {
  1236. u32 insn;
  1237. insn = aarch64_insn_get_extr_value();
  1238. switch (variant) {
  1239. case AARCH64_INSN_VARIANT_32BIT:
  1240. if (lsb > 31)
  1241. return AARCH64_BREAK_FAULT;
  1242. break;
  1243. case AARCH64_INSN_VARIANT_64BIT:
  1244. if (lsb > 63)
  1245. return AARCH64_BREAK_FAULT;
  1246. insn |= AARCH64_INSN_SF_BIT;
  1247. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_N, insn, 1);
  1248. break;
  1249. default:
  1250. pr_err("%s: unknown variant encoding %d\n", __func__, variant);
  1251. return AARCH64_BREAK_FAULT;
  1252. }
  1253. insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, lsb);
  1254. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, Rd);
  1255. insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, Rn);
  1256. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, Rm);
  1257. }
  1258. static u32 __get_barrier_crm_val(enum aarch64_insn_mb_type type)
  1259. {
  1260. switch (type) {
  1261. case AARCH64_INSN_MB_SY:
  1262. return 0xf;
  1263. case AARCH64_INSN_MB_ST:
  1264. return 0xe;
  1265. case AARCH64_INSN_MB_LD:
  1266. return 0xd;
  1267. case AARCH64_INSN_MB_ISH:
  1268. return 0xb;
  1269. case AARCH64_INSN_MB_ISHST:
  1270. return 0xa;
  1271. case AARCH64_INSN_MB_ISHLD:
  1272. return 0x9;
  1273. case AARCH64_INSN_MB_NSH:
  1274. return 0x7;
  1275. case AARCH64_INSN_MB_NSHST:
  1276. return 0x6;
  1277. case AARCH64_INSN_MB_NSHLD:
  1278. return 0x5;
  1279. default:
  1280. pr_err("%s: unknown barrier type %d\n", __func__, type);
  1281. return AARCH64_BREAK_FAULT;
  1282. }
  1283. }
  1284. u32 aarch64_insn_gen_dmb(enum aarch64_insn_mb_type type)
  1285. {
  1286. u32 opt;
  1287. u32 insn;
  1288. opt = __get_barrier_crm_val(type);
  1289. if (opt == AARCH64_BREAK_FAULT)
  1290. return AARCH64_BREAK_FAULT;
  1291. insn = aarch64_insn_get_dmb_value();
  1292. insn &= ~GENMASK(11, 8);
  1293. insn |= (opt << 8);
  1294. return insn;
  1295. }
  1296. u32 aarch64_insn_gen_dsb(enum aarch64_insn_mb_type type)
  1297. {
  1298. u32 opt, insn;
  1299. opt = __get_barrier_crm_val(type);
  1300. if (opt == AARCH64_BREAK_FAULT)
  1301. return AARCH64_BREAK_FAULT;
  1302. insn = aarch64_insn_get_dsb_base_value();
  1303. insn &= ~GENMASK(11, 8);
  1304. insn |= (opt << 8);
  1305. return insn;
  1306. }
  1307. u32 aarch64_insn_gen_mrs(enum aarch64_insn_register result,
  1308. enum aarch64_insn_system_register sysreg)
  1309. {
  1310. u32 insn = aarch64_insn_get_mrs_value();
  1311. insn &= ~GENMASK(19, 0);
  1312. insn |= sysreg << 5;
  1313. return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT,
  1314. insn, result);
  1315. }