aml-build.c 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992
  1. /* Support for generating ACPI tables and passing them to Guests
  2. *
  3. * Copyright (C) 2015 Red Hat Inc
  4. *
  5. * Author: Michael S. Tsirkin <mst@redhat.com>
  6. * Author: Igor Mammedov <imammedo@redhat.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version.
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. * You should have received a copy of the GNU General Public License along
  17. * with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "qemu/osdep.h"
  20. #include <glib/gprintf.h>
  21. #include "hw/acpi/aml-build.h"
  22. #include "qemu/bswap.h"
  23. #include "qemu/bitops.h"
  24. #include "sysemu/numa.h"
  25. #include "hw/boards.h"
  26. #include "hw/acpi/tpm.h"
  27. static GArray *build_alloc_array(void)
  28. {
  29. return g_array_new(false, true /* clear */, 1);
  30. }
  31. static void build_free_array(GArray *array)
  32. {
  33. g_array_free(array, true);
  34. }
  35. static void build_prepend_byte(GArray *array, uint8_t val)
  36. {
  37. g_array_prepend_val(array, val);
  38. }
  39. static void build_append_byte(GArray *array, uint8_t val)
  40. {
  41. g_array_append_val(array, val);
  42. }
  43. static void build_append_array(GArray *array, GArray *val)
  44. {
  45. g_array_append_vals(array, val->data, val->len);
  46. }
  47. #define ACPI_NAMESEG_LEN 4
  48. static void
  49. build_append_nameseg(GArray *array, const char *seg)
  50. {
  51. int len;
  52. len = strlen(seg);
  53. assert(len <= ACPI_NAMESEG_LEN);
  54. g_array_append_vals(array, seg, len);
  55. /* Pad up to ACPI_NAMESEG_LEN characters if necessary. */
  56. g_array_append_vals(array, "____", ACPI_NAMESEG_LEN - len);
  57. }
  58. static void GCC_FMT_ATTR(2, 0)
  59. build_append_namestringv(GArray *array, const char *format, va_list ap)
  60. {
  61. char *s;
  62. char **segs;
  63. char **segs_iter;
  64. int seg_count = 0;
  65. s = g_strdup_vprintf(format, ap);
  66. segs = g_strsplit(s, ".", 0);
  67. g_free(s);
  68. /* count segments */
  69. segs_iter = segs;
  70. while (*segs_iter) {
  71. ++segs_iter;
  72. ++seg_count;
  73. }
  74. /*
  75. * ACPI 5.0 spec: 20.2.2 Name Objects Encoding:
  76. * "SegCount can be from 1 to 255"
  77. */
  78. assert(seg_count > 0 && seg_count <= 255);
  79. /* handle RootPath || PrefixPath */
  80. s = *segs;
  81. while (*s == '\\' || *s == '^') {
  82. build_append_byte(array, *s);
  83. ++s;
  84. }
  85. switch (seg_count) {
  86. case 1:
  87. if (!*s) {
  88. build_append_byte(array, 0x00); /* NullName */
  89. } else {
  90. build_append_nameseg(array, s);
  91. }
  92. break;
  93. case 2:
  94. build_append_byte(array, 0x2E); /* DualNamePrefix */
  95. build_append_nameseg(array, s);
  96. build_append_nameseg(array, segs[1]);
  97. break;
  98. default:
  99. build_append_byte(array, 0x2F); /* MultiNamePrefix */
  100. build_append_byte(array, seg_count);
  101. /* handle the 1st segment manually due to prefix/root path */
  102. build_append_nameseg(array, s);
  103. /* add the rest of segments */
  104. segs_iter = segs + 1;
  105. while (*segs_iter) {
  106. build_append_nameseg(array, *segs_iter);
  107. ++segs_iter;
  108. }
  109. break;
  110. }
  111. g_strfreev(segs);
  112. }
  113. GCC_FMT_ATTR(2, 3)
  114. static void build_append_namestring(GArray *array, const char *format, ...)
  115. {
  116. va_list ap;
  117. va_start(ap, format);
  118. build_append_namestringv(array, format, ap);
  119. va_end(ap);
  120. }
  121. /* 5.4 Definition Block Encoding */
  122. enum {
  123. PACKAGE_LENGTH_1BYTE_SHIFT = 6, /* Up to 63 - use extra 2 bits. */
  124. PACKAGE_LENGTH_2BYTE_SHIFT = 4,
  125. PACKAGE_LENGTH_3BYTE_SHIFT = 12,
  126. PACKAGE_LENGTH_4BYTE_SHIFT = 20,
  127. };
  128. static void
  129. build_prepend_package_length(GArray *package, unsigned length, bool incl_self)
  130. {
  131. uint8_t byte;
  132. unsigned length_bytes;
  133. if (length + 1 < (1 << PACKAGE_LENGTH_1BYTE_SHIFT)) {
  134. length_bytes = 1;
  135. } else if (length + 2 < (1 << PACKAGE_LENGTH_3BYTE_SHIFT)) {
  136. length_bytes = 2;
  137. } else if (length + 3 < (1 << PACKAGE_LENGTH_4BYTE_SHIFT)) {
  138. length_bytes = 3;
  139. } else {
  140. length_bytes = 4;
  141. }
  142. /*
  143. * NamedField uses PkgLength encoding but it doesn't include length
  144. * of PkgLength itself.
  145. */
  146. if (incl_self) {
  147. /*
  148. * PkgLength is the length of the inclusive length of the data
  149. * and PkgLength's length itself when used for terms with
  150. * explitit length.
  151. */
  152. length += length_bytes;
  153. }
  154. switch (length_bytes) {
  155. case 1:
  156. byte = length;
  157. build_prepend_byte(package, byte);
  158. return;
  159. case 4:
  160. byte = length >> PACKAGE_LENGTH_4BYTE_SHIFT;
  161. build_prepend_byte(package, byte);
  162. length &= (1 << PACKAGE_LENGTH_4BYTE_SHIFT) - 1;
  163. /* fall through */
  164. case 3:
  165. byte = length >> PACKAGE_LENGTH_3BYTE_SHIFT;
  166. build_prepend_byte(package, byte);
  167. length &= (1 << PACKAGE_LENGTH_3BYTE_SHIFT) - 1;
  168. /* fall through */
  169. case 2:
  170. byte = length >> PACKAGE_LENGTH_2BYTE_SHIFT;
  171. build_prepend_byte(package, byte);
  172. length &= (1 << PACKAGE_LENGTH_2BYTE_SHIFT) - 1;
  173. /* fall through */
  174. }
  175. /*
  176. * Most significant two bits of byte zero indicate how many following bytes
  177. * are in PkgLength encoding.
  178. */
  179. byte = ((length_bytes - 1) << PACKAGE_LENGTH_1BYTE_SHIFT) | length;
  180. build_prepend_byte(package, byte);
  181. }
  182. static void
  183. build_append_pkg_length(GArray *array, unsigned length, bool incl_self)
  184. {
  185. GArray *tmp = build_alloc_array();
  186. build_prepend_package_length(tmp, length, incl_self);
  187. build_append_array(array, tmp);
  188. build_free_array(tmp);
  189. }
  190. static void build_package(GArray *package, uint8_t op)
  191. {
  192. build_prepend_package_length(package, package->len, true);
  193. build_prepend_byte(package, op);
  194. }
  195. static void build_extop_package(GArray *package, uint8_t op)
  196. {
  197. build_package(package, op);
  198. build_prepend_byte(package, 0x5B); /* ExtOpPrefix */
  199. }
  200. void build_append_int_noprefix(GArray *table, uint64_t value, int size)
  201. {
  202. int i;
  203. for (i = 0; i < size; ++i) {
  204. build_append_byte(table, value & 0xFF);
  205. value = value >> 8;
  206. }
  207. }
  208. static void build_append_int(GArray *table, uint64_t value)
  209. {
  210. if (value == 0x00) {
  211. build_append_byte(table, 0x00); /* ZeroOp */
  212. } else if (value == 0x01) {
  213. build_append_byte(table, 0x01); /* OneOp */
  214. } else if (value <= 0xFF) {
  215. build_append_byte(table, 0x0A); /* BytePrefix */
  216. build_append_int_noprefix(table, value, 1);
  217. } else if (value <= 0xFFFF) {
  218. build_append_byte(table, 0x0B); /* WordPrefix */
  219. build_append_int_noprefix(table, value, 2);
  220. } else if (value <= 0xFFFFFFFF) {
  221. build_append_byte(table, 0x0C); /* DWordPrefix */
  222. build_append_int_noprefix(table, value, 4);
  223. } else {
  224. build_append_byte(table, 0x0E); /* QWordPrefix */
  225. build_append_int_noprefix(table, value, 8);
  226. }
  227. }
  228. /* Generic Address Structure (GAS)
  229. * ACPI 2.0/3.0: 5.2.3.1 Generic Address Structure
  230. * 2.0 compat note:
  231. * @access_width must be 0, see ACPI 2.0:Table 5-1
  232. */
  233. void build_append_gas(GArray *table, AmlAddressSpace as,
  234. uint8_t bit_width, uint8_t bit_offset,
  235. uint8_t access_width, uint64_t address)
  236. {
  237. build_append_int_noprefix(table, as, 1);
  238. build_append_int_noprefix(table, bit_width, 1);
  239. build_append_int_noprefix(table, bit_offset, 1);
  240. build_append_int_noprefix(table, access_width, 1);
  241. build_append_int_noprefix(table, address, 8);
  242. }
  243. /*
  244. * Build NAME(XXXX, 0x00000000) where 0x00000000 is encoded as a dword,
  245. * and return the offset to 0x00000000 for runtime patching.
  246. *
  247. * Warning: runtime patching is best avoided. Only use this as
  248. * a replacement for DataTableRegion (for guests that don't
  249. * support it).
  250. */
  251. int
  252. build_append_named_dword(GArray *array, const char *name_format, ...)
  253. {
  254. int offset;
  255. va_list ap;
  256. build_append_byte(array, 0x08); /* NameOp */
  257. va_start(ap, name_format);
  258. build_append_namestringv(array, name_format, ap);
  259. va_end(ap);
  260. build_append_byte(array, 0x0C); /* DWordPrefix */
  261. offset = array->len;
  262. build_append_int_noprefix(array, 0x00000000, 4);
  263. assert(array->len == offset + 4);
  264. return offset;
  265. }
  266. static GPtrArray *alloc_list;
  267. static Aml *aml_alloc(void)
  268. {
  269. Aml *var = g_new0(typeof(*var), 1);
  270. g_ptr_array_add(alloc_list, var);
  271. var->block_flags = AML_NO_OPCODE;
  272. var->buf = build_alloc_array();
  273. return var;
  274. }
  275. static Aml *aml_opcode(uint8_t op)
  276. {
  277. Aml *var = aml_alloc();
  278. var->op = op;
  279. var->block_flags = AML_OPCODE;
  280. return var;
  281. }
  282. static Aml *aml_bundle(uint8_t op, AmlBlockFlags flags)
  283. {
  284. Aml *var = aml_alloc();
  285. var->op = op;
  286. var->block_flags = flags;
  287. return var;
  288. }
  289. static void aml_free(gpointer data, gpointer user_data)
  290. {
  291. Aml *var = data;
  292. build_free_array(var->buf);
  293. g_free(var);
  294. }
  295. Aml *init_aml_allocator(void)
  296. {
  297. assert(!alloc_list);
  298. alloc_list = g_ptr_array_new();
  299. return aml_alloc();
  300. }
  301. void free_aml_allocator(void)
  302. {
  303. g_ptr_array_foreach(alloc_list, aml_free, NULL);
  304. g_ptr_array_free(alloc_list, true);
  305. alloc_list = 0;
  306. }
  307. /* pack data with DefBuffer encoding */
  308. static void build_buffer(GArray *array, uint8_t op)
  309. {
  310. GArray *data = build_alloc_array();
  311. build_append_int(data, array->len);
  312. g_array_prepend_vals(array, data->data, data->len);
  313. build_free_array(data);
  314. build_package(array, op);
  315. }
  316. void aml_append(Aml *parent_ctx, Aml *child)
  317. {
  318. GArray *buf = build_alloc_array();
  319. build_append_array(buf, child->buf);
  320. switch (child->block_flags) {
  321. case AML_OPCODE:
  322. build_append_byte(parent_ctx->buf, child->op);
  323. break;
  324. case AML_EXT_PACKAGE:
  325. build_extop_package(buf, child->op);
  326. break;
  327. case AML_PACKAGE:
  328. build_package(buf, child->op);
  329. break;
  330. case AML_RES_TEMPLATE:
  331. build_append_byte(buf, 0x79); /* EndTag */
  332. /*
  333. * checksum operations are treated as succeeded if checksum
  334. * field is zero. [ACPI Spec 1.0b, 6.4.2.8 End Tag]
  335. */
  336. build_append_byte(buf, 0);
  337. /* fall through, to pack resources in buffer */
  338. case AML_BUFFER:
  339. build_buffer(buf, child->op);
  340. break;
  341. case AML_NO_OPCODE:
  342. break;
  343. default:
  344. assert(0);
  345. break;
  346. }
  347. build_append_array(parent_ctx->buf, buf);
  348. build_free_array(buf);
  349. }
  350. /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefScope */
  351. Aml *aml_scope(const char *name_format, ...)
  352. {
  353. va_list ap;
  354. Aml *var = aml_bundle(0x10 /* ScopeOp */, AML_PACKAGE);
  355. va_start(ap, name_format);
  356. build_append_namestringv(var->buf, name_format, ap);
  357. va_end(ap);
  358. return var;
  359. }
  360. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefReturn */
  361. Aml *aml_return(Aml *val)
  362. {
  363. Aml *var = aml_opcode(0xA4 /* ReturnOp */);
  364. aml_append(var, val);
  365. return var;
  366. }
  367. /* ACPI 1.0b: 16.2.6.3 Debug Objects Encoding: DebugObj */
  368. Aml *aml_debug(void)
  369. {
  370. Aml *var = aml_alloc();
  371. build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
  372. build_append_byte(var->buf, 0x31); /* DebugOp */
  373. return var;
  374. }
  375. /*
  376. * ACPI 1.0b: 16.2.3 Data Objects Encoding:
  377. * encodes: ByteConst, WordConst, DWordConst, QWordConst, ZeroOp, OneOp
  378. */
  379. Aml *aml_int(const uint64_t val)
  380. {
  381. Aml *var = aml_alloc();
  382. build_append_int(var->buf, val);
  383. return var;
  384. }
  385. /*
  386. * helper to construct NameString, which returns Aml object
  387. * for using with aml_append or other aml_* terms
  388. */
  389. Aml *aml_name(const char *name_format, ...)
  390. {
  391. va_list ap;
  392. Aml *var = aml_alloc();
  393. va_start(ap, name_format);
  394. build_append_namestringv(var->buf, name_format, ap);
  395. va_end(ap);
  396. return var;
  397. }
  398. /* ACPI 1.0b: 16.2.5.1 Namespace Modifier Objects Encoding: DefName */
  399. Aml *aml_name_decl(const char *name, Aml *val)
  400. {
  401. Aml *var = aml_opcode(0x08 /* NameOp */);
  402. build_append_namestring(var->buf, "%s", name);
  403. aml_append(var, val);
  404. return var;
  405. }
  406. /* ACPI 1.0b: 16.2.6.1 Arg Objects Encoding */
  407. Aml *aml_arg(int pos)
  408. {
  409. uint8_t op = 0x68 /* ARG0 op */ + pos;
  410. assert(pos <= 6);
  411. return aml_opcode(op);
  412. }
  413. /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToInteger */
  414. Aml *aml_to_integer(Aml *arg)
  415. {
  416. Aml *var = aml_opcode(0x99 /* ToIntegerOp */);
  417. aml_append(var, arg);
  418. build_append_byte(var->buf, 0x00 /* NullNameOp */);
  419. return var;
  420. }
  421. /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToHexString */
  422. Aml *aml_to_hexstring(Aml *src, Aml *dst)
  423. {
  424. Aml *var = aml_opcode(0x98 /* ToHexStringOp */);
  425. aml_append(var, src);
  426. if (dst) {
  427. aml_append(var, dst);
  428. } else {
  429. build_append_byte(var->buf, 0x00 /* NullNameOp */);
  430. }
  431. return var;
  432. }
  433. /* ACPI 2.0a: 17.2.4.4 Type 2 Opcodes Encoding: DefToBuffer */
  434. Aml *aml_to_buffer(Aml *src, Aml *dst)
  435. {
  436. Aml *var = aml_opcode(0x96 /* ToBufferOp */);
  437. aml_append(var, src);
  438. if (dst) {
  439. aml_append(var, dst);
  440. } else {
  441. build_append_byte(var->buf, 0x00 /* NullNameOp */);
  442. }
  443. return var;
  444. }
  445. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefStore */
  446. Aml *aml_store(Aml *val, Aml *target)
  447. {
  448. Aml *var = aml_opcode(0x70 /* StoreOp */);
  449. aml_append(var, val);
  450. aml_append(var, target);
  451. return var;
  452. }
  453. /**
  454. * build_opcode_2arg_dst:
  455. * @op: 1-byte opcode
  456. * @arg1: 1st operand
  457. * @arg2: 2nd operand
  458. * @dst: optional target to store to, set to NULL if it's not required
  459. *
  460. * An internal helper to compose AML terms that have
  461. * "Op Operand Operand Target"
  462. * pattern.
  463. *
  464. * Returns: The newly allocated and composed according to patter Aml object.
  465. */
  466. static Aml *
  467. build_opcode_2arg_dst(uint8_t op, Aml *arg1, Aml *arg2, Aml *dst)
  468. {
  469. Aml *var = aml_opcode(op);
  470. aml_append(var, arg1);
  471. aml_append(var, arg2);
  472. if (dst) {
  473. aml_append(var, dst);
  474. } else {
  475. build_append_byte(var->buf, 0x00 /* NullNameOp */);
  476. }
  477. return var;
  478. }
  479. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAnd */
  480. Aml *aml_and(Aml *arg1, Aml *arg2, Aml *dst)
  481. {
  482. return build_opcode_2arg_dst(0x7B /* AndOp */, arg1, arg2, dst);
  483. }
  484. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefOr */
  485. Aml *aml_or(Aml *arg1, Aml *arg2, Aml *dst)
  486. {
  487. return build_opcode_2arg_dst(0x7D /* OrOp */, arg1, arg2, dst);
  488. }
  489. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLAnd */
  490. Aml *aml_land(Aml *arg1, Aml *arg2)
  491. {
  492. Aml *var = aml_opcode(0x90 /* LAndOp */);
  493. aml_append(var, arg1);
  494. aml_append(var, arg2);
  495. return var;
  496. }
  497. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLOr */
  498. Aml *aml_lor(Aml *arg1, Aml *arg2)
  499. {
  500. Aml *var = aml_opcode(0x91 /* LOrOp */);
  501. aml_append(var, arg1);
  502. aml_append(var, arg2);
  503. return var;
  504. }
  505. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftLeft */
  506. Aml *aml_shiftleft(Aml *arg1, Aml *count)
  507. {
  508. return build_opcode_2arg_dst(0x79 /* ShiftLeftOp */, arg1, count, NULL);
  509. }
  510. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefShiftRight */
  511. Aml *aml_shiftright(Aml *arg1, Aml *count, Aml *dst)
  512. {
  513. return build_opcode_2arg_dst(0x7A /* ShiftRightOp */, arg1, count, dst);
  514. }
  515. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLLess */
  516. Aml *aml_lless(Aml *arg1, Aml *arg2)
  517. {
  518. Aml *var = aml_opcode(0x95 /* LLessOp */);
  519. aml_append(var, arg1);
  520. aml_append(var, arg2);
  521. return var;
  522. }
  523. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAdd */
  524. Aml *aml_add(Aml *arg1, Aml *arg2, Aml *dst)
  525. {
  526. return build_opcode_2arg_dst(0x72 /* AddOp */, arg1, arg2, dst);
  527. }
  528. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSubtract */
  529. Aml *aml_subtract(Aml *arg1, Aml *arg2, Aml *dst)
  530. {
  531. return build_opcode_2arg_dst(0x74 /* SubtractOp */, arg1, arg2, dst);
  532. }
  533. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIncrement */
  534. Aml *aml_increment(Aml *arg)
  535. {
  536. Aml *var = aml_opcode(0x75 /* IncrementOp */);
  537. aml_append(var, arg);
  538. return var;
  539. }
  540. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDecrement */
  541. Aml *aml_decrement(Aml *arg)
  542. {
  543. Aml *var = aml_opcode(0x76 /* DecrementOp */);
  544. aml_append(var, arg);
  545. return var;
  546. }
  547. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefIndex */
  548. Aml *aml_index(Aml *arg1, Aml *idx)
  549. {
  550. return build_opcode_2arg_dst(0x88 /* IndexOp */, arg1, idx, NULL);
  551. }
  552. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefNotify */
  553. Aml *aml_notify(Aml *arg1, Aml *arg2)
  554. {
  555. Aml *var = aml_opcode(0x86 /* NotifyOp */);
  556. aml_append(var, arg1);
  557. aml_append(var, arg2);
  558. return var;
  559. }
  560. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefBreak */
  561. Aml *aml_break(void)
  562. {
  563. Aml *var = aml_opcode(0xa5 /* BreakOp */);
  564. return var;
  565. }
  566. /* helper to call method without argument */
  567. Aml *aml_call0(const char *method)
  568. {
  569. Aml *var = aml_alloc();
  570. build_append_namestring(var->buf, "%s", method);
  571. return var;
  572. }
  573. /* helper to call method with 1 argument */
  574. Aml *aml_call1(const char *method, Aml *arg1)
  575. {
  576. Aml *var = aml_alloc();
  577. build_append_namestring(var->buf, "%s", method);
  578. aml_append(var, arg1);
  579. return var;
  580. }
  581. /* helper to call method with 2 arguments */
  582. Aml *aml_call2(const char *method, Aml *arg1, Aml *arg2)
  583. {
  584. Aml *var = aml_alloc();
  585. build_append_namestring(var->buf, "%s", method);
  586. aml_append(var, arg1);
  587. aml_append(var, arg2);
  588. return var;
  589. }
  590. /* helper to call method with 3 arguments */
  591. Aml *aml_call3(const char *method, Aml *arg1, Aml *arg2, Aml *arg3)
  592. {
  593. Aml *var = aml_alloc();
  594. build_append_namestring(var->buf, "%s", method);
  595. aml_append(var, arg1);
  596. aml_append(var, arg2);
  597. aml_append(var, arg3);
  598. return var;
  599. }
  600. /* helper to call method with 4 arguments */
  601. Aml *aml_call4(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4)
  602. {
  603. Aml *var = aml_alloc();
  604. build_append_namestring(var->buf, "%s", method);
  605. aml_append(var, arg1);
  606. aml_append(var, arg2);
  607. aml_append(var, arg3);
  608. aml_append(var, arg4);
  609. return var;
  610. }
  611. /* helper to call method with 5 arguments */
  612. Aml *aml_call5(const char *method, Aml *arg1, Aml *arg2, Aml *arg3, Aml *arg4,
  613. Aml *arg5)
  614. {
  615. Aml *var = aml_alloc();
  616. build_append_namestring(var->buf, "%s", method);
  617. aml_append(var, arg1);
  618. aml_append(var, arg2);
  619. aml_append(var, arg3);
  620. aml_append(var, arg4);
  621. aml_append(var, arg5);
  622. return var;
  623. }
  624. /*
  625. * ACPI 5.0: 6.4.3.8.1 GPIO Connection Descriptor
  626. * Type 1, Large Item Name 0xC
  627. */
  628. static Aml *aml_gpio_connection(AmlGpioConnectionType type,
  629. AmlConsumerAndProducer con_and_pro,
  630. uint8_t flags, AmlPinConfig pin_config,
  631. uint16_t output_drive,
  632. uint16_t debounce_timeout,
  633. const uint32_t pin_list[], uint32_t pin_count,
  634. const char *resource_source_name,
  635. const uint8_t *vendor_data,
  636. uint16_t vendor_data_len)
  637. {
  638. Aml *var = aml_alloc();
  639. const uint16_t min_desc_len = 0x16;
  640. uint16_t resource_source_name_len, length;
  641. uint16_t pin_table_offset, resource_source_name_offset, vendor_data_offset;
  642. uint32_t i;
  643. assert(resource_source_name);
  644. resource_source_name_len = strlen(resource_source_name) + 1;
  645. length = min_desc_len + resource_source_name_len + vendor_data_len;
  646. pin_table_offset = min_desc_len + 1;
  647. resource_source_name_offset = pin_table_offset + pin_count * 2;
  648. vendor_data_offset = resource_source_name_offset + resource_source_name_len;
  649. build_append_byte(var->buf, 0x8C); /* GPIO Connection Descriptor */
  650. build_append_int_noprefix(var->buf, length, 2); /* Length */
  651. build_append_byte(var->buf, 1); /* Revision ID */
  652. build_append_byte(var->buf, type); /* GPIO Connection Type */
  653. /* General Flags (2 bytes) */
  654. build_append_int_noprefix(var->buf, con_and_pro, 2);
  655. /* Interrupt and IO Flags (2 bytes) */
  656. build_append_int_noprefix(var->buf, flags, 2);
  657. /* Pin Configuration 0 = Default 1 = Pull-up 2 = Pull-down 3 = No Pull */
  658. build_append_byte(var->buf, pin_config);
  659. /* Output Drive Strength (2 bytes) */
  660. build_append_int_noprefix(var->buf, output_drive, 2);
  661. /* Debounce Timeout (2 bytes) */
  662. build_append_int_noprefix(var->buf, debounce_timeout, 2);
  663. /* Pin Table Offset (2 bytes) */
  664. build_append_int_noprefix(var->buf, pin_table_offset, 2);
  665. build_append_byte(var->buf, 0); /* Resource Source Index */
  666. /* Resource Source Name Offset (2 bytes) */
  667. build_append_int_noprefix(var->buf, resource_source_name_offset, 2);
  668. /* Vendor Data Offset (2 bytes) */
  669. build_append_int_noprefix(var->buf, vendor_data_offset, 2);
  670. /* Vendor Data Length (2 bytes) */
  671. build_append_int_noprefix(var->buf, vendor_data_len, 2);
  672. /* Pin Number (2n bytes)*/
  673. for (i = 0; i < pin_count; i++) {
  674. build_append_int_noprefix(var->buf, pin_list[i], 2);
  675. }
  676. /* Resource Source Name */
  677. build_append_namestring(var->buf, "%s", resource_source_name);
  678. build_append_byte(var->buf, '\0');
  679. /* Vendor-defined Data */
  680. if (vendor_data != NULL) {
  681. g_array_append_vals(var->buf, vendor_data, vendor_data_len);
  682. }
  683. return var;
  684. }
  685. /*
  686. * ACPI 5.0: 19.5.53
  687. * GpioInt(GPIO Interrupt Connection Resource Descriptor Macro)
  688. */
  689. Aml *aml_gpio_int(AmlConsumerAndProducer con_and_pro,
  690. AmlLevelAndEdge edge_level,
  691. AmlActiveHighAndLow active_level, AmlShared shared,
  692. AmlPinConfig pin_config, uint16_t debounce_timeout,
  693. const uint32_t pin_list[], uint32_t pin_count,
  694. const char *resource_source_name,
  695. const uint8_t *vendor_data, uint16_t vendor_data_len)
  696. {
  697. uint8_t flags = edge_level | (active_level << 1) | (shared << 3);
  698. return aml_gpio_connection(AML_INTERRUPT_CONNECTION, con_and_pro, flags,
  699. pin_config, 0, debounce_timeout, pin_list,
  700. pin_count, resource_source_name, vendor_data,
  701. vendor_data_len);
  702. }
  703. /*
  704. * ACPI 1.0b: 6.4.3.4 32-Bit Fixed Location Memory Range Descriptor
  705. * (Type 1, Large Item Name 0x6)
  706. */
  707. Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
  708. AmlReadAndWrite read_and_write)
  709. {
  710. Aml *var = aml_alloc();
  711. build_append_byte(var->buf, 0x86); /* Memory32Fixed Resource Descriptor */
  712. build_append_byte(var->buf, 9); /* Length, bits[7:0] value = 9 */
  713. build_append_byte(var->buf, 0); /* Length, bits[15:8] value = 0 */
  714. build_append_byte(var->buf, read_and_write); /* Write status, 1 rw 0 ro */
  715. /* Range base address */
  716. build_append_byte(var->buf, extract32(addr, 0, 8)); /* bits[7:0] */
  717. build_append_byte(var->buf, extract32(addr, 8, 8)); /* bits[15:8] */
  718. build_append_byte(var->buf, extract32(addr, 16, 8)); /* bits[23:16] */
  719. build_append_byte(var->buf, extract32(addr, 24, 8)); /* bits[31:24] */
  720. /* Range length */
  721. build_append_byte(var->buf, extract32(size, 0, 8)); /* bits[7:0] */
  722. build_append_byte(var->buf, extract32(size, 8, 8)); /* bits[15:8] */
  723. build_append_byte(var->buf, extract32(size, 16, 8)); /* bits[23:16] */
  724. build_append_byte(var->buf, extract32(size, 24, 8)); /* bits[31:24] */
  725. return var;
  726. }
  727. /*
  728. * ACPI 5.0: 6.4.3.6 Extended Interrupt Descriptor
  729. * Type 1, Large Item Name 0x9
  730. */
  731. Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
  732. AmlLevelAndEdge level_and_edge,
  733. AmlActiveHighAndLow high_and_low, AmlShared shared,
  734. uint32_t *irq_list, uint8_t irq_count)
  735. {
  736. int i;
  737. Aml *var = aml_alloc();
  738. uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
  739. | (high_and_low << 2) | (shared << 3);
  740. const int header_bytes_in_len = 2;
  741. uint16_t len = header_bytes_in_len + irq_count * sizeof(uint32_t);
  742. assert(irq_count > 0);
  743. build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
  744. build_append_byte(var->buf, len & 0xFF); /* Length, bits[7:0] */
  745. build_append_byte(var->buf, len >> 8); /* Length, bits[15:8] */
  746. build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
  747. build_append_byte(var->buf, irq_count); /* Interrupt table length */
  748. /* Interrupt Number List */
  749. for (i = 0; i < irq_count; i++) {
  750. build_append_int_noprefix(var->buf, irq_list[i], 4);
  751. }
  752. return var;
  753. }
  754. /* ACPI 1.0b: 6.4.2.5 I/O Port Descriptor */
  755. Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
  756. uint8_t aln, uint8_t len)
  757. {
  758. Aml *var = aml_alloc();
  759. build_append_byte(var->buf, 0x47); /* IO port descriptor */
  760. build_append_byte(var->buf, dec);
  761. build_append_byte(var->buf, min_base & 0xff);
  762. build_append_byte(var->buf, (min_base >> 8) & 0xff);
  763. build_append_byte(var->buf, max_base & 0xff);
  764. build_append_byte(var->buf, (max_base >> 8) & 0xff);
  765. build_append_byte(var->buf, aln);
  766. build_append_byte(var->buf, len);
  767. return var;
  768. }
  769. /*
  770. * ACPI 1.0b: 6.4.2.1.1 ASL Macro for IRQ Descriptor
  771. *
  772. * More verbose description at:
  773. * ACPI 5.0: 19.5.64 IRQNoFlags (Interrupt Resource Descriptor Macro)
  774. * 6.4.2.1 IRQ Descriptor
  775. */
  776. Aml *aml_irq_no_flags(uint8_t irq)
  777. {
  778. uint16_t irq_mask;
  779. Aml *var = aml_alloc();
  780. assert(irq < 16);
  781. build_append_byte(var->buf, 0x22); /* IRQ descriptor 2 byte form */
  782. irq_mask = 1U << irq;
  783. build_append_byte(var->buf, irq_mask & 0xFF); /* IRQ mask bits[7:0] */
  784. build_append_byte(var->buf, irq_mask >> 8); /* IRQ mask bits[15:8] */
  785. return var;
  786. }
  787. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLNot */
  788. Aml *aml_lnot(Aml *arg)
  789. {
  790. Aml *var = aml_opcode(0x92 /* LNotOp */);
  791. aml_append(var, arg);
  792. return var;
  793. }
  794. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLEqual */
  795. Aml *aml_equal(Aml *arg1, Aml *arg2)
  796. {
  797. Aml *var = aml_opcode(0x93 /* LequalOp */);
  798. aml_append(var, arg1);
  799. aml_append(var, arg2);
  800. return var;
  801. }
  802. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreater */
  803. Aml *aml_lgreater(Aml *arg1, Aml *arg2)
  804. {
  805. Aml *var = aml_opcode(0x94 /* LGreaterOp */);
  806. aml_append(var, arg1);
  807. aml_append(var, arg2);
  808. return var;
  809. }
  810. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefLGreaterEqual */
  811. Aml *aml_lgreater_equal(Aml *arg1, Aml *arg2)
  812. {
  813. /* LGreaterEqualOp := LNotOp LLessOp */
  814. Aml *var = aml_opcode(0x92 /* LNotOp */);
  815. build_append_byte(var->buf, 0x95 /* LLessOp */);
  816. aml_append(var, arg1);
  817. aml_append(var, arg2);
  818. return var;
  819. }
  820. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefIfElse */
  821. Aml *aml_if(Aml *predicate)
  822. {
  823. Aml *var = aml_bundle(0xA0 /* IfOp */, AML_PACKAGE);
  824. aml_append(var, predicate);
  825. return var;
  826. }
  827. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefElse */
  828. Aml *aml_else(void)
  829. {
  830. Aml *var = aml_bundle(0xA1 /* ElseOp */, AML_PACKAGE);
  831. return var;
  832. }
  833. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefWhile */
  834. Aml *aml_while(Aml *predicate)
  835. {
  836. Aml *var = aml_bundle(0xA2 /* WhileOp */, AML_PACKAGE);
  837. aml_append(var, predicate);
  838. return var;
  839. }
  840. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMethod */
  841. Aml *aml_method(const char *name, int arg_count, AmlSerializeFlag sflag)
  842. {
  843. Aml *var = aml_bundle(0x14 /* MethodOp */, AML_PACKAGE);
  844. int methodflags;
  845. /*
  846. * MethodFlags:
  847. * bit 0-2: ArgCount (0-7)
  848. * bit 3: SerializeFlag
  849. * 0: NotSerialized
  850. * 1: Serialized
  851. * bit 4-7: reserved (must be 0)
  852. */
  853. assert(arg_count < 8);
  854. methodflags = arg_count | (sflag << 3);
  855. build_append_namestring(var->buf, "%s", name);
  856. build_append_byte(var->buf, methodflags); /* MethodFlags: ArgCount */
  857. return var;
  858. }
  859. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefDevice */
  860. Aml *aml_device(const char *name_format, ...)
  861. {
  862. va_list ap;
  863. Aml *var = aml_bundle(0x82 /* DeviceOp */, AML_EXT_PACKAGE);
  864. va_start(ap, name_format);
  865. build_append_namestringv(var->buf, name_format, ap);
  866. va_end(ap);
  867. return var;
  868. }
  869. /* ACPI 1.0b: 6.4.1 ASL Macros for Resource Descriptors */
  870. Aml *aml_resource_template(void)
  871. {
  872. /* ResourceTemplate is a buffer of Resources with EndTag at the end */
  873. Aml *var = aml_bundle(0x11 /* BufferOp */, AML_RES_TEMPLATE);
  874. return var;
  875. }
  876. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefBuffer
  877. * Pass byte_list as NULL to request uninitialized buffer to reserve space.
  878. */
  879. Aml *aml_buffer(int buffer_size, uint8_t *byte_list)
  880. {
  881. int i;
  882. Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
  883. for (i = 0; i < buffer_size; i++) {
  884. if (byte_list == NULL) {
  885. build_append_byte(var->buf, 0x0);
  886. } else {
  887. build_append_byte(var->buf, byte_list[i]);
  888. }
  889. }
  890. return var;
  891. }
  892. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefPackage */
  893. Aml *aml_package(uint8_t num_elements)
  894. {
  895. Aml *var = aml_bundle(0x12 /* PackageOp */, AML_PACKAGE);
  896. build_append_byte(var->buf, num_elements);
  897. return var;
  898. }
  899. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefOpRegion */
  900. Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
  901. Aml *offset, uint32_t len)
  902. {
  903. Aml *var = aml_alloc();
  904. build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
  905. build_append_byte(var->buf, 0x80); /* OpRegionOp */
  906. build_append_namestring(var->buf, "%s", name);
  907. build_append_byte(var->buf, rs);
  908. aml_append(var, offset);
  909. build_append_int(var->buf, len);
  910. return var;
  911. }
  912. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: NamedField */
  913. Aml *aml_named_field(const char *name, unsigned length)
  914. {
  915. Aml *var = aml_alloc();
  916. build_append_nameseg(var->buf, name);
  917. build_append_pkg_length(var->buf, length, false);
  918. return var;
  919. }
  920. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: ReservedField */
  921. Aml *aml_reserved_field(unsigned length)
  922. {
  923. Aml *var = aml_alloc();
  924. /* ReservedField := 0x00 PkgLength */
  925. build_append_byte(var->buf, 0x00);
  926. build_append_pkg_length(var->buf, length, false);
  927. return var;
  928. }
  929. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefField */
  930. Aml *aml_field(const char *name, AmlAccessType type, AmlLockRule lock,
  931. AmlUpdateRule rule)
  932. {
  933. Aml *var = aml_bundle(0x81 /* FieldOp */, AML_EXT_PACKAGE);
  934. uint8_t flags = rule << 5 | type;
  935. flags |= lock << 4; /* LockRule at 4 bit offset */
  936. build_append_namestring(var->buf, "%s", name);
  937. build_append_byte(var->buf, flags);
  938. return var;
  939. }
  940. static
  941. Aml *create_field_common(int opcode, Aml *srcbuf, Aml *index, const char *name)
  942. {
  943. Aml *var = aml_opcode(opcode);
  944. aml_append(var, srcbuf);
  945. aml_append(var, index);
  946. build_append_namestring(var->buf, "%s", name);
  947. return var;
  948. }
  949. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateField */
  950. Aml *aml_create_field(Aml *srcbuf, Aml *bit_index, Aml *num_bits,
  951. const char *name)
  952. {
  953. Aml *var = aml_alloc();
  954. build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
  955. build_append_byte(var->buf, 0x13); /* CreateFieldOp */
  956. aml_append(var, srcbuf);
  957. aml_append(var, bit_index);
  958. aml_append(var, num_bits);
  959. build_append_namestring(var->buf, "%s", name);
  960. return var;
  961. }
  962. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefCreateDWordField */
  963. Aml *aml_create_dword_field(Aml *srcbuf, Aml *index, const char *name)
  964. {
  965. return create_field_common(0x8A /* CreateDWordFieldOp */,
  966. srcbuf, index, name);
  967. }
  968. /* ACPI 2.0a: 17.2.4.2 Named Objects Encoding: DefCreateQWordField */
  969. Aml *aml_create_qword_field(Aml *srcbuf, Aml *index, const char *name)
  970. {
  971. return create_field_common(0x8F /* CreateQWordFieldOp */,
  972. srcbuf, index, name);
  973. }
  974. /* ACPI 1.0b: 16.2.3 Data Objects Encoding: String */
  975. Aml *aml_string(const char *name_format, ...)
  976. {
  977. Aml *var = aml_opcode(0x0D /* StringPrefix */);
  978. va_list ap;
  979. char *s;
  980. int len;
  981. va_start(ap, name_format);
  982. len = g_vasprintf(&s, name_format, ap);
  983. va_end(ap);
  984. g_array_append_vals(var->buf, s, len + 1);
  985. g_free(s);
  986. return var;
  987. }
  988. /* ACPI 1.0b: 16.2.6.2 Local Objects Encoding */
  989. Aml *aml_local(int num)
  990. {
  991. uint8_t op = 0x60 /* Local0Op */ + num;
  992. assert(num <= 7);
  993. return aml_opcode(op);
  994. }
  995. /* ACPI 2.0a: 17.2.2 Data Objects Encoding: DefVarPackage */
  996. Aml *aml_varpackage(uint32_t num_elements)
  997. {
  998. Aml *var = aml_bundle(0x13 /* VarPackageOp */, AML_PACKAGE);
  999. build_append_int(var->buf, num_elements);
  1000. return var;
  1001. }
  1002. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefProcessor */
  1003. Aml *aml_processor(uint8_t proc_id, uint32_t pblk_addr, uint8_t pblk_len,
  1004. const char *name_format, ...)
  1005. {
  1006. va_list ap;
  1007. Aml *var = aml_bundle(0x83 /* ProcessorOp */, AML_EXT_PACKAGE);
  1008. va_start(ap, name_format);
  1009. build_append_namestringv(var->buf, name_format, ap);
  1010. va_end(ap);
  1011. build_append_byte(var->buf, proc_id); /* ProcID */
  1012. build_append_int_noprefix(var->buf, pblk_addr, sizeof(pblk_addr));
  1013. build_append_byte(var->buf, pblk_len); /* PblkLen */
  1014. return var;
  1015. }
  1016. static uint8_t Hex2Digit(char c)
  1017. {
  1018. if (c >= 'A') {
  1019. return c - 'A' + 10;
  1020. }
  1021. return c - '0';
  1022. }
  1023. /* ACPI 1.0b: 15.2.3.6.4.1 EISAID Macro - Convert EISA ID String To Integer */
  1024. Aml *aml_eisaid(const char *str)
  1025. {
  1026. Aml *var = aml_alloc();
  1027. uint32_t id;
  1028. g_assert(strlen(str) == 7);
  1029. id = (str[0] - 0x40) << 26 |
  1030. (str[1] - 0x40) << 21 |
  1031. (str[2] - 0x40) << 16 |
  1032. Hex2Digit(str[3]) << 12 |
  1033. Hex2Digit(str[4]) << 8 |
  1034. Hex2Digit(str[5]) << 4 |
  1035. Hex2Digit(str[6]);
  1036. build_append_byte(var->buf, 0x0C); /* DWordPrefix */
  1037. build_append_int_noprefix(var->buf, bswap32(id), sizeof(id));
  1038. return var;
  1039. }
  1040. /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor: bytes 3-5 */
  1041. static Aml *aml_as_desc_header(AmlResourceType type, AmlMinFixed min_fixed,
  1042. AmlMaxFixed max_fixed, AmlDecode dec,
  1043. uint8_t type_flags)
  1044. {
  1045. uint8_t flags = max_fixed | min_fixed | dec;
  1046. Aml *var = aml_alloc();
  1047. build_append_byte(var->buf, type);
  1048. build_append_byte(var->buf, flags);
  1049. build_append_byte(var->buf, type_flags); /* Type Specific Flags */
  1050. return var;
  1051. }
  1052. /* ACPI 1.0b: 6.4.3.5.5 Word Address Space Descriptor */
  1053. static Aml *aml_word_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
  1054. AmlMaxFixed max_fixed, AmlDecode dec,
  1055. uint16_t addr_gran, uint16_t addr_min,
  1056. uint16_t addr_max, uint16_t addr_trans,
  1057. uint16_t len, uint8_t type_flags)
  1058. {
  1059. Aml *var = aml_alloc();
  1060. build_append_byte(var->buf, 0x88); /* Word Address Space Descriptor */
  1061. /* minimum length since we do not encode optional fields */
  1062. build_append_byte(var->buf, 0x0D);
  1063. build_append_byte(var->buf, 0x0);
  1064. aml_append(var,
  1065. aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
  1066. build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
  1067. build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
  1068. build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
  1069. build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
  1070. build_append_int_noprefix(var->buf, len, sizeof(len));
  1071. return var;
  1072. }
  1073. /* ACPI 1.0b: 6.4.3.5.3 DWord Address Space Descriptor */
  1074. static Aml *aml_dword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
  1075. AmlMaxFixed max_fixed, AmlDecode dec,
  1076. uint32_t addr_gran, uint32_t addr_min,
  1077. uint32_t addr_max, uint32_t addr_trans,
  1078. uint32_t len, uint8_t type_flags)
  1079. {
  1080. Aml *var = aml_alloc();
  1081. build_append_byte(var->buf, 0x87); /* DWord Address Space Descriptor */
  1082. /* minimum length since we do not encode optional fields */
  1083. build_append_byte(var->buf, 23);
  1084. build_append_byte(var->buf, 0x0);
  1085. aml_append(var,
  1086. aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
  1087. build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
  1088. build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
  1089. build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
  1090. build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
  1091. build_append_int_noprefix(var->buf, len, sizeof(len));
  1092. return var;
  1093. }
  1094. /* ACPI 1.0b: 6.4.3.5.1 QWord Address Space Descriptor */
  1095. static Aml *aml_qword_as_desc(AmlResourceType type, AmlMinFixed min_fixed,
  1096. AmlMaxFixed max_fixed, AmlDecode dec,
  1097. uint64_t addr_gran, uint64_t addr_min,
  1098. uint64_t addr_max, uint64_t addr_trans,
  1099. uint64_t len, uint8_t type_flags)
  1100. {
  1101. Aml *var = aml_alloc();
  1102. build_append_byte(var->buf, 0x8A); /* QWord Address Space Descriptor */
  1103. /* minimum length since we do not encode optional fields */
  1104. build_append_byte(var->buf, 0x2B);
  1105. build_append_byte(var->buf, 0x0);
  1106. aml_append(var,
  1107. aml_as_desc_header(type, min_fixed, max_fixed, dec, type_flags));
  1108. build_append_int_noprefix(var->buf, addr_gran, sizeof(addr_gran));
  1109. build_append_int_noprefix(var->buf, addr_min, sizeof(addr_min));
  1110. build_append_int_noprefix(var->buf, addr_max, sizeof(addr_max));
  1111. build_append_int_noprefix(var->buf, addr_trans, sizeof(addr_trans));
  1112. build_append_int_noprefix(var->buf, len, sizeof(len));
  1113. return var;
  1114. }
  1115. /*
  1116. * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
  1117. *
  1118. * More verbose description at:
  1119. * ACPI 5.0: 19.5.141 WordBusNumber (Word Bus Number Resource Descriptor Macro)
  1120. */
  1121. Aml *aml_word_bus_number(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
  1122. AmlDecode dec, uint16_t addr_gran,
  1123. uint16_t addr_min, uint16_t addr_max,
  1124. uint16_t addr_trans, uint16_t len)
  1125. {
  1126. return aml_word_as_desc(AML_BUS_NUMBER_RANGE, min_fixed, max_fixed, dec,
  1127. addr_gran, addr_min, addr_max, addr_trans, len, 0);
  1128. }
  1129. /*
  1130. * ACPI 1.0b: 6.4.3.5.6 ASL Macros for WORD Address Descriptor
  1131. *
  1132. * More verbose description at:
  1133. * ACPI 5.0: 19.5.142 WordIO (Word IO Resource Descriptor Macro)
  1134. */
  1135. Aml *aml_word_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
  1136. AmlDecode dec, AmlISARanges isa_ranges,
  1137. uint16_t addr_gran, uint16_t addr_min,
  1138. uint16_t addr_max, uint16_t addr_trans,
  1139. uint16_t len)
  1140. {
  1141. return aml_word_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
  1142. addr_gran, addr_min, addr_max, addr_trans, len,
  1143. isa_ranges);
  1144. }
  1145. /*
  1146. * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Descriptor
  1147. *
  1148. * More verbose description at:
  1149. * ACPI 5.0: 19.5.33 DWordIO (DWord IO Resource Descriptor Macro)
  1150. */
  1151. Aml *aml_dword_io(AmlMinFixed min_fixed, AmlMaxFixed max_fixed,
  1152. AmlDecode dec, AmlISARanges isa_ranges,
  1153. uint32_t addr_gran, uint32_t addr_min,
  1154. uint32_t addr_max, uint32_t addr_trans,
  1155. uint32_t len)
  1156. {
  1157. return aml_dword_as_desc(AML_IO_RANGE, min_fixed, max_fixed, dec,
  1158. addr_gran, addr_min, addr_max, addr_trans, len,
  1159. isa_ranges);
  1160. }
  1161. /*
  1162. * ACPI 1.0b: 6.4.3.5.4 ASL Macros for DWORD Address Space Descriptor
  1163. *
  1164. * More verbose description at:
  1165. * ACPI 5.0: 19.5.34 DWordMemory (DWord Memory Resource Descriptor Macro)
  1166. */
  1167. Aml *aml_dword_memory(AmlDecode dec, AmlMinFixed min_fixed,
  1168. AmlMaxFixed max_fixed, AmlCacheable cacheable,
  1169. AmlReadAndWrite read_and_write,
  1170. uint32_t addr_gran, uint32_t addr_min,
  1171. uint32_t addr_max, uint32_t addr_trans,
  1172. uint32_t len)
  1173. {
  1174. uint8_t flags = read_and_write | (cacheable << 1);
  1175. return aml_dword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
  1176. dec, addr_gran, addr_min, addr_max,
  1177. addr_trans, len, flags);
  1178. }
  1179. /*
  1180. * ACPI 1.0b: 6.4.3.5.2 ASL Macros for QWORD Address Space Descriptor
  1181. *
  1182. * More verbose description at:
  1183. * ACPI 5.0: 19.5.102 QWordMemory (QWord Memory Resource Descriptor Macro)
  1184. */
  1185. Aml *aml_qword_memory(AmlDecode dec, AmlMinFixed min_fixed,
  1186. AmlMaxFixed max_fixed, AmlCacheable cacheable,
  1187. AmlReadAndWrite read_and_write,
  1188. uint64_t addr_gran, uint64_t addr_min,
  1189. uint64_t addr_max, uint64_t addr_trans,
  1190. uint64_t len)
  1191. {
  1192. uint8_t flags = read_and_write | (cacheable << 1);
  1193. return aml_qword_as_desc(AML_MEMORY_RANGE, min_fixed, max_fixed,
  1194. dec, addr_gran, addr_min, addr_max,
  1195. addr_trans, len, flags);
  1196. }
  1197. /* ACPI 1.0b: 6.4.2.2 DMA Format/6.4.2.2.1 ASL Macro for DMA Descriptor */
  1198. Aml *aml_dma(AmlDmaType typ, AmlDmaBusMaster bm, AmlTransferSize sz,
  1199. uint8_t channel)
  1200. {
  1201. Aml *var = aml_alloc();
  1202. uint8_t flags = sz | bm << 2 | typ << 5;
  1203. assert(channel < 8);
  1204. build_append_byte(var->buf, 0x2A); /* Byte 0: DMA Descriptor */
  1205. build_append_byte(var->buf, 1U << channel); /* Byte 1: _DMA - DmaChannel */
  1206. build_append_byte(var->buf, flags); /* Byte 2 */
  1207. return var;
  1208. }
  1209. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefSleep */
  1210. Aml *aml_sleep(uint64_t msec)
  1211. {
  1212. Aml *var = aml_alloc();
  1213. build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
  1214. build_append_byte(var->buf, 0x22); /* SleepOp */
  1215. aml_append(var, aml_int(msec));
  1216. return var;
  1217. }
  1218. static uint8_t Hex2Byte(const char *src)
  1219. {
  1220. int hi, lo;
  1221. hi = Hex2Digit(src[0]);
  1222. assert(hi >= 0);
  1223. assert(hi <= 15);
  1224. lo = Hex2Digit(src[1]);
  1225. assert(lo >= 0);
  1226. assert(lo <= 15);
  1227. return (hi << 4) | lo;
  1228. }
  1229. /*
  1230. * ACPI 3.0: 17.5.124 ToUUID (Convert String to UUID Macro)
  1231. * e.g. UUID: aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
  1232. * call aml_touuid("aabbccdd-eeff-gghh-iijj-kkllmmnnoopp");
  1233. */
  1234. Aml *aml_touuid(const char *uuid)
  1235. {
  1236. Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
  1237. assert(strlen(uuid) == 36);
  1238. assert(uuid[8] == '-');
  1239. assert(uuid[13] == '-');
  1240. assert(uuid[18] == '-');
  1241. assert(uuid[23] == '-');
  1242. build_append_byte(var->buf, Hex2Byte(uuid + 6)); /* dd - at offset 00 */
  1243. build_append_byte(var->buf, Hex2Byte(uuid + 4)); /* cc - at offset 01 */
  1244. build_append_byte(var->buf, Hex2Byte(uuid + 2)); /* bb - at offset 02 */
  1245. build_append_byte(var->buf, Hex2Byte(uuid + 0)); /* aa - at offset 03 */
  1246. build_append_byte(var->buf, Hex2Byte(uuid + 11)); /* ff - at offset 04 */
  1247. build_append_byte(var->buf, Hex2Byte(uuid + 9)); /* ee - at offset 05 */
  1248. build_append_byte(var->buf, Hex2Byte(uuid + 16)); /* hh - at offset 06 */
  1249. build_append_byte(var->buf, Hex2Byte(uuid + 14)); /* gg - at offset 07 */
  1250. build_append_byte(var->buf, Hex2Byte(uuid + 19)); /* ii - at offset 08 */
  1251. build_append_byte(var->buf, Hex2Byte(uuid + 21)); /* jj - at offset 09 */
  1252. build_append_byte(var->buf, Hex2Byte(uuid + 24)); /* kk - at offset 10 */
  1253. build_append_byte(var->buf, Hex2Byte(uuid + 26)); /* ll - at offset 11 */
  1254. build_append_byte(var->buf, Hex2Byte(uuid + 28)); /* mm - at offset 12 */
  1255. build_append_byte(var->buf, Hex2Byte(uuid + 30)); /* nn - at offset 13 */
  1256. build_append_byte(var->buf, Hex2Byte(uuid + 32)); /* oo - at offset 14 */
  1257. build_append_byte(var->buf, Hex2Byte(uuid + 34)); /* pp - at offset 15 */
  1258. return var;
  1259. }
  1260. /*
  1261. * ACPI 2.0b: 16.2.3.6.4.3 Unicode Macro (Convert Ascii String To Unicode)
  1262. */
  1263. Aml *aml_unicode(const char *str)
  1264. {
  1265. int i = 0;
  1266. Aml *var = aml_bundle(0x11 /* BufferOp */, AML_BUFFER);
  1267. do {
  1268. build_append_byte(var->buf, str[i]);
  1269. build_append_byte(var->buf, 0);
  1270. i++;
  1271. } while (i <= strlen(str));
  1272. return var;
  1273. }
  1274. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefRefOf */
  1275. Aml *aml_refof(Aml *arg)
  1276. {
  1277. Aml *var = aml_opcode(0x71 /* RefOfOp */);
  1278. aml_append(var, arg);
  1279. return var;
  1280. }
  1281. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefDerefOf */
  1282. Aml *aml_derefof(Aml *arg)
  1283. {
  1284. Aml *var = aml_opcode(0x83 /* DerefOfOp */);
  1285. aml_append(var, arg);
  1286. return var;
  1287. }
  1288. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefSizeOf */
  1289. Aml *aml_sizeof(Aml *arg)
  1290. {
  1291. Aml *var = aml_opcode(0x87 /* SizeOfOp */);
  1292. aml_append(var, arg);
  1293. return var;
  1294. }
  1295. /* ACPI 1.0b: 16.2.5.2 Named Objects Encoding: DefMutex */
  1296. Aml *aml_mutex(const char *name, uint8_t sync_level)
  1297. {
  1298. Aml *var = aml_alloc();
  1299. build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
  1300. build_append_byte(var->buf, 0x01); /* MutexOp */
  1301. build_append_namestring(var->buf, "%s", name);
  1302. assert(!(sync_level & 0xF0));
  1303. build_append_byte(var->buf, sync_level);
  1304. return var;
  1305. }
  1306. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefAcquire */
  1307. Aml *aml_acquire(Aml *mutex, uint16_t timeout)
  1308. {
  1309. Aml *var = aml_alloc();
  1310. build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
  1311. build_append_byte(var->buf, 0x23); /* AcquireOp */
  1312. aml_append(var, mutex);
  1313. build_append_int_noprefix(var->buf, timeout, sizeof(timeout));
  1314. return var;
  1315. }
  1316. /* ACPI 1.0b: 16.2.5.3 Type 1 Opcodes Encoding: DefRelease */
  1317. Aml *aml_release(Aml *mutex)
  1318. {
  1319. Aml *var = aml_alloc();
  1320. build_append_byte(var->buf, 0x5B); /* ExtOpPrefix */
  1321. build_append_byte(var->buf, 0x27); /* ReleaseOp */
  1322. aml_append(var, mutex);
  1323. return var;
  1324. }
  1325. /* ACPI 1.0b: 16.2.5.1 Name Space Modifier Objects Encoding: DefAlias */
  1326. Aml *aml_alias(const char *source_object, const char *alias_object)
  1327. {
  1328. Aml *var = aml_opcode(0x06 /* AliasOp */);
  1329. aml_append(var, aml_name("%s", source_object));
  1330. aml_append(var, aml_name("%s", alias_object));
  1331. return var;
  1332. }
  1333. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefConcat */
  1334. Aml *aml_concatenate(Aml *source1, Aml *source2, Aml *target)
  1335. {
  1336. return build_opcode_2arg_dst(0x73 /* ConcatOp */, source1, source2,
  1337. target);
  1338. }
  1339. /* ACPI 1.0b: 16.2.5.4 Type 2 Opcodes Encoding: DefObjectType */
  1340. Aml *aml_object_type(Aml *object)
  1341. {
  1342. Aml *var = aml_opcode(0x8E /* ObjectTypeOp */);
  1343. aml_append(var, object);
  1344. return var;
  1345. }
  1346. void
  1347. build_header(BIOSLinker *linker, GArray *table_data,
  1348. AcpiTableHeader *h, const char *sig, int len, uint8_t rev,
  1349. const char *oem_id, const char *oem_table_id)
  1350. {
  1351. unsigned tbl_offset = (char *)h - table_data->data;
  1352. unsigned checksum_offset = (char *)&h->checksum - table_data->data;
  1353. memcpy(&h->signature, sig, 4);
  1354. h->length = cpu_to_le32(len);
  1355. h->revision = rev;
  1356. if (oem_id) {
  1357. strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);
  1358. } else {
  1359. memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
  1360. }
  1361. if (oem_table_id) {
  1362. strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));
  1363. } else {
  1364. memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
  1365. memcpy(h->oem_table_id + 4, sig, 4);
  1366. }
  1367. h->oem_revision = cpu_to_le32(1);
  1368. memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
  1369. h->asl_compiler_revision = cpu_to_le32(1);
  1370. /* Checksum to be filled in by Guest linker */
  1371. bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
  1372. tbl_offset, len, checksum_offset);
  1373. }
  1374. void *acpi_data_push(GArray *table_data, unsigned size)
  1375. {
  1376. unsigned off = table_data->len;
  1377. g_array_set_size(table_data, off + size);
  1378. return table_data->data + off;
  1379. }
  1380. unsigned acpi_data_len(GArray *table)
  1381. {
  1382. assert(g_array_get_element_size(table) == 1);
  1383. return table->len;
  1384. }
  1385. void acpi_add_table(GArray *table_offsets, GArray *table_data)
  1386. {
  1387. uint32_t offset = table_data->len;
  1388. g_array_append_val(table_offsets, offset);
  1389. }
  1390. void acpi_build_tables_init(AcpiBuildTables *tables)
  1391. {
  1392. tables->rsdp = g_array_new(false, true /* clear */, 1);
  1393. tables->table_data = g_array_new(false, true /* clear */, 1);
  1394. tables->tcpalog = g_array_new(false, true /* clear */, 1);
  1395. tables->vmgenid = g_array_new(false, true /* clear */, 1);
  1396. tables->hardware_errors = g_array_new(false, true /* clear */, 1);
  1397. tables->linker = bios_linker_loader_init();
  1398. }
  1399. void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
  1400. {
  1401. bios_linker_loader_cleanup(tables->linker);
  1402. g_array_free(tables->rsdp, true);
  1403. g_array_free(tables->table_data, true);
  1404. g_array_free(tables->tcpalog, mfre);
  1405. g_array_free(tables->vmgenid, mfre);
  1406. g_array_free(tables->hardware_errors, mfre);
  1407. }
  1408. /*
  1409. * ACPI spec 5.2.5.3 Root System Description Pointer (RSDP).
  1410. * (Revision 1.0 or later)
  1411. */
  1412. void
  1413. build_rsdp(GArray *tbl, BIOSLinker *linker, AcpiRsdpData *rsdp_data)
  1414. {
  1415. int tbl_off = tbl->len; /* Table offset in the RSDP file */
  1416. switch (rsdp_data->revision) {
  1417. case 0:
  1418. /* With ACPI 1.0, we must have an RSDT pointer */
  1419. g_assert(rsdp_data->rsdt_tbl_offset);
  1420. break;
  1421. case 2:
  1422. /* With ACPI 2.0+, we must have an XSDT pointer */
  1423. g_assert(rsdp_data->xsdt_tbl_offset);
  1424. break;
  1425. default:
  1426. /* Only revisions 0 (ACPI 1.0) and 2 (ACPI 2.0+) are valid for RSDP */
  1427. g_assert_not_reached();
  1428. }
  1429. bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, tbl, 16,
  1430. true /* fseg memory */);
  1431. g_array_append_vals(tbl, "RSD PTR ", 8); /* Signature */
  1432. build_append_int_noprefix(tbl, 0, 1); /* Checksum */
  1433. g_array_append_vals(tbl, rsdp_data->oem_id, 6); /* OEMID */
  1434. build_append_int_noprefix(tbl, rsdp_data->revision, 1); /* Revision */
  1435. build_append_int_noprefix(tbl, 0, 4); /* RsdtAddress */
  1436. if (rsdp_data->rsdt_tbl_offset) {
  1437. /* RSDT address to be filled by guest linker */
  1438. bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
  1439. tbl_off + 16, 4,
  1440. ACPI_BUILD_TABLE_FILE,
  1441. *rsdp_data->rsdt_tbl_offset);
  1442. }
  1443. /* Checksum to be filled by guest linker */
  1444. bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
  1445. tbl_off, 20, /* ACPI rev 1.0 RSDP size */
  1446. 8);
  1447. if (rsdp_data->revision == 0) {
  1448. /* ACPI 1.0 RSDP, we're done */
  1449. return;
  1450. }
  1451. build_append_int_noprefix(tbl, 36, 4); /* Length */
  1452. /* XSDT address to be filled by guest linker */
  1453. build_append_int_noprefix(tbl, 0, 8); /* XsdtAddress */
  1454. /* We already validated our xsdt pointer */
  1455. bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,
  1456. tbl_off + 24, 8,
  1457. ACPI_BUILD_TABLE_FILE,
  1458. *rsdp_data->xsdt_tbl_offset);
  1459. build_append_int_noprefix(tbl, 0, 1); /* Extended Checksum */
  1460. build_append_int_noprefix(tbl, 0, 3); /* Reserved */
  1461. /* Extended checksum to be filled by Guest linker */
  1462. bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,
  1463. tbl_off, 36, /* ACPI rev 2.0 RSDP size */
  1464. 32);
  1465. }
  1466. /* Build rsdt table */
  1467. void
  1468. build_rsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
  1469. const char *oem_id, const char *oem_table_id)
  1470. {
  1471. int i;
  1472. unsigned rsdt_entries_offset;
  1473. AcpiRsdtDescriptorRev1 *rsdt;
  1474. const unsigned table_data_len = (sizeof(uint32_t) * table_offsets->len);
  1475. const unsigned rsdt_entry_size = sizeof(rsdt->table_offset_entry[0]);
  1476. const size_t rsdt_len = sizeof(*rsdt) + table_data_len;
  1477. rsdt = acpi_data_push(table_data, rsdt_len);
  1478. rsdt_entries_offset = (char *)rsdt->table_offset_entry - table_data->data;
  1479. for (i = 0; i < table_offsets->len; ++i) {
  1480. uint32_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
  1481. uint32_t rsdt_entry_offset = rsdt_entries_offset + rsdt_entry_size * i;
  1482. /* rsdt->table_offset_entry to be filled by Guest linker */
  1483. bios_linker_loader_add_pointer(linker,
  1484. ACPI_BUILD_TABLE_FILE, rsdt_entry_offset, rsdt_entry_size,
  1485. ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
  1486. }
  1487. build_header(linker, table_data,
  1488. (void *)rsdt, "RSDT", rsdt_len, 1, oem_id, oem_table_id);
  1489. }
  1490. /* Build xsdt table */
  1491. void
  1492. build_xsdt(GArray *table_data, BIOSLinker *linker, GArray *table_offsets,
  1493. const char *oem_id, const char *oem_table_id)
  1494. {
  1495. int i;
  1496. unsigned xsdt_entries_offset;
  1497. AcpiXsdtDescriptorRev2 *xsdt;
  1498. const unsigned table_data_len = (sizeof(uint64_t) * table_offsets->len);
  1499. const unsigned xsdt_entry_size = sizeof(xsdt->table_offset_entry[0]);
  1500. const size_t xsdt_len = sizeof(*xsdt) + table_data_len;
  1501. xsdt = acpi_data_push(table_data, xsdt_len);
  1502. xsdt_entries_offset = (char *)xsdt->table_offset_entry - table_data->data;
  1503. for (i = 0; i < table_offsets->len; ++i) {
  1504. uint64_t ref_tbl_offset = g_array_index(table_offsets, uint32_t, i);
  1505. uint64_t xsdt_entry_offset = xsdt_entries_offset + xsdt_entry_size * i;
  1506. /* xsdt->table_offset_entry to be filled by Guest linker */
  1507. bios_linker_loader_add_pointer(linker,
  1508. ACPI_BUILD_TABLE_FILE, xsdt_entry_offset, xsdt_entry_size,
  1509. ACPI_BUILD_TABLE_FILE, ref_tbl_offset);
  1510. }
  1511. build_header(linker, table_data,
  1512. (void *)xsdt, "XSDT", xsdt_len, 1, oem_id, oem_table_id);
  1513. }
  1514. void build_srat_memory(AcpiSratMemoryAffinity *numamem, uint64_t base,
  1515. uint64_t len, int node, MemoryAffinityFlags flags)
  1516. {
  1517. numamem->type = ACPI_SRAT_MEMORY;
  1518. numamem->length = sizeof(*numamem);
  1519. numamem->proximity = cpu_to_le32(node);
  1520. numamem->flags = cpu_to_le32(flags);
  1521. numamem->base_addr = cpu_to_le64(base);
  1522. numamem->range_length = cpu_to_le64(len);
  1523. }
  1524. /*
  1525. * ACPI spec 5.2.17 System Locality Distance Information Table
  1526. * (Revision 2.0 or later)
  1527. */
  1528. void build_slit(GArray *table_data, BIOSLinker *linker, MachineState *ms)
  1529. {
  1530. int slit_start, i, j;
  1531. slit_start = table_data->len;
  1532. int nb_numa_nodes = ms->numa_state->num_nodes;
  1533. acpi_data_push(table_data, sizeof(AcpiTableHeader));
  1534. build_append_int_noprefix(table_data, nb_numa_nodes, 8);
  1535. for (i = 0; i < nb_numa_nodes; i++) {
  1536. for (j = 0; j < nb_numa_nodes; j++) {
  1537. assert(ms->numa_state->nodes[i].distance[j]);
  1538. build_append_int_noprefix(table_data,
  1539. ms->numa_state->nodes[i].distance[j],
  1540. 1);
  1541. }
  1542. }
  1543. build_header(linker, table_data,
  1544. (void *)(table_data->data + slit_start),
  1545. "SLIT",
  1546. table_data->len - slit_start, 1, NULL, NULL);
  1547. }
  1548. /* build rev1/rev3/rev5.1 FADT */
  1549. void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
  1550. const char *oem_id, const char *oem_table_id)
  1551. {
  1552. int off;
  1553. int fadt_start = tbl->len;
  1554. acpi_data_push(tbl, sizeof(AcpiTableHeader));
  1555. /* FACS address to be filled by Guest linker at runtime */
  1556. off = tbl->len;
  1557. build_append_int_noprefix(tbl, 0, 4); /* FIRMWARE_CTRL */
  1558. if (f->facs_tbl_offset) { /* don't patch if not supported by platform */
  1559. bios_linker_loader_add_pointer(linker,
  1560. ACPI_BUILD_TABLE_FILE, off, 4,
  1561. ACPI_BUILD_TABLE_FILE, *f->facs_tbl_offset);
  1562. }
  1563. /* DSDT address to be filled by Guest linker at runtime */
  1564. off = tbl->len;
  1565. build_append_int_noprefix(tbl, 0, 4); /* DSDT */
  1566. if (f->dsdt_tbl_offset) { /* don't patch if not supported by platform */
  1567. bios_linker_loader_add_pointer(linker,
  1568. ACPI_BUILD_TABLE_FILE, off, 4,
  1569. ACPI_BUILD_TABLE_FILE, *f->dsdt_tbl_offset);
  1570. }
  1571. /* ACPI1.0: INT_MODEL, ACPI2.0+: Reserved */
  1572. build_append_int_noprefix(tbl, f->int_model /* Multiple APIC */, 1);
  1573. /* Preferred_PM_Profile */
  1574. build_append_int_noprefix(tbl, 0 /* Unspecified */, 1);
  1575. build_append_int_noprefix(tbl, f->sci_int, 2); /* SCI_INT */
  1576. build_append_int_noprefix(tbl, f->smi_cmd, 4); /* SMI_CMD */
  1577. build_append_int_noprefix(tbl, f->acpi_enable_cmd, 1); /* ACPI_ENABLE */
  1578. build_append_int_noprefix(tbl, f->acpi_disable_cmd, 1); /* ACPI_DISABLE */
  1579. build_append_int_noprefix(tbl, 0 /* not supported */, 1); /* S4BIOS_REQ */
  1580. /* ACPI1.0: Reserved, ACPI2.0+: PSTATE_CNT */
  1581. build_append_int_noprefix(tbl, 0, 1);
  1582. build_append_int_noprefix(tbl, f->pm1a_evt.address, 4); /* PM1a_EVT_BLK */
  1583. build_append_int_noprefix(tbl, 0, 4); /* PM1b_EVT_BLK */
  1584. build_append_int_noprefix(tbl, f->pm1a_cnt.address, 4); /* PM1a_CNT_BLK */
  1585. build_append_int_noprefix(tbl, 0, 4); /* PM1b_CNT_BLK */
  1586. build_append_int_noprefix(tbl, 0, 4); /* PM2_CNT_BLK */
  1587. build_append_int_noprefix(tbl, f->pm_tmr.address, 4); /* PM_TMR_BLK */
  1588. build_append_int_noprefix(tbl, f->gpe0_blk.address, 4); /* GPE0_BLK */
  1589. build_append_int_noprefix(tbl, 0, 4); /* GPE1_BLK */
  1590. /* PM1_EVT_LEN */
  1591. build_append_int_noprefix(tbl, f->pm1a_evt.bit_width / 8, 1);
  1592. /* PM1_CNT_LEN */
  1593. build_append_int_noprefix(tbl, f->pm1a_cnt.bit_width / 8, 1);
  1594. build_append_int_noprefix(tbl, 0, 1); /* PM2_CNT_LEN */
  1595. build_append_int_noprefix(tbl, f->pm_tmr.bit_width / 8, 1); /* PM_TMR_LEN */
  1596. /* GPE0_BLK_LEN */
  1597. build_append_int_noprefix(tbl, f->gpe0_blk.bit_width / 8, 1);
  1598. build_append_int_noprefix(tbl, 0, 1); /* GPE1_BLK_LEN */
  1599. build_append_int_noprefix(tbl, 0, 1); /* GPE1_BASE */
  1600. build_append_int_noprefix(tbl, 0, 1); /* CST_CNT */
  1601. build_append_int_noprefix(tbl, f->plvl2_lat, 2); /* P_LVL2_LAT */
  1602. build_append_int_noprefix(tbl, f->plvl3_lat, 2); /* P_LVL3_LAT */
  1603. build_append_int_noprefix(tbl, 0, 2); /* FLUSH_SIZE */
  1604. build_append_int_noprefix(tbl, 0, 2); /* FLUSH_STRIDE */
  1605. build_append_int_noprefix(tbl, 0, 1); /* DUTY_OFFSET */
  1606. build_append_int_noprefix(tbl, 0, 1); /* DUTY_WIDTH */
  1607. build_append_int_noprefix(tbl, 0, 1); /* DAY_ALRM */
  1608. build_append_int_noprefix(tbl, 0, 1); /* MON_ALRM */
  1609. build_append_int_noprefix(tbl, f->rtc_century, 1); /* CENTURY */
  1610. build_append_int_noprefix(tbl, 0, 2); /* IAPC_BOOT_ARCH */
  1611. build_append_int_noprefix(tbl, 0, 1); /* Reserved */
  1612. build_append_int_noprefix(tbl, f->flags, 4); /* Flags */
  1613. if (f->rev == 1) {
  1614. goto build_hdr;
  1615. }
  1616. build_append_gas_from_struct(tbl, &f->reset_reg); /* RESET_REG */
  1617. build_append_int_noprefix(tbl, f->reset_val, 1); /* RESET_VALUE */
  1618. /* Since ACPI 5.1 */
  1619. if ((f->rev >= 6) || ((f->rev == 5) && f->minor_ver > 0)) {
  1620. build_append_int_noprefix(tbl, f->arm_boot_arch, 2); /* ARM_BOOT_ARCH */
  1621. /* FADT Minor Version */
  1622. build_append_int_noprefix(tbl, f->minor_ver, 1);
  1623. } else {
  1624. build_append_int_noprefix(tbl, 0, 3); /* Reserved upto ACPI 5.0 */
  1625. }
  1626. build_append_int_noprefix(tbl, 0, 8); /* X_FIRMWARE_CTRL */
  1627. /* XDSDT address to be filled by Guest linker at runtime */
  1628. off = tbl->len;
  1629. build_append_int_noprefix(tbl, 0, 8); /* X_DSDT */
  1630. if (f->xdsdt_tbl_offset) {
  1631. bios_linker_loader_add_pointer(linker,
  1632. ACPI_BUILD_TABLE_FILE, off, 8,
  1633. ACPI_BUILD_TABLE_FILE, *f->xdsdt_tbl_offset);
  1634. }
  1635. build_append_gas_from_struct(tbl, &f->pm1a_evt); /* X_PM1a_EVT_BLK */
  1636. /* X_PM1b_EVT_BLK */
  1637. build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
  1638. build_append_gas_from_struct(tbl, &f->pm1a_cnt); /* X_PM1a_CNT_BLK */
  1639. /* X_PM1b_CNT_BLK */
  1640. build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
  1641. /* X_PM2_CNT_BLK */
  1642. build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0);
  1643. build_append_gas_from_struct(tbl, &f->pm_tmr); /* X_PM_TMR_BLK */
  1644. build_append_gas_from_struct(tbl, &f->gpe0_blk); /* X_GPE0_BLK */
  1645. build_append_gas(tbl, AML_AS_SYSTEM_MEMORY, 0 , 0, 0, 0); /* X_GPE1_BLK */
  1646. if (f->rev <= 4) {
  1647. goto build_hdr;
  1648. }
  1649. /* SLEEP_CONTROL_REG */
  1650. build_append_gas_from_struct(tbl, &f->sleep_ctl);
  1651. /* SLEEP_STATUS_REG */
  1652. build_append_gas_from_struct(tbl, &f->sleep_sts);
  1653. /* TODO: extra fields need to be added to support revisions above rev5 */
  1654. assert(f->rev == 5);
  1655. build_hdr:
  1656. build_header(linker, tbl, (void *)(tbl->data + fadt_start),
  1657. "FACP", tbl->len - fadt_start, f->rev, oem_id, oem_table_id);
  1658. }
  1659. /*
  1660. * build_tpm2 - Build the TPM2 table as specified in
  1661. * table 7: TCG Hardware Interface Description Table Format for TPM 2.0
  1662. * of TCG ACPI Specification, Family “1.2” and “2.0”, Version 1.2, Rev 8
  1663. */
  1664. void build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog)
  1665. {
  1666. uint8_t start_method_params[12] = {};
  1667. unsigned log_addr_offset, tpm2_start;
  1668. uint64_t control_area_start_address;
  1669. TPMIf *tpmif = tpm_find();
  1670. uint32_t start_method;
  1671. void *tpm2_ptr;
  1672. tpm2_start = table_data->len;
  1673. tpm2_ptr = acpi_data_push(table_data, sizeof(AcpiTableHeader));
  1674. /* Platform Class */
  1675. build_append_int_noprefix(table_data, TPM2_ACPI_CLASS_CLIENT, 2);
  1676. /* Reserved */
  1677. build_append_int_noprefix(table_data, 0, 2);
  1678. if (TPM_IS_TIS_ISA(tpmif) || TPM_IS_TIS_SYSBUS(tpmif)) {
  1679. control_area_start_address = 0;
  1680. start_method = TPM2_START_METHOD_MMIO;
  1681. } else if (TPM_IS_CRB(tpmif)) {
  1682. control_area_start_address = TPM_CRB_ADDR_CTRL;
  1683. start_method = TPM2_START_METHOD_CRB;
  1684. } else {
  1685. g_assert_not_reached();
  1686. }
  1687. /* Address of Control Area */
  1688. build_append_int_noprefix(table_data, control_area_start_address, 8);
  1689. /* Start Method */
  1690. build_append_int_noprefix(table_data, start_method, 4);
  1691. /* Platform Specific Parameters */
  1692. g_array_append_vals(table_data, &start_method_params,
  1693. ARRAY_SIZE(start_method_params));
  1694. /* Log Area Minimum Length */
  1695. build_append_int_noprefix(table_data, TPM_LOG_AREA_MINIMUM_SIZE, 4);
  1696. acpi_data_push(tcpalog, TPM_LOG_AREA_MINIMUM_SIZE);
  1697. bios_linker_loader_alloc(linker, ACPI_BUILD_TPMLOG_FILE, tcpalog, 1,
  1698. false);
  1699. log_addr_offset = table_data->len;
  1700. /* Log Area Start Address to be filled by Guest linker */
  1701. build_append_int_noprefix(table_data, 0, 8);
  1702. bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,
  1703. log_addr_offset, 8,
  1704. ACPI_BUILD_TPMLOG_FILE, 0);
  1705. build_header(linker, table_data,
  1706. tpm2_ptr, "TPM2", table_data->len - tpm2_start, 4, NULL, NULL);
  1707. }
  1708. /* ACPI 5.0: 6.4.3.8.2 Serial Bus Connection Descriptors */
  1709. static Aml *aml_serial_bus_device(uint8_t serial_bus_type, uint8_t flags,
  1710. uint16_t type_flags,
  1711. uint8_t revid, uint16_t data_length,
  1712. uint16_t resource_source_len)
  1713. {
  1714. Aml *var = aml_alloc();
  1715. uint16_t length = data_length + resource_source_len + 9;
  1716. build_append_byte(var->buf, 0x8e); /* Serial Bus Connection Descriptor */
  1717. build_append_int_noprefix(var->buf, length, sizeof(length));
  1718. build_append_byte(var->buf, 1); /* Revision ID */
  1719. build_append_byte(var->buf, 0); /* Resource Source Index */
  1720. build_append_byte(var->buf, serial_bus_type); /* Serial Bus Type */
  1721. build_append_byte(var->buf, flags); /* General Flags */
  1722. build_append_int_noprefix(var->buf, type_flags, /* Type Specific Flags */
  1723. sizeof(type_flags));
  1724. build_append_byte(var->buf, revid); /* Type Specification Revision ID */
  1725. build_append_int_noprefix(var->buf, data_length, sizeof(data_length));
  1726. return var;
  1727. }
  1728. /* ACPI 5.0: 6.4.3.8.2.1 I2C Serial Bus Connection Resource Descriptor */
  1729. Aml *aml_i2c_serial_bus_device(uint16_t address, const char *resource_source)
  1730. {
  1731. uint16_t resource_source_len = strlen(resource_source) + 1;
  1732. Aml *var = aml_serial_bus_device(AML_SERIAL_BUS_TYPE_I2C, 0, 0, 1,
  1733. 6, resource_source_len);
  1734. /* Connection Speed. Just set to 100K for now, it doesn't really matter. */
  1735. build_append_int_noprefix(var->buf, 100000, 4);
  1736. build_append_int_noprefix(var->buf, address, sizeof(address));
  1737. /* This is a string, not a name, so just copy it directly in. */
  1738. g_array_append_vals(var->buf, resource_source, resource_source_len);
  1739. return var;
  1740. }