1*61046927SAndroid Build Coastguard Worker /* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2*61046927SAndroid Build Coastguard Worker
3*61046927SAndroid Build Coastguard Worker /*
4*61046927SAndroid Build Coastguard Worker * Copyright © 2014 Rob Clark <[email protected]>
5*61046927SAndroid Build Coastguard Worker * SPDX-License-Identifier: MIT
6*61046927SAndroid Build Coastguard Worker *
7*61046927SAndroid Build Coastguard Worker * Authors:
8*61046927SAndroid Build Coastguard Worker * Rob Clark <[email protected]>
9*61046927SAndroid Build Coastguard Worker */
10*61046927SAndroid Build Coastguard Worker
11*61046927SAndroid Build Coastguard Worker #define LUA_COMPAT_APIINTCASTS
12*61046927SAndroid Build Coastguard Worker
13*61046927SAndroid Build Coastguard Worker #include <assert.h>
14*61046927SAndroid Build Coastguard Worker #include <lauxlib.h>
15*61046927SAndroid Build Coastguard Worker #include <lua.h>
16*61046927SAndroid Build Coastguard Worker #include <lualib.h>
17*61046927SAndroid Build Coastguard Worker #include <stdio.h>
18*61046927SAndroid Build Coastguard Worker #include <stdlib.h>
19*61046927SAndroid Build Coastguard Worker #include <string.h>
20*61046927SAndroid Build Coastguard Worker #include "util/u_math.h"
21*61046927SAndroid Build Coastguard Worker
22*61046927SAndroid Build Coastguard Worker #include "cffdec.h"
23*61046927SAndroid Build Coastguard Worker #include "rnnutil.h"
24*61046927SAndroid Build Coastguard Worker #include "script.h"
25*61046927SAndroid Build Coastguard Worker
26*61046927SAndroid Build Coastguard Worker static lua_State *L;
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker #if 0
29*61046927SAndroid Build Coastguard Worker #define DBG(fmt, ...) \
30*61046927SAndroid Build Coastguard Worker do { \
31*61046927SAndroid Build Coastguard Worker printf(" ** %s:%d ** " fmt "\n", __func__, __LINE__, ##__VA_ARGS__); \
32*61046927SAndroid Build Coastguard Worker } while (0)
33*61046927SAndroid Build Coastguard Worker #else
34*61046927SAndroid Build Coastguard Worker #define DBG(fmt, ...) \
35*61046927SAndroid Build Coastguard Worker do { \
36*61046927SAndroid Build Coastguard Worker } while (0)
37*61046927SAndroid Build Coastguard Worker #endif
38*61046927SAndroid Build Coastguard Worker
39*61046927SAndroid Build Coastguard Worker /* An rnn based decoder, which can either be decoding current register
40*61046927SAndroid Build Coastguard Worker * values, or domain based decoding of a pm4 packet.
41*61046927SAndroid Build Coastguard Worker *
42*61046927SAndroid Build Coastguard Worker */
43*61046927SAndroid Build Coastguard Worker struct rnndec {
44*61046927SAndroid Build Coastguard Worker struct rnn base;
45*61046927SAndroid Build Coastguard Worker
46*61046927SAndroid Build Coastguard Worker /* for pm4 packet decoding: */
47*61046927SAndroid Build Coastguard Worker uint32_t sizedwords;
48*61046927SAndroid Build Coastguard Worker uint32_t *dwords;
49*61046927SAndroid Build Coastguard Worker };
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker static inline struct rnndec *
to_rnndec(struct rnn * rnn)52*61046927SAndroid Build Coastguard Worker to_rnndec(struct rnn *rnn)
53*61046927SAndroid Build Coastguard Worker {
54*61046927SAndroid Build Coastguard Worker return (struct rnndec *)rnn;
55*61046927SAndroid Build Coastguard Worker }
56*61046927SAndroid Build Coastguard Worker
57*61046927SAndroid Build Coastguard Worker static uint32_t
rnn_val(struct rnn * rnn,uint32_t regbase)58*61046927SAndroid Build Coastguard Worker rnn_val(struct rnn *rnn, uint32_t regbase)
59*61046927SAndroid Build Coastguard Worker {
60*61046927SAndroid Build Coastguard Worker struct rnndec *rnndec = to_rnndec(rnn);
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker if (!rnndec->sizedwords) {
63*61046927SAndroid Build Coastguard Worker return reg_val(regbase);
64*61046927SAndroid Build Coastguard Worker } else if (regbase < rnndec->sizedwords) {
65*61046927SAndroid Build Coastguard Worker return rnndec->dwords[regbase];
66*61046927SAndroid Build Coastguard Worker } else {
67*61046927SAndroid Build Coastguard Worker // XXX throw an error
68*61046927SAndroid Build Coastguard Worker return -1;
69*61046927SAndroid Build Coastguard Worker }
70*61046927SAndroid Build Coastguard Worker }
71*61046927SAndroid Build Coastguard Worker
72*61046927SAndroid Build Coastguard Worker /* does not return */
73*61046927SAndroid Build Coastguard Worker static void
error(const char * fmt)74*61046927SAndroid Build Coastguard Worker error(const char *fmt)
75*61046927SAndroid Build Coastguard Worker {
76*61046927SAndroid Build Coastguard Worker fprintf(stderr, fmt, lua_tostring(L, -1));
77*61046927SAndroid Build Coastguard Worker exit(1);
78*61046927SAndroid Build Coastguard Worker }
79*61046927SAndroid Build Coastguard Worker
80*61046927SAndroid Build Coastguard Worker /*
81*61046927SAndroid Build Coastguard Worker * An enum type that can be used as string or number:
82*61046927SAndroid Build Coastguard Worker */
83*61046927SAndroid Build Coastguard Worker
84*61046927SAndroid Build Coastguard Worker struct rnndenum {
85*61046927SAndroid Build Coastguard Worker const char *str;
86*61046927SAndroid Build Coastguard Worker int val;
87*61046927SAndroid Build Coastguard Worker };
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker static int
l_meta_rnn_enum_tostring(lua_State * L)90*61046927SAndroid Build Coastguard Worker l_meta_rnn_enum_tostring(lua_State *L)
91*61046927SAndroid Build Coastguard Worker {
92*61046927SAndroid Build Coastguard Worker struct rnndenum *e = lua_touserdata(L, 1);
93*61046927SAndroid Build Coastguard Worker if (e->str) {
94*61046927SAndroid Build Coastguard Worker lua_pushstring(L, e->str);
95*61046927SAndroid Build Coastguard Worker } else {
96*61046927SAndroid Build Coastguard Worker char buf[32];
97*61046927SAndroid Build Coastguard Worker sprintf(buf, "%u", e->val);
98*61046927SAndroid Build Coastguard Worker lua_pushstring(L, buf);
99*61046927SAndroid Build Coastguard Worker }
100*61046927SAndroid Build Coastguard Worker return 1;
101*61046927SAndroid Build Coastguard Worker }
102*61046927SAndroid Build Coastguard Worker
103*61046927SAndroid Build Coastguard Worker /* so, this doesn't actually seem to be implemented yet, but hopefully
104*61046927SAndroid Build Coastguard Worker * some day lua comes to it's senses
105*61046927SAndroid Build Coastguard Worker */
106*61046927SAndroid Build Coastguard Worker static int
l_meta_rnn_enum_tonumber(lua_State * L)107*61046927SAndroid Build Coastguard Worker l_meta_rnn_enum_tonumber(lua_State *L)
108*61046927SAndroid Build Coastguard Worker {
109*61046927SAndroid Build Coastguard Worker struct rnndenum *e = lua_touserdata(L, 1);
110*61046927SAndroid Build Coastguard Worker lua_pushinteger(L, e->val);
111*61046927SAndroid Build Coastguard Worker return 1;
112*61046927SAndroid Build Coastguard Worker }
113*61046927SAndroid Build Coastguard Worker
114*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_enum[] = {
115*61046927SAndroid Build Coastguard Worker {"__tostring", l_meta_rnn_enum_tostring},
116*61046927SAndroid Build Coastguard Worker {"__tonumber", l_meta_rnn_enum_tonumber},
117*61046927SAndroid Build Coastguard Worker {NULL, NULL} /* sentinel */
118*61046927SAndroid Build Coastguard Worker };
119*61046927SAndroid Build Coastguard Worker
120*61046927SAndroid Build Coastguard Worker static void
pushenum(struct lua_State * L,int val,struct rnnenum * info)121*61046927SAndroid Build Coastguard Worker pushenum(struct lua_State *L, int val, struct rnnenum *info)
122*61046927SAndroid Build Coastguard Worker {
123*61046927SAndroid Build Coastguard Worker struct rnndenum *e = lua_newuserdata(L, sizeof(*e));
124*61046927SAndroid Build Coastguard Worker
125*61046927SAndroid Build Coastguard Worker e->val = val;
126*61046927SAndroid Build Coastguard Worker e->str = NULL;
127*61046927SAndroid Build Coastguard Worker
128*61046927SAndroid Build Coastguard Worker for (int i = 0; i < info->valsnum; i++) {
129*61046927SAndroid Build Coastguard Worker if (info->vals[i]->valvalid && (info->vals[i]->value == val)) {
130*61046927SAndroid Build Coastguard Worker e->str = info->vals[i]->name;
131*61046927SAndroid Build Coastguard Worker break;
132*61046927SAndroid Build Coastguard Worker }
133*61046927SAndroid Build Coastguard Worker }
134*61046927SAndroid Build Coastguard Worker
135*61046927SAndroid Build Coastguard Worker luaL_newmetatable(L, "rnnmetaenum");
136*61046927SAndroid Build Coastguard Worker luaL_setfuncs(L, l_meta_rnn_enum, 0);
137*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
138*61046927SAndroid Build Coastguard Worker
139*61046927SAndroid Build Coastguard Worker luaL_setmetatable(L, "rnnmetaenum");
140*61046927SAndroid Build Coastguard Worker }
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker /* Expose rnn decode to script environment as "rnn" library:
143*61046927SAndroid Build Coastguard Worker */
144*61046927SAndroid Build Coastguard Worker
145*61046927SAndroid Build Coastguard Worker struct rnndoff {
146*61046927SAndroid Build Coastguard Worker struct rnn *rnn;
147*61046927SAndroid Build Coastguard Worker struct rnndelem *elem;
148*61046927SAndroid Build Coastguard Worker uint64_t offset;
149*61046927SAndroid Build Coastguard Worker };
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker static void
push_rnndoff(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)152*61046927SAndroid Build Coastguard Worker push_rnndoff(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
153*61046927SAndroid Build Coastguard Worker uint64_t offset)
154*61046927SAndroid Build Coastguard Worker {
155*61046927SAndroid Build Coastguard Worker struct rnndoff *rnndoff = lua_newuserdata(L, sizeof(*rnndoff));
156*61046927SAndroid Build Coastguard Worker rnndoff->rnn = rnn;
157*61046927SAndroid Build Coastguard Worker rnndoff->elem = elem;
158*61046927SAndroid Build Coastguard Worker rnndoff->offset = offset;
159*61046927SAndroid Build Coastguard Worker }
160*61046927SAndroid Build Coastguard Worker
161*61046927SAndroid Build Coastguard Worker static int l_rnn_etype_array(lua_State *L, struct rnn *rnn,
162*61046927SAndroid Build Coastguard Worker struct rnndelem *elem, uint64_t offset);
163*61046927SAndroid Build Coastguard Worker static int l_rnn_etype_reg(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
164*61046927SAndroid Build Coastguard Worker uint64_t offset);
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker static int
pushdecval(struct lua_State * L,struct rnn * rnn,uint64_t regval,struct rnntypeinfo * info)167*61046927SAndroid Build Coastguard Worker pushdecval(struct lua_State *L, struct rnn *rnn, uint64_t regval,
168*61046927SAndroid Build Coastguard Worker struct rnntypeinfo *info)
169*61046927SAndroid Build Coastguard Worker {
170*61046927SAndroid Build Coastguard Worker union rnndecval val;
171*61046927SAndroid Build Coastguard Worker switch (rnn_decodelem(rnn, info, regval, &val)) {
172*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_ENUM:
173*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_INLINE_ENUM:
174*61046927SAndroid Build Coastguard Worker pushenum(L, val.i, info->eenum);
175*61046927SAndroid Build Coastguard Worker return 1;
176*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_INT:
177*61046927SAndroid Build Coastguard Worker lua_pushinteger(L, val.i);
178*61046927SAndroid Build Coastguard Worker return 1;
179*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_UINT:
180*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_HEX:
181*61046927SAndroid Build Coastguard Worker lua_pushunsigned(L, val.u);
182*61046927SAndroid Build Coastguard Worker return 1;
183*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_FLOAT:
184*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, uif(val.u));
185*61046927SAndroid Build Coastguard Worker return 1;
186*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_BOOLEAN:
187*61046927SAndroid Build Coastguard Worker lua_pushboolean(L, val.u);
188*61046927SAndroid Build Coastguard Worker return 1;
189*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_INVALID:
190*61046927SAndroid Build Coastguard Worker default:
191*61046927SAndroid Build Coastguard Worker return 0;
192*61046927SAndroid Build Coastguard Worker }
193*61046927SAndroid Build Coastguard Worker }
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)196*61046927SAndroid Build Coastguard Worker l_rnn_etype(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
197*61046927SAndroid Build Coastguard Worker uint64_t offset)
198*61046927SAndroid Build Coastguard Worker {
199*61046927SAndroid Build Coastguard Worker int ret;
200*61046927SAndroid Build Coastguard Worker uint64_t regval;
201*61046927SAndroid Build Coastguard Worker DBG("elem=%p (%d), offset=%lu", elem, elem->type, offset);
202*61046927SAndroid Build Coastguard Worker switch (elem->type) {
203*61046927SAndroid Build Coastguard Worker case RNN_ETYPE_REG:
204*61046927SAndroid Build Coastguard Worker /* if a register has no bitfields, just return
205*61046927SAndroid Build Coastguard Worker * the raw value:
206*61046927SAndroid Build Coastguard Worker */
207*61046927SAndroid Build Coastguard Worker regval = rnn_val(rnn, offset);
208*61046927SAndroid Build Coastguard Worker if (elem->width == 64)
209*61046927SAndroid Build Coastguard Worker regval |= (uint64_t)rnn_val(rnn, offset + 1) << 32;
210*61046927SAndroid Build Coastguard Worker regval <<= elem->typeinfo.shr;
211*61046927SAndroid Build Coastguard Worker ret = pushdecval(L, rnn, regval, &elem->typeinfo);
212*61046927SAndroid Build Coastguard Worker if (ret)
213*61046927SAndroid Build Coastguard Worker return ret;
214*61046927SAndroid Build Coastguard Worker return l_rnn_etype_reg(L, rnn, elem, offset);
215*61046927SAndroid Build Coastguard Worker case RNN_ETYPE_ARRAY:
216*61046927SAndroid Build Coastguard Worker return l_rnn_etype_array(L, rnn, elem, offset);
217*61046927SAndroid Build Coastguard Worker default:
218*61046927SAndroid Build Coastguard Worker /* hmm.. */
219*61046927SAndroid Build Coastguard Worker printf("unhandled type: %d\n", elem->type);
220*61046927SAndroid Build Coastguard Worker return 0;
221*61046927SAndroid Build Coastguard Worker }
222*61046927SAndroid Build Coastguard Worker }
223*61046927SAndroid Build Coastguard Worker
224*61046927SAndroid Build Coastguard Worker /*
225*61046927SAndroid Build Coastguard Worker * Struct Object:
226*61046927SAndroid Build Coastguard Worker * To implement stuff like 'RB_MRT[n].CONTROL' we need a struct-object
227*61046927SAndroid Build Coastguard Worker * to represent the current array index (ie. 'RB_MRT[n]')
228*61046927SAndroid Build Coastguard Worker */
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker static int
l_rnn_struct_meta_index(lua_State * L)231*61046927SAndroid Build Coastguard Worker l_rnn_struct_meta_index(lua_State *L)
232*61046927SAndroid Build Coastguard Worker {
233*61046927SAndroid Build Coastguard Worker struct rnndoff *rnndoff = lua_touserdata(L, 1);
234*61046927SAndroid Build Coastguard Worker const char *name = lua_tostring(L, 2);
235*61046927SAndroid Build Coastguard Worker struct rnndelem *elem = rnndoff->elem;
236*61046927SAndroid Build Coastguard Worker int i;
237*61046927SAndroid Build Coastguard Worker
238*61046927SAndroid Build Coastguard Worker for (i = 0; i < elem->subelemsnum; i++) {
239*61046927SAndroid Build Coastguard Worker struct rnndelem *subelem = elem->subelems[i];
240*61046927SAndroid Build Coastguard Worker if (!strcmp(name, subelem->name)) {
241*61046927SAndroid Build Coastguard Worker return l_rnn_etype(L, rnndoff->rnn, subelem,
242*61046927SAndroid Build Coastguard Worker rnndoff->offset + subelem->offset);
243*61046927SAndroid Build Coastguard Worker }
244*61046927SAndroid Build Coastguard Worker }
245*61046927SAndroid Build Coastguard Worker
246*61046927SAndroid Build Coastguard Worker return 0;
247*61046927SAndroid Build Coastguard Worker }
248*61046927SAndroid Build Coastguard Worker
249*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_struct[] = {
250*61046927SAndroid Build Coastguard Worker {"__index", l_rnn_struct_meta_index}, {NULL, NULL} /* sentinel */
251*61046927SAndroid Build Coastguard Worker };
252*61046927SAndroid Build Coastguard Worker
253*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype_struct(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)254*61046927SAndroid Build Coastguard Worker l_rnn_etype_struct(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
255*61046927SAndroid Build Coastguard Worker uint64_t offset)
256*61046927SAndroid Build Coastguard Worker {
257*61046927SAndroid Build Coastguard Worker push_rnndoff(L, rnn, elem, offset);
258*61046927SAndroid Build Coastguard Worker
259*61046927SAndroid Build Coastguard Worker luaL_newmetatable(L, "rnnmetastruct");
260*61046927SAndroid Build Coastguard Worker luaL_setfuncs(L, l_meta_rnn_struct, 0);
261*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker luaL_setmetatable(L, "rnnmetastruct");
264*61046927SAndroid Build Coastguard Worker
265*61046927SAndroid Build Coastguard Worker return 1;
266*61046927SAndroid Build Coastguard Worker }
267*61046927SAndroid Build Coastguard Worker
268*61046927SAndroid Build Coastguard Worker /*
269*61046927SAndroid Build Coastguard Worker * Array Object:
270*61046927SAndroid Build Coastguard Worker */
271*61046927SAndroid Build Coastguard Worker
272*61046927SAndroid Build Coastguard Worker static int
l_rnn_array_meta_index(lua_State * L)273*61046927SAndroid Build Coastguard Worker l_rnn_array_meta_index(lua_State *L)
274*61046927SAndroid Build Coastguard Worker {
275*61046927SAndroid Build Coastguard Worker struct rnndoff *rnndoff = lua_touserdata(L, 1);
276*61046927SAndroid Build Coastguard Worker int idx = lua_tointeger(L, 2);
277*61046927SAndroid Build Coastguard Worker struct rnndelem *elem = rnndoff->elem;
278*61046927SAndroid Build Coastguard Worker uint64_t offset = rnndoff->offset + (elem->stride * idx);
279*61046927SAndroid Build Coastguard Worker
280*61046927SAndroid Build Coastguard Worker DBG("rnndoff=%p, idx=%d, numsubelems=%d", rnndoff, idx,
281*61046927SAndroid Build Coastguard Worker rnndoff->elem->subelemsnum);
282*61046927SAndroid Build Coastguard Worker
283*61046927SAndroid Build Coastguard Worker /* if just a single sub-element, it is directly a register,
284*61046927SAndroid Build Coastguard Worker * otherwise we need to accumulate the array index while
285*61046927SAndroid Build Coastguard Worker * we wait for the register name within the array..
286*61046927SAndroid Build Coastguard Worker */
287*61046927SAndroid Build Coastguard Worker if (elem->subelemsnum == 1) {
288*61046927SAndroid Build Coastguard Worker return l_rnn_etype(L, rnndoff->rnn, elem->subelems[0], offset);
289*61046927SAndroid Build Coastguard Worker } else {
290*61046927SAndroid Build Coastguard Worker return l_rnn_etype_struct(L, rnndoff->rnn, elem, offset);
291*61046927SAndroid Build Coastguard Worker }
292*61046927SAndroid Build Coastguard Worker
293*61046927SAndroid Build Coastguard Worker return 0;
294*61046927SAndroid Build Coastguard Worker }
295*61046927SAndroid Build Coastguard Worker
296*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_array[] = {
297*61046927SAndroid Build Coastguard Worker {"__index", l_rnn_array_meta_index}, {NULL, NULL} /* sentinel */
298*61046927SAndroid Build Coastguard Worker };
299*61046927SAndroid Build Coastguard Worker
300*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype_array(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)301*61046927SAndroid Build Coastguard Worker l_rnn_etype_array(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
302*61046927SAndroid Build Coastguard Worker uint64_t offset)
303*61046927SAndroid Build Coastguard Worker {
304*61046927SAndroid Build Coastguard Worker push_rnndoff(L, rnn, elem, offset);
305*61046927SAndroid Build Coastguard Worker
306*61046927SAndroid Build Coastguard Worker luaL_newmetatable(L, "rnnmetaarray");
307*61046927SAndroid Build Coastguard Worker luaL_setfuncs(L, l_meta_rnn_array, 0);
308*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker luaL_setmetatable(L, "rnnmetaarray");
311*61046927SAndroid Build Coastguard Worker
312*61046927SAndroid Build Coastguard Worker return 1;
313*61046927SAndroid Build Coastguard Worker }
314*61046927SAndroid Build Coastguard Worker
315*61046927SAndroid Build Coastguard Worker /*
316*61046927SAndroid Build Coastguard Worker * Register element:
317*61046927SAndroid Build Coastguard Worker */
318*61046927SAndroid Build Coastguard Worker
319*61046927SAndroid Build Coastguard Worker static int
l_rnn_reg_meta_index(lua_State * L)320*61046927SAndroid Build Coastguard Worker l_rnn_reg_meta_index(lua_State *L)
321*61046927SAndroid Build Coastguard Worker {
322*61046927SAndroid Build Coastguard Worker struct rnndoff *rnndoff = lua_touserdata(L, 1);
323*61046927SAndroid Build Coastguard Worker const char *name = lua_tostring(L, 2);
324*61046927SAndroid Build Coastguard Worker struct rnndelem *elem = rnndoff->elem;
325*61046927SAndroid Build Coastguard Worker struct rnntypeinfo *info = &elem->typeinfo;
326*61046927SAndroid Build Coastguard Worker struct rnnbitfield **bitfields;
327*61046927SAndroid Build Coastguard Worker int bitfieldsnum;
328*61046927SAndroid Build Coastguard Worker int i;
329*61046927SAndroid Build Coastguard Worker
330*61046927SAndroid Build Coastguard Worker switch (info->type) {
331*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_BITSET:
332*61046927SAndroid Build Coastguard Worker bitfields = info->ebitset->bitfields;
333*61046927SAndroid Build Coastguard Worker bitfieldsnum = info->ebitset->bitfieldsnum;
334*61046927SAndroid Build Coastguard Worker break;
335*61046927SAndroid Build Coastguard Worker case RNN_TTYPE_INLINE_BITSET:
336*61046927SAndroid Build Coastguard Worker bitfields = info->bitfields;
337*61046927SAndroid Build Coastguard Worker bitfieldsnum = info->bitfieldsnum;
338*61046927SAndroid Build Coastguard Worker break;
339*61046927SAndroid Build Coastguard Worker default:
340*61046927SAndroid Build Coastguard Worker printf("invalid register type: %d\n", info->type);
341*61046927SAndroid Build Coastguard Worker return 0;
342*61046927SAndroid Build Coastguard Worker }
343*61046927SAndroid Build Coastguard Worker
344*61046927SAndroid Build Coastguard Worker for (i = 0; i < bitfieldsnum; i++) {
345*61046927SAndroid Build Coastguard Worker struct rnnbitfield *bf = bitfields[i];
346*61046927SAndroid Build Coastguard Worker if (!strcmp(name, bf->name)) {
347*61046927SAndroid Build Coastguard Worker uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset);
348*61046927SAndroid Build Coastguard Worker
349*61046927SAndroid Build Coastguard Worker regval &= typeinfo_mask(&bf->typeinfo);
350*61046927SAndroid Build Coastguard Worker regval >>= bf->typeinfo.low;
351*61046927SAndroid Build Coastguard Worker regval <<= bf->typeinfo.shr;
352*61046927SAndroid Build Coastguard Worker
353*61046927SAndroid Build Coastguard Worker DBG("name=%s, info=%p, subelemsnum=%d, type=%d, regval=%x", name, info,
354*61046927SAndroid Build Coastguard Worker rnndoff->elem->subelemsnum, bf->typeinfo.type, regval);
355*61046927SAndroid Build Coastguard Worker
356*61046927SAndroid Build Coastguard Worker return pushdecval(L, rnndoff->rnn, regval, &bf->typeinfo);
357*61046927SAndroid Build Coastguard Worker }
358*61046927SAndroid Build Coastguard Worker }
359*61046927SAndroid Build Coastguard Worker
360*61046927SAndroid Build Coastguard Worker printf("invalid member: %s\n", name);
361*61046927SAndroid Build Coastguard Worker return 0;
362*61046927SAndroid Build Coastguard Worker }
363*61046927SAndroid Build Coastguard Worker
364*61046927SAndroid Build Coastguard Worker static int
l_rnn_reg_meta_tostring(lua_State * L)365*61046927SAndroid Build Coastguard Worker l_rnn_reg_meta_tostring(lua_State *L)
366*61046927SAndroid Build Coastguard Worker {
367*61046927SAndroid Build Coastguard Worker struct rnndoff *rnndoff = lua_touserdata(L, 1);
368*61046927SAndroid Build Coastguard Worker uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset);
369*61046927SAndroid Build Coastguard Worker struct rnndecaddrinfo *info = rnn_reginfo(rnndoff->rnn, rnndoff->offset);
370*61046927SAndroid Build Coastguard Worker char *decoded;
371*61046927SAndroid Build Coastguard Worker if (info && info->typeinfo) {
372*61046927SAndroid Build Coastguard Worker decoded = rnndec_decodeval(rnndoff->rnn->vc, info->typeinfo, regval);
373*61046927SAndroid Build Coastguard Worker } else {
374*61046927SAndroid Build Coastguard Worker asprintf(&decoded, "%08x", regval);
375*61046927SAndroid Build Coastguard Worker }
376*61046927SAndroid Build Coastguard Worker lua_pushstring(L, decoded);
377*61046927SAndroid Build Coastguard Worker free(decoded);
378*61046927SAndroid Build Coastguard Worker rnn_reginfo_free(info);
379*61046927SAndroid Build Coastguard Worker return 1;
380*61046927SAndroid Build Coastguard Worker }
381*61046927SAndroid Build Coastguard Worker
382*61046927SAndroid Build Coastguard Worker static int
l_rnn_reg_meta_tonumber(lua_State * L)383*61046927SAndroid Build Coastguard Worker l_rnn_reg_meta_tonumber(lua_State *L)
384*61046927SAndroid Build Coastguard Worker {
385*61046927SAndroid Build Coastguard Worker struct rnndoff *rnndoff = lua_touserdata(L, 1);
386*61046927SAndroid Build Coastguard Worker uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset);
387*61046927SAndroid Build Coastguard Worker
388*61046927SAndroid Build Coastguard Worker regval <<= rnndoff->elem->typeinfo.shr;
389*61046927SAndroid Build Coastguard Worker
390*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, regval);
391*61046927SAndroid Build Coastguard Worker return 1;
392*61046927SAndroid Build Coastguard Worker }
393*61046927SAndroid Build Coastguard Worker
394*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_reg[] = {
395*61046927SAndroid Build Coastguard Worker {"__index", l_rnn_reg_meta_index},
396*61046927SAndroid Build Coastguard Worker {"__tostring", l_rnn_reg_meta_tostring},
397*61046927SAndroid Build Coastguard Worker {"__tonumber", l_rnn_reg_meta_tonumber},
398*61046927SAndroid Build Coastguard Worker {NULL, NULL} /* sentinel */
399*61046927SAndroid Build Coastguard Worker };
400*61046927SAndroid Build Coastguard Worker
401*61046927SAndroid Build Coastguard Worker static int
l_rnn_etype_reg(lua_State * L,struct rnn * rnn,struct rnndelem * elem,uint64_t offset)402*61046927SAndroid Build Coastguard Worker l_rnn_etype_reg(lua_State *L, struct rnn *rnn, struct rnndelem *elem,
403*61046927SAndroid Build Coastguard Worker uint64_t offset)
404*61046927SAndroid Build Coastguard Worker {
405*61046927SAndroid Build Coastguard Worker push_rnndoff(L, rnn, elem, offset);
406*61046927SAndroid Build Coastguard Worker
407*61046927SAndroid Build Coastguard Worker luaL_newmetatable(L, "rnnmetareg");
408*61046927SAndroid Build Coastguard Worker luaL_setfuncs(L, l_meta_rnn_reg, 0);
409*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
410*61046927SAndroid Build Coastguard Worker
411*61046927SAndroid Build Coastguard Worker luaL_setmetatable(L, "rnnmetareg");
412*61046927SAndroid Build Coastguard Worker
413*61046927SAndroid Build Coastguard Worker return 1;
414*61046927SAndroid Build Coastguard Worker }
415*61046927SAndroid Build Coastguard Worker
416*61046927SAndroid Build Coastguard Worker /*
417*61046927SAndroid Build Coastguard Worker *
418*61046927SAndroid Build Coastguard Worker */
419*61046927SAndroid Build Coastguard Worker
420*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_index(lua_State * L)421*61046927SAndroid Build Coastguard Worker l_rnn_meta_index(lua_State *L)
422*61046927SAndroid Build Coastguard Worker {
423*61046927SAndroid Build Coastguard Worker struct rnn *rnn = lua_touserdata(L, 1);
424*61046927SAndroid Build Coastguard Worker const char *name = lua_tostring(L, 2);
425*61046927SAndroid Build Coastguard Worker struct rnndelem *elem;
426*61046927SAndroid Build Coastguard Worker
427*61046927SAndroid Build Coastguard Worker elem = rnn_regelem(rnn, name);
428*61046927SAndroid Build Coastguard Worker if (!elem)
429*61046927SAndroid Build Coastguard Worker return 0;
430*61046927SAndroid Build Coastguard Worker
431*61046927SAndroid Build Coastguard Worker return l_rnn_etype(L, rnn, elem, elem->offset);
432*61046927SAndroid Build Coastguard Worker }
433*61046927SAndroid Build Coastguard Worker
434*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_gc(lua_State * L)435*61046927SAndroid Build Coastguard Worker l_rnn_meta_gc(lua_State *L)
436*61046927SAndroid Build Coastguard Worker {
437*61046927SAndroid Build Coastguard Worker // TODO
438*61046927SAndroid Build Coastguard Worker // struct rnn *rnn = lua_touserdata(L, 1);
439*61046927SAndroid Build Coastguard Worker // rnn_deinit(rnn);
440*61046927SAndroid Build Coastguard Worker return 0;
441*61046927SAndroid Build Coastguard Worker }
442*61046927SAndroid Build Coastguard Worker
443*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn[] = {
444*61046927SAndroid Build Coastguard Worker {"__index", l_rnn_meta_index},
445*61046927SAndroid Build Coastguard Worker {"__gc", l_rnn_meta_gc},
446*61046927SAndroid Build Coastguard Worker {NULL, NULL} /* sentinel */
447*61046927SAndroid Build Coastguard Worker };
448*61046927SAndroid Build Coastguard Worker
449*61046927SAndroid Build Coastguard Worker static int
l_rnn_init(lua_State * L)450*61046927SAndroid Build Coastguard Worker l_rnn_init(lua_State *L)
451*61046927SAndroid Build Coastguard Worker {
452*61046927SAndroid Build Coastguard Worker const char *gpuname = lua_tostring(L, 1);
453*61046927SAndroid Build Coastguard Worker struct rnndec *rnndec = lua_newuserdata(L, sizeof(*rnndec));
454*61046927SAndroid Build Coastguard Worker _rnn_init(&rnndec->base, 0);
455*61046927SAndroid Build Coastguard Worker rnn_load(&rnndec->base, gpuname);
456*61046927SAndroid Build Coastguard Worker rnndec->sizedwords = 0;
457*61046927SAndroid Build Coastguard Worker
458*61046927SAndroid Build Coastguard Worker luaL_newmetatable(L, "rnnmeta");
459*61046927SAndroid Build Coastguard Worker luaL_setfuncs(L, l_meta_rnn, 0);
460*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
461*61046927SAndroid Build Coastguard Worker
462*61046927SAndroid Build Coastguard Worker luaL_setmetatable(L, "rnnmeta");
463*61046927SAndroid Build Coastguard Worker
464*61046927SAndroid Build Coastguard Worker return 1;
465*61046927SAndroid Build Coastguard Worker }
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker static int
l_rnn_enumname(lua_State * L)468*61046927SAndroid Build Coastguard Worker l_rnn_enumname(lua_State *L)
469*61046927SAndroid Build Coastguard Worker {
470*61046927SAndroid Build Coastguard Worker struct rnn *rnn = lua_touserdata(L, 1);
471*61046927SAndroid Build Coastguard Worker const char *name = lua_tostring(L, 2);
472*61046927SAndroid Build Coastguard Worker uint32_t val = (uint32_t)lua_tonumber(L, 3);
473*61046927SAndroid Build Coastguard Worker lua_pushstring(L, rnn_enumname(rnn, name, val));
474*61046927SAndroid Build Coastguard Worker return 1;
475*61046927SAndroid Build Coastguard Worker }
476*61046927SAndroid Build Coastguard Worker
477*61046927SAndroid Build Coastguard Worker static int
l_rnn_regname(lua_State * L)478*61046927SAndroid Build Coastguard Worker l_rnn_regname(lua_State *L)
479*61046927SAndroid Build Coastguard Worker {
480*61046927SAndroid Build Coastguard Worker struct rnn *rnn = lua_touserdata(L, 1);
481*61046927SAndroid Build Coastguard Worker uint32_t regbase = (uint32_t)lua_tonumber(L, 2);
482*61046927SAndroid Build Coastguard Worker lua_pushstring(L, rnn_regname(rnn, regbase, 1));
483*61046927SAndroid Build Coastguard Worker return 1;
484*61046927SAndroid Build Coastguard Worker }
485*61046927SAndroid Build Coastguard Worker
486*61046927SAndroid Build Coastguard Worker static int
l_rnn_regval(lua_State * L)487*61046927SAndroid Build Coastguard Worker l_rnn_regval(lua_State *L)
488*61046927SAndroid Build Coastguard Worker {
489*61046927SAndroid Build Coastguard Worker struct rnn *rnn = lua_touserdata(L, 1);
490*61046927SAndroid Build Coastguard Worker uint32_t regbase = (uint32_t)lua_tonumber(L, 2);
491*61046927SAndroid Build Coastguard Worker uint32_t regval = (uint32_t)lua_tonumber(L, 3);
492*61046927SAndroid Build Coastguard Worker struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase);
493*61046927SAndroid Build Coastguard Worker char *decoded;
494*61046927SAndroid Build Coastguard Worker if (info && info->typeinfo) {
495*61046927SAndroid Build Coastguard Worker decoded = rnndec_decodeval(rnn->vc, info->typeinfo, regval);
496*61046927SAndroid Build Coastguard Worker } else {
497*61046927SAndroid Build Coastguard Worker asprintf(&decoded, "%08x", regval);
498*61046927SAndroid Build Coastguard Worker }
499*61046927SAndroid Build Coastguard Worker lua_pushstring(L, decoded);
500*61046927SAndroid Build Coastguard Worker free(decoded);
501*61046927SAndroid Build Coastguard Worker rnn_reginfo_free(info);
502*61046927SAndroid Build Coastguard Worker return 1;
503*61046927SAndroid Build Coastguard Worker }
504*61046927SAndroid Build Coastguard Worker
505*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_rnn[] = {
506*61046927SAndroid Build Coastguard Worker {"init", l_rnn_init},
507*61046927SAndroid Build Coastguard Worker {"enumname", l_rnn_enumname},
508*61046927SAndroid Build Coastguard Worker {"regname", l_rnn_regname},
509*61046927SAndroid Build Coastguard Worker {"regval", l_rnn_regval},
510*61046927SAndroid Build Coastguard Worker {NULL, NULL} /* sentinel */
511*61046927SAndroid Build Coastguard Worker };
512*61046927SAndroid Build Coastguard Worker
513*61046927SAndroid Build Coastguard Worker /* Expose the register state to script enviroment as a "regs" library:
514*61046927SAndroid Build Coastguard Worker */
515*61046927SAndroid Build Coastguard Worker
516*61046927SAndroid Build Coastguard Worker static int
l_reg_written(lua_State * L)517*61046927SAndroid Build Coastguard Worker l_reg_written(lua_State *L)
518*61046927SAndroid Build Coastguard Worker {
519*61046927SAndroid Build Coastguard Worker uint32_t regbase = (uint32_t)lua_tonumber(L, 1);
520*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, reg_written(regbase));
521*61046927SAndroid Build Coastguard Worker return 1;
522*61046927SAndroid Build Coastguard Worker }
523*61046927SAndroid Build Coastguard Worker
524*61046927SAndroid Build Coastguard Worker static int
l_reg_lastval(lua_State * L)525*61046927SAndroid Build Coastguard Worker l_reg_lastval(lua_State *L)
526*61046927SAndroid Build Coastguard Worker {
527*61046927SAndroid Build Coastguard Worker uint32_t regbase = (uint32_t)lua_tonumber(L, 1);
528*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, reg_lastval(regbase));
529*61046927SAndroid Build Coastguard Worker return 1;
530*61046927SAndroid Build Coastguard Worker }
531*61046927SAndroid Build Coastguard Worker
532*61046927SAndroid Build Coastguard Worker static int
l_reg_val(lua_State * L)533*61046927SAndroid Build Coastguard Worker l_reg_val(lua_State *L)
534*61046927SAndroid Build Coastguard Worker {
535*61046927SAndroid Build Coastguard Worker uint32_t regbase = (uint32_t)lua_tonumber(L, 1);
536*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, reg_val(regbase));
537*61046927SAndroid Build Coastguard Worker return 1;
538*61046927SAndroid Build Coastguard Worker }
539*61046927SAndroid Build Coastguard Worker
540*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_regs[] = {
541*61046927SAndroid Build Coastguard Worker {"written", l_reg_written},
542*61046927SAndroid Build Coastguard Worker {"lastval", l_reg_lastval},
543*61046927SAndroid Build Coastguard Worker {"val", l_reg_val},
544*61046927SAndroid Build Coastguard Worker {NULL, NULL} /* sentinel */
545*61046927SAndroid Build Coastguard Worker };
546*61046927SAndroid Build Coastguard Worker
547*61046927SAndroid Build Coastguard Worker /* Expose API to lookup snapshot buffers:
548*61046927SAndroid Build Coastguard Worker */
549*61046927SAndroid Build Coastguard Worker
550*61046927SAndroid Build Coastguard Worker uint64_t gpubaseaddr(uint64_t gpuaddr);
551*61046927SAndroid Build Coastguard Worker unsigned hostlen(uint64_t gpuaddr);
552*61046927SAndroid Build Coastguard Worker
553*61046927SAndroid Build Coastguard Worker /* given address, return base-address of buffer: */
554*61046927SAndroid Build Coastguard Worker static int
l_bo_base(lua_State * L)555*61046927SAndroid Build Coastguard Worker l_bo_base(lua_State *L)
556*61046927SAndroid Build Coastguard Worker {
557*61046927SAndroid Build Coastguard Worker uint64_t addr = (uint64_t)lua_tonumber(L, 1);
558*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, gpubaseaddr(addr));
559*61046927SAndroid Build Coastguard Worker return 1;
560*61046927SAndroid Build Coastguard Worker }
561*61046927SAndroid Build Coastguard Worker
562*61046927SAndroid Build Coastguard Worker /* given address, return the remaining size of the buffer: */
563*61046927SAndroid Build Coastguard Worker static int
l_bo_size(lua_State * L)564*61046927SAndroid Build Coastguard Worker l_bo_size(lua_State *L)
565*61046927SAndroid Build Coastguard Worker {
566*61046927SAndroid Build Coastguard Worker uint64_t addr = (uint64_t)lua_tonumber(L, 1);
567*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, hostlen(addr));
568*61046927SAndroid Build Coastguard Worker return 1;
569*61046927SAndroid Build Coastguard Worker }
570*61046927SAndroid Build Coastguard Worker
571*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_bos[] = {
572*61046927SAndroid Build Coastguard Worker {"base", l_bo_base}, {"size", l_bo_size}, {NULL, NULL} /* sentinel */
573*61046927SAndroid Build Coastguard Worker };
574*61046927SAndroid Build Coastguard Worker
575*61046927SAndroid Build Coastguard Worker static void
openlib(const char * lib,const luaL_Reg * reg)576*61046927SAndroid Build Coastguard Worker openlib(const char *lib, const luaL_Reg *reg)
577*61046927SAndroid Build Coastguard Worker {
578*61046927SAndroid Build Coastguard Worker lua_newtable(L);
579*61046927SAndroid Build Coastguard Worker luaL_setfuncs(L, reg, 0);
580*61046927SAndroid Build Coastguard Worker lua_setglobal(L, lib);
581*61046927SAndroid Build Coastguard Worker }
582*61046927SAndroid Build Coastguard Worker
583*61046927SAndroid Build Coastguard Worker /* called at start to load the script: */
584*61046927SAndroid Build Coastguard Worker int
script_load(const char * file)585*61046927SAndroid Build Coastguard Worker script_load(const char *file)
586*61046927SAndroid Build Coastguard Worker {
587*61046927SAndroid Build Coastguard Worker int ret;
588*61046927SAndroid Build Coastguard Worker
589*61046927SAndroid Build Coastguard Worker assert(!L);
590*61046927SAndroid Build Coastguard Worker
591*61046927SAndroid Build Coastguard Worker L = luaL_newstate();
592*61046927SAndroid Build Coastguard Worker luaL_openlibs(L);
593*61046927SAndroid Build Coastguard Worker openlib("bos", l_bos);
594*61046927SAndroid Build Coastguard Worker openlib("regs", l_regs);
595*61046927SAndroid Build Coastguard Worker openlib("rnn", l_rnn);
596*61046927SAndroid Build Coastguard Worker
597*61046927SAndroid Build Coastguard Worker ret = luaL_loadfile(L, file);
598*61046927SAndroid Build Coastguard Worker if (ret)
599*61046927SAndroid Build Coastguard Worker error("%s\n");
600*61046927SAndroid Build Coastguard Worker
601*61046927SAndroid Build Coastguard Worker ret = lua_pcall(L, 0, LUA_MULTRET, 0);
602*61046927SAndroid Build Coastguard Worker if (ret)
603*61046927SAndroid Build Coastguard Worker error("%s\n");
604*61046927SAndroid Build Coastguard Worker
605*61046927SAndroid Build Coastguard Worker return 0;
606*61046927SAndroid Build Coastguard Worker }
607*61046927SAndroid Build Coastguard Worker
608*61046927SAndroid Build Coastguard Worker /* called at start of each cmdstream file: */
609*61046927SAndroid Build Coastguard Worker void
script_start_cmdstream(const char * name)610*61046927SAndroid Build Coastguard Worker script_start_cmdstream(const char *name)
611*61046927SAndroid Build Coastguard Worker {
612*61046927SAndroid Build Coastguard Worker if (!L)
613*61046927SAndroid Build Coastguard Worker return;
614*61046927SAndroid Build Coastguard Worker
615*61046927SAndroid Build Coastguard Worker lua_getglobal(L, "start_cmdstream");
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker /* if no handler just ignore it: */
618*61046927SAndroid Build Coastguard Worker if (!lua_isfunction(L, -1)) {
619*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
620*61046927SAndroid Build Coastguard Worker return;
621*61046927SAndroid Build Coastguard Worker }
622*61046927SAndroid Build Coastguard Worker
623*61046927SAndroid Build Coastguard Worker lua_pushstring(L, name);
624*61046927SAndroid Build Coastguard Worker
625*61046927SAndroid Build Coastguard Worker /* do the call (1 arguments, 0 result) */
626*61046927SAndroid Build Coastguard Worker if (lua_pcall(L, 1, 0, 0) != 0)
627*61046927SAndroid Build Coastguard Worker error("error running function `f': %s\n");
628*61046927SAndroid Build Coastguard Worker }
629*61046927SAndroid Build Coastguard Worker
630*61046927SAndroid Build Coastguard Worker /* called at each DRAW_INDX, calls script drawidx fxn to process
631*61046927SAndroid Build Coastguard Worker * the current state
632*61046927SAndroid Build Coastguard Worker */
633*61046927SAndroid Build Coastguard Worker void
script_draw(const char * primtype,uint32_t nindx)634*61046927SAndroid Build Coastguard Worker script_draw(const char *primtype, uint32_t nindx)
635*61046927SAndroid Build Coastguard Worker {
636*61046927SAndroid Build Coastguard Worker if (!L)
637*61046927SAndroid Build Coastguard Worker return;
638*61046927SAndroid Build Coastguard Worker
639*61046927SAndroid Build Coastguard Worker lua_getglobal(L, "draw");
640*61046927SAndroid Build Coastguard Worker
641*61046927SAndroid Build Coastguard Worker /* if no handler just ignore it: */
642*61046927SAndroid Build Coastguard Worker if (!lua_isfunction(L, -1)) {
643*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
644*61046927SAndroid Build Coastguard Worker return;
645*61046927SAndroid Build Coastguard Worker }
646*61046927SAndroid Build Coastguard Worker
647*61046927SAndroid Build Coastguard Worker lua_pushstring(L, primtype);
648*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, nindx);
649*61046927SAndroid Build Coastguard Worker
650*61046927SAndroid Build Coastguard Worker /* do the call (2 arguments, 0 result) */
651*61046927SAndroid Build Coastguard Worker if (lua_pcall(L, 2, 0, 0) != 0)
652*61046927SAndroid Build Coastguard Worker error("error running function `f': %s\n");
653*61046927SAndroid Build Coastguard Worker }
654*61046927SAndroid Build Coastguard Worker
655*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_dom_index(lua_State * L)656*61046927SAndroid Build Coastguard Worker l_rnn_meta_dom_index(lua_State *L)
657*61046927SAndroid Build Coastguard Worker {
658*61046927SAndroid Build Coastguard Worker struct rnn *rnn = lua_touserdata(L, 1);
659*61046927SAndroid Build Coastguard Worker uint32_t offset = (uint32_t)lua_tonumber(L, 2);
660*61046927SAndroid Build Coastguard Worker struct rnndelem *elem;
661*61046927SAndroid Build Coastguard Worker
662*61046927SAndroid Build Coastguard Worker /* TODO might be nicer if the arg isn't a number, to search the domain
663*61046927SAndroid Build Coastguard Worker * for matching bitfields.. so that the script could do something like
664*61046927SAndroid Build Coastguard Worker * 'pkt.WIDTH' insteadl of 'pkt[1].WIDTH', ie. not have to remember the
665*61046927SAndroid Build Coastguard Worker * offset of the dword containing the bitfield..
666*61046927SAndroid Build Coastguard Worker */
667*61046927SAndroid Build Coastguard Worker
668*61046927SAndroid Build Coastguard Worker elem = rnn_regoff(rnn, offset);
669*61046927SAndroid Build Coastguard Worker if (!elem)
670*61046927SAndroid Build Coastguard Worker return 0;
671*61046927SAndroid Build Coastguard Worker
672*61046927SAndroid Build Coastguard Worker return l_rnn_etype(L, rnn, elem, elem->offset);
673*61046927SAndroid Build Coastguard Worker }
674*61046927SAndroid Build Coastguard Worker
675*61046927SAndroid Build Coastguard Worker /*
676*61046927SAndroid Build Coastguard Worker * A wrapper object for rnndomain based decoding of an array of dwords
677*61046927SAndroid Build Coastguard Worker * (ie. for pm4 packet decoding). Mostly re-uses the register-value
678*61046927SAndroid Build Coastguard Worker * decoding for the individual dwords and bitfields.
679*61046927SAndroid Build Coastguard Worker */
680*61046927SAndroid Build Coastguard Worker
681*61046927SAndroid Build Coastguard Worker static int
l_rnn_meta_dom_gc(lua_State * L)682*61046927SAndroid Build Coastguard Worker l_rnn_meta_dom_gc(lua_State *L)
683*61046927SAndroid Build Coastguard Worker {
684*61046927SAndroid Build Coastguard Worker // TODO
685*61046927SAndroid Build Coastguard Worker // struct rnn *rnn = lua_touserdata(L, 1);
686*61046927SAndroid Build Coastguard Worker // rnn_deinit(rnn);
687*61046927SAndroid Build Coastguard Worker return 0;
688*61046927SAndroid Build Coastguard Worker }
689*61046927SAndroid Build Coastguard Worker
690*61046927SAndroid Build Coastguard Worker static const struct luaL_Reg l_meta_rnn_dom[] = {
691*61046927SAndroid Build Coastguard Worker {"__index", l_rnn_meta_dom_index},
692*61046927SAndroid Build Coastguard Worker {"__gc", l_rnn_meta_dom_gc},
693*61046927SAndroid Build Coastguard Worker {NULL, NULL} /* sentinel */
694*61046927SAndroid Build Coastguard Worker };
695*61046927SAndroid Build Coastguard Worker
696*61046927SAndroid Build Coastguard Worker /* called to general pm4 packet decoding, such as texture/sampler state
697*61046927SAndroid Build Coastguard Worker */
698*61046927SAndroid Build Coastguard Worker void
script_packet(uint32_t * dwords,uint32_t sizedwords,struct rnn * rnn,struct rnndomain * dom)699*61046927SAndroid Build Coastguard Worker script_packet(uint32_t *dwords, uint32_t sizedwords, struct rnn *rnn,
700*61046927SAndroid Build Coastguard Worker struct rnndomain *dom)
701*61046927SAndroid Build Coastguard Worker {
702*61046927SAndroid Build Coastguard Worker if (!L)
703*61046927SAndroid Build Coastguard Worker return;
704*61046927SAndroid Build Coastguard Worker
705*61046927SAndroid Build Coastguard Worker lua_getglobal(L, dom->name);
706*61046927SAndroid Build Coastguard Worker
707*61046927SAndroid Build Coastguard Worker /* if no handler for the packet, just ignore it: */
708*61046927SAndroid Build Coastguard Worker if (!lua_isfunction(L, -1)) {
709*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
710*61046927SAndroid Build Coastguard Worker return;
711*61046927SAndroid Build Coastguard Worker }
712*61046927SAndroid Build Coastguard Worker
713*61046927SAndroid Build Coastguard Worker struct rnndec *rnndec = lua_newuserdata(L, sizeof(*rnndec));
714*61046927SAndroid Build Coastguard Worker
715*61046927SAndroid Build Coastguard Worker rnndec->base = *rnn;
716*61046927SAndroid Build Coastguard Worker rnndec->base.dom[0] = dom;
717*61046927SAndroid Build Coastguard Worker rnndec->base.dom[1] = NULL;
718*61046927SAndroid Build Coastguard Worker rnndec->dwords = dwords;
719*61046927SAndroid Build Coastguard Worker rnndec->sizedwords = sizedwords;
720*61046927SAndroid Build Coastguard Worker
721*61046927SAndroid Build Coastguard Worker luaL_newmetatable(L, "rnnmetadom");
722*61046927SAndroid Build Coastguard Worker luaL_setfuncs(L, l_meta_rnn_dom, 0);
723*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
724*61046927SAndroid Build Coastguard Worker
725*61046927SAndroid Build Coastguard Worker luaL_setmetatable(L, "rnnmetadom");
726*61046927SAndroid Build Coastguard Worker
727*61046927SAndroid Build Coastguard Worker lua_pushnumber(L, sizedwords);
728*61046927SAndroid Build Coastguard Worker
729*61046927SAndroid Build Coastguard Worker if (lua_pcall(L, 2, 0, 0) != 0)
730*61046927SAndroid Build Coastguard Worker error("error running function `f': %s\n");
731*61046927SAndroid Build Coastguard Worker }
732*61046927SAndroid Build Coastguard Worker
733*61046927SAndroid Build Coastguard Worker /* helper to call fxn that takes and returns void: */
734*61046927SAndroid Build Coastguard Worker static void
simple_call(const char * name)735*61046927SAndroid Build Coastguard Worker simple_call(const char *name)
736*61046927SAndroid Build Coastguard Worker {
737*61046927SAndroid Build Coastguard Worker if (!L)
738*61046927SAndroid Build Coastguard Worker return;
739*61046927SAndroid Build Coastguard Worker
740*61046927SAndroid Build Coastguard Worker lua_getglobal(L, name);
741*61046927SAndroid Build Coastguard Worker
742*61046927SAndroid Build Coastguard Worker /* if no handler just ignore it: */
743*61046927SAndroid Build Coastguard Worker if (!lua_isfunction(L, -1)) {
744*61046927SAndroid Build Coastguard Worker lua_pop(L, 1);
745*61046927SAndroid Build Coastguard Worker return;
746*61046927SAndroid Build Coastguard Worker }
747*61046927SAndroid Build Coastguard Worker
748*61046927SAndroid Build Coastguard Worker /* do the call (0 arguments, 0 result) */
749*61046927SAndroid Build Coastguard Worker if (lua_pcall(L, 0, 0, 0) != 0)
750*61046927SAndroid Build Coastguard Worker error("error running function `f': %s\n");
751*61046927SAndroid Build Coastguard Worker }
752*61046927SAndroid Build Coastguard Worker
753*61046927SAndroid Build Coastguard Worker /* called at end of each cmdstream file: */
754*61046927SAndroid Build Coastguard Worker void
script_end_cmdstream(void)755*61046927SAndroid Build Coastguard Worker script_end_cmdstream(void)
756*61046927SAndroid Build Coastguard Worker {
757*61046927SAndroid Build Coastguard Worker simple_call("end_cmdstream");
758*61046927SAndroid Build Coastguard Worker }
759*61046927SAndroid Build Coastguard Worker
760*61046927SAndroid Build Coastguard Worker /* called at start of submit/issueibcmds: */
761*61046927SAndroid Build Coastguard Worker void
script_start_submit(void)762*61046927SAndroid Build Coastguard Worker script_start_submit(void)
763*61046927SAndroid Build Coastguard Worker {
764*61046927SAndroid Build Coastguard Worker simple_call("start_submit");
765*61046927SAndroid Build Coastguard Worker }
766*61046927SAndroid Build Coastguard Worker
767*61046927SAndroid Build Coastguard Worker /* called at end of submit/issueibcmds: */
768*61046927SAndroid Build Coastguard Worker void
script_end_submit(void)769*61046927SAndroid Build Coastguard Worker script_end_submit(void)
770*61046927SAndroid Build Coastguard Worker {
771*61046927SAndroid Build Coastguard Worker simple_call("end_submit");
772*61046927SAndroid Build Coastguard Worker }
773*61046927SAndroid Build Coastguard Worker
774*61046927SAndroid Build Coastguard Worker /* called after last cmdstream file: */
775*61046927SAndroid Build Coastguard Worker void
script_finish(void)776*61046927SAndroid Build Coastguard Worker script_finish(void)
777*61046927SAndroid Build Coastguard Worker {
778*61046927SAndroid Build Coastguard Worker if (!L)
779*61046927SAndroid Build Coastguard Worker return;
780*61046927SAndroid Build Coastguard Worker
781*61046927SAndroid Build Coastguard Worker simple_call("finish");
782*61046927SAndroid Build Coastguard Worker
783*61046927SAndroid Build Coastguard Worker lua_close(L);
784*61046927SAndroid Build Coastguard Worker L = NULL;
785*61046927SAndroid Build Coastguard Worker }
786