script.c revision 7ec681f3
17ec681f3Smrg/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */ 27ec681f3Smrg 37ec681f3Smrg/* 47ec681f3Smrg * Copyright (C) 2014 Rob Clark <robclark@freedesktop.org> 57ec681f3Smrg * 67ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 77ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 87ec681f3Smrg * to deal in the Software without restriction, including without limitation 97ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 107ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 117ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 127ec681f3Smrg * 137ec681f3Smrg * The above copyright notice and this permission notice (including the next 147ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 157ec681f3Smrg * Software. 167ec681f3Smrg * 177ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 187ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 197ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 207ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 217ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 227ec681f3Smrg * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 237ec681f3Smrg * SOFTWARE. 247ec681f3Smrg * 257ec681f3Smrg * Authors: 267ec681f3Smrg * Rob Clark <robclark@freedesktop.org> 277ec681f3Smrg */ 287ec681f3Smrg 297ec681f3Smrg#define LUA_COMPAT_APIINTCASTS 307ec681f3Smrg 317ec681f3Smrg#include <assert.h> 327ec681f3Smrg#include <lauxlib.h> 337ec681f3Smrg#include <lua.h> 347ec681f3Smrg#include <lualib.h> 357ec681f3Smrg#include <stdio.h> 367ec681f3Smrg#include <stdlib.h> 377ec681f3Smrg#include <string.h> 387ec681f3Smrg 397ec681f3Smrg#include "cffdec.h" 407ec681f3Smrg#include "rnnutil.h" 417ec681f3Smrg#include "script.h" 427ec681f3Smrg 437ec681f3Smrgstatic lua_State *L; 447ec681f3Smrg 457ec681f3Smrg#if 0 467ec681f3Smrg#define DBG(fmt, ...) \ 477ec681f3Smrg do { \ 487ec681f3Smrg printf(" ** %s:%d ** " fmt "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ 497ec681f3Smrg } while (0) 507ec681f3Smrg#else 517ec681f3Smrg#define DBG(fmt, ...) \ 527ec681f3Smrg do { \ 537ec681f3Smrg } while (0) 547ec681f3Smrg#endif 557ec681f3Smrg 567ec681f3Smrg/* An rnn based decoder, which can either be decoding current register 577ec681f3Smrg * values, or domain based decoding of a pm4 packet. 587ec681f3Smrg * 597ec681f3Smrg */ 607ec681f3Smrgstruct rnndec { 617ec681f3Smrg struct rnn base; 627ec681f3Smrg 637ec681f3Smrg /* for pm4 packet decoding: */ 647ec681f3Smrg uint32_t sizedwords; 657ec681f3Smrg uint32_t *dwords; 667ec681f3Smrg}; 677ec681f3Smrg 687ec681f3Smrgstatic inline struct rnndec * 697ec681f3Smrgto_rnndec(struct rnn *rnn) 707ec681f3Smrg{ 717ec681f3Smrg return (struct rnndec *)rnn; 727ec681f3Smrg} 737ec681f3Smrg 747ec681f3Smrgstatic uint32_t 757ec681f3Smrgrnn_val(struct rnn *rnn, uint32_t regbase) 767ec681f3Smrg{ 777ec681f3Smrg struct rnndec *rnndec = to_rnndec(rnn); 787ec681f3Smrg 797ec681f3Smrg if (!rnndec->sizedwords) { 807ec681f3Smrg return reg_val(regbase); 817ec681f3Smrg } else if (regbase < rnndec->sizedwords) { 827ec681f3Smrg return rnndec->dwords[regbase]; 837ec681f3Smrg } else { 847ec681f3Smrg // XXX throw an error 857ec681f3Smrg return -1; 867ec681f3Smrg } 877ec681f3Smrg} 887ec681f3Smrg 897ec681f3Smrg/* does not return */ 907ec681f3Smrgstatic void 917ec681f3Smrgerror(const char *fmt) 927ec681f3Smrg{ 937ec681f3Smrg fprintf(stderr, fmt, lua_tostring(L, -1)); 947ec681f3Smrg exit(1); 957ec681f3Smrg} 967ec681f3Smrg 977ec681f3Smrg/* 987ec681f3Smrg * An enum type that can be used as string or number: 997ec681f3Smrg */ 1007ec681f3Smrg 1017ec681f3Smrgstruct rnndenum { 1027ec681f3Smrg const char *str; 1037ec681f3Smrg int val; 1047ec681f3Smrg}; 1057ec681f3Smrg 1067ec681f3Smrgstatic int 1077ec681f3Smrgl_meta_rnn_enum_tostring(lua_State *L) 1087ec681f3Smrg{ 1097ec681f3Smrg struct rnndenum *e = lua_touserdata(L, 1); 1107ec681f3Smrg if (e->str) { 1117ec681f3Smrg lua_pushstring(L, e->str); 1127ec681f3Smrg } else { 1137ec681f3Smrg char buf[32]; 1147ec681f3Smrg sprintf(buf, "%u", e->val); 1157ec681f3Smrg lua_pushstring(L, buf); 1167ec681f3Smrg } 1177ec681f3Smrg return 1; 1187ec681f3Smrg} 1197ec681f3Smrg 1207ec681f3Smrg/* so, this doesn't actually seem to be implemented yet, but hopefully 1217ec681f3Smrg * some day lua comes to it's senses 1227ec681f3Smrg */ 1237ec681f3Smrgstatic int 1247ec681f3Smrgl_meta_rnn_enum_tonumber(lua_State *L) 1257ec681f3Smrg{ 1267ec681f3Smrg struct rnndenum *e = lua_touserdata(L, 1); 1277ec681f3Smrg lua_pushinteger(L, e->val); 1287ec681f3Smrg return 1; 1297ec681f3Smrg} 1307ec681f3Smrg 1317ec681f3Smrgstatic const struct luaL_Reg l_meta_rnn_enum[] = { 1327ec681f3Smrg {"__tostring", l_meta_rnn_enum_tostring}, 1337ec681f3Smrg {"__tonumber", l_meta_rnn_enum_tonumber}, 1347ec681f3Smrg {NULL, NULL} /* sentinel */ 1357ec681f3Smrg}; 1367ec681f3Smrg 1377ec681f3Smrgstatic void 1387ec681f3Smrgpushenum(struct lua_State *L, int val, struct rnnenum *info) 1397ec681f3Smrg{ 1407ec681f3Smrg struct rnndenum *e = lua_newuserdata(L, sizeof(*e)); 1417ec681f3Smrg 1427ec681f3Smrg e->val = val; 1437ec681f3Smrg e->str = NULL; 1447ec681f3Smrg 1457ec681f3Smrg for (int i = 0; i < info->valsnum; i++) { 1467ec681f3Smrg if (info->vals[i]->valvalid && (info->vals[i]->value == val)) { 1477ec681f3Smrg e->str = info->vals[i]->name; 1487ec681f3Smrg break; 1497ec681f3Smrg } 1507ec681f3Smrg } 1517ec681f3Smrg 1527ec681f3Smrg luaL_newmetatable(L, "rnnmetaenum"); 1537ec681f3Smrg luaL_setfuncs(L, l_meta_rnn_enum, 0); 1547ec681f3Smrg lua_pop(L, 1); 1557ec681f3Smrg 1567ec681f3Smrg luaL_setmetatable(L, "rnnmetaenum"); 1577ec681f3Smrg} 1587ec681f3Smrg 1597ec681f3Smrg/* Expose rnn decode to script environment as "rnn" library: 1607ec681f3Smrg */ 1617ec681f3Smrg 1627ec681f3Smrgstruct rnndoff { 1637ec681f3Smrg struct rnn *rnn; 1647ec681f3Smrg struct rnndelem *elem; 1657ec681f3Smrg uint64_t offset; 1667ec681f3Smrg}; 1677ec681f3Smrg 1687ec681f3Smrgstatic void 1697ec681f3Smrgpush_rnndoff(lua_State *L, struct rnn *rnn, struct rnndelem *elem, 1707ec681f3Smrg uint64_t offset) 1717ec681f3Smrg{ 1727ec681f3Smrg struct rnndoff *rnndoff = lua_newuserdata(L, sizeof(*rnndoff)); 1737ec681f3Smrg rnndoff->rnn = rnn; 1747ec681f3Smrg rnndoff->elem = elem; 1757ec681f3Smrg rnndoff->offset = offset; 1767ec681f3Smrg} 1777ec681f3Smrg 1787ec681f3Smrgstatic int l_rnn_etype_array(lua_State *L, struct rnn *rnn, 1797ec681f3Smrg struct rnndelem *elem, uint64_t offset); 1807ec681f3Smrgstatic int l_rnn_etype_reg(lua_State *L, struct rnn *rnn, struct rnndelem *elem, 1817ec681f3Smrg uint64_t offset); 1827ec681f3Smrg 1837ec681f3Smrgstatic int 1847ec681f3Smrgpushdecval(struct lua_State *L, struct rnn *rnn, uint32_t regval, 1857ec681f3Smrg struct rnntypeinfo *info) 1867ec681f3Smrg{ 1877ec681f3Smrg union rnndecval val; 1887ec681f3Smrg switch (rnn_decodelem(rnn, info, regval, &val)) { 1897ec681f3Smrg case RNN_TTYPE_ENUM: 1907ec681f3Smrg case RNN_TTYPE_INLINE_ENUM: 1917ec681f3Smrg pushenum(L, val.i, info->eenum); 1927ec681f3Smrg return 1; 1937ec681f3Smrg case RNN_TTYPE_INT: 1947ec681f3Smrg lua_pushinteger(L, val.i); 1957ec681f3Smrg return 1; 1967ec681f3Smrg case RNN_TTYPE_UINT: 1977ec681f3Smrg case RNN_TTYPE_HEX: 1987ec681f3Smrg lua_pushunsigned(L, val.u); 1997ec681f3Smrg return 1; 2007ec681f3Smrg case RNN_TTYPE_FLOAT: 2017ec681f3Smrg lua_pushnumber(L, val.f); 2027ec681f3Smrg return 1; 2037ec681f3Smrg case RNN_TTYPE_BOOLEAN: 2047ec681f3Smrg lua_pushboolean(L, val.u); 2057ec681f3Smrg return 1; 2067ec681f3Smrg case RNN_TTYPE_INVALID: 2077ec681f3Smrg default: 2087ec681f3Smrg return 0; 2097ec681f3Smrg } 2107ec681f3Smrg} 2117ec681f3Smrg 2127ec681f3Smrgstatic int 2137ec681f3Smrgl_rnn_etype(lua_State *L, struct rnn *rnn, struct rnndelem *elem, 2147ec681f3Smrg uint64_t offset) 2157ec681f3Smrg{ 2167ec681f3Smrg int ret; 2177ec681f3Smrg uint32_t regval; 2187ec681f3Smrg DBG("elem=%p (%d), offset=%lu", elem, elem->type, offset); 2197ec681f3Smrg switch (elem->type) { 2207ec681f3Smrg case RNN_ETYPE_REG: 2217ec681f3Smrg /* if a register has no bitfields, just return 2227ec681f3Smrg * the raw value: 2237ec681f3Smrg */ 2247ec681f3Smrg regval = rnn_val(rnn, offset); 2257ec681f3Smrg regval <<= elem->typeinfo.shr; 2267ec681f3Smrg ret = pushdecval(L, rnn, regval, &elem->typeinfo); 2277ec681f3Smrg if (ret) 2287ec681f3Smrg return ret; 2297ec681f3Smrg return l_rnn_etype_reg(L, rnn, elem, offset); 2307ec681f3Smrg case RNN_ETYPE_ARRAY: 2317ec681f3Smrg return l_rnn_etype_array(L, rnn, elem, offset); 2327ec681f3Smrg default: 2337ec681f3Smrg /* hmm.. */ 2347ec681f3Smrg printf("unhandled type: %d\n", elem->type); 2357ec681f3Smrg return 0; 2367ec681f3Smrg } 2377ec681f3Smrg} 2387ec681f3Smrg 2397ec681f3Smrg/* 2407ec681f3Smrg * Struct Object: 2417ec681f3Smrg * To implement stuff like 'RB_MRT[n].CONTROL' we need a struct-object 2427ec681f3Smrg * to represent the current array index (ie. 'RB_MRT[n]') 2437ec681f3Smrg */ 2447ec681f3Smrg 2457ec681f3Smrgstatic int 2467ec681f3Smrgl_rnn_struct_meta_index(lua_State *L) 2477ec681f3Smrg{ 2487ec681f3Smrg struct rnndoff *rnndoff = lua_touserdata(L, 1); 2497ec681f3Smrg const char *name = lua_tostring(L, 2); 2507ec681f3Smrg struct rnndelem *elem = rnndoff->elem; 2517ec681f3Smrg int i; 2527ec681f3Smrg 2537ec681f3Smrg for (i = 0; i < elem->subelemsnum; i++) { 2547ec681f3Smrg struct rnndelem *subelem = elem->subelems[i]; 2557ec681f3Smrg if (!strcmp(name, subelem->name)) { 2567ec681f3Smrg return l_rnn_etype(L, rnndoff->rnn, subelem, 2577ec681f3Smrg rnndoff->offset + subelem->offset); 2587ec681f3Smrg } 2597ec681f3Smrg } 2607ec681f3Smrg 2617ec681f3Smrg return 0; 2627ec681f3Smrg} 2637ec681f3Smrg 2647ec681f3Smrgstatic const struct luaL_Reg l_meta_rnn_struct[] = { 2657ec681f3Smrg {"__index", l_rnn_struct_meta_index}, {NULL, NULL} /* sentinel */ 2667ec681f3Smrg}; 2677ec681f3Smrg 2687ec681f3Smrgstatic int 2697ec681f3Smrgl_rnn_etype_struct(lua_State *L, struct rnn *rnn, struct rnndelem *elem, 2707ec681f3Smrg uint64_t offset) 2717ec681f3Smrg{ 2727ec681f3Smrg push_rnndoff(L, rnn, elem, offset); 2737ec681f3Smrg 2747ec681f3Smrg luaL_newmetatable(L, "rnnmetastruct"); 2757ec681f3Smrg luaL_setfuncs(L, l_meta_rnn_struct, 0); 2767ec681f3Smrg lua_pop(L, 1); 2777ec681f3Smrg 2787ec681f3Smrg luaL_setmetatable(L, "rnnmetastruct"); 2797ec681f3Smrg 2807ec681f3Smrg return 1; 2817ec681f3Smrg} 2827ec681f3Smrg 2837ec681f3Smrg/* 2847ec681f3Smrg * Array Object: 2857ec681f3Smrg */ 2867ec681f3Smrg 2877ec681f3Smrgstatic int 2887ec681f3Smrgl_rnn_array_meta_index(lua_State *L) 2897ec681f3Smrg{ 2907ec681f3Smrg struct rnndoff *rnndoff = lua_touserdata(L, 1); 2917ec681f3Smrg int idx = lua_tointeger(L, 2); 2927ec681f3Smrg struct rnndelem *elem = rnndoff->elem; 2937ec681f3Smrg uint64_t offset = rnndoff->offset + (elem->stride * idx); 2947ec681f3Smrg 2957ec681f3Smrg DBG("rnndoff=%p, idx=%d, numsubelems=%d", rnndoff, idx, 2967ec681f3Smrg rnndoff->elem->subelemsnum); 2977ec681f3Smrg 2987ec681f3Smrg /* if just a single sub-element, it is directly a register, 2997ec681f3Smrg * otherwise we need to accumulate the array index while 3007ec681f3Smrg * we wait for the register name within the array.. 3017ec681f3Smrg */ 3027ec681f3Smrg if (elem->subelemsnum == 1) { 3037ec681f3Smrg return l_rnn_etype(L, rnndoff->rnn, elem->subelems[0], offset); 3047ec681f3Smrg } else { 3057ec681f3Smrg return l_rnn_etype_struct(L, rnndoff->rnn, elem, offset); 3067ec681f3Smrg } 3077ec681f3Smrg 3087ec681f3Smrg return 0; 3097ec681f3Smrg} 3107ec681f3Smrg 3117ec681f3Smrgstatic const struct luaL_Reg l_meta_rnn_array[] = { 3127ec681f3Smrg {"__index", l_rnn_array_meta_index}, {NULL, NULL} /* sentinel */ 3137ec681f3Smrg}; 3147ec681f3Smrg 3157ec681f3Smrgstatic int 3167ec681f3Smrgl_rnn_etype_array(lua_State *L, struct rnn *rnn, struct rnndelem *elem, 3177ec681f3Smrg uint64_t offset) 3187ec681f3Smrg{ 3197ec681f3Smrg push_rnndoff(L, rnn, elem, offset); 3207ec681f3Smrg 3217ec681f3Smrg luaL_newmetatable(L, "rnnmetaarray"); 3227ec681f3Smrg luaL_setfuncs(L, l_meta_rnn_array, 0); 3237ec681f3Smrg lua_pop(L, 1); 3247ec681f3Smrg 3257ec681f3Smrg luaL_setmetatable(L, "rnnmetaarray"); 3267ec681f3Smrg 3277ec681f3Smrg return 1; 3287ec681f3Smrg} 3297ec681f3Smrg 3307ec681f3Smrg/* 3317ec681f3Smrg * Register element: 3327ec681f3Smrg */ 3337ec681f3Smrg 3347ec681f3Smrgstatic int 3357ec681f3Smrgl_rnn_reg_meta_index(lua_State *L) 3367ec681f3Smrg{ 3377ec681f3Smrg struct rnndoff *rnndoff = lua_touserdata(L, 1); 3387ec681f3Smrg const char *name = lua_tostring(L, 2); 3397ec681f3Smrg struct rnndelem *elem = rnndoff->elem; 3407ec681f3Smrg struct rnntypeinfo *info = &elem->typeinfo; 3417ec681f3Smrg struct rnnbitfield **bitfields; 3427ec681f3Smrg int bitfieldsnum; 3437ec681f3Smrg int i; 3447ec681f3Smrg 3457ec681f3Smrg switch (info->type) { 3467ec681f3Smrg case RNN_TTYPE_BITSET: 3477ec681f3Smrg bitfields = info->ebitset->bitfields; 3487ec681f3Smrg bitfieldsnum = info->ebitset->bitfieldsnum; 3497ec681f3Smrg break; 3507ec681f3Smrg case RNN_TTYPE_INLINE_BITSET: 3517ec681f3Smrg bitfields = info->bitfields; 3527ec681f3Smrg bitfieldsnum = info->bitfieldsnum; 3537ec681f3Smrg break; 3547ec681f3Smrg default: 3557ec681f3Smrg printf("invalid register type: %d\n", info->type); 3567ec681f3Smrg return 0; 3577ec681f3Smrg } 3587ec681f3Smrg 3597ec681f3Smrg for (i = 0; i < bitfieldsnum; i++) { 3607ec681f3Smrg struct rnnbitfield *bf = bitfields[i]; 3617ec681f3Smrg if (!strcmp(name, bf->name)) { 3627ec681f3Smrg uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset); 3637ec681f3Smrg 3647ec681f3Smrg regval &= typeinfo_mask(&bf->typeinfo); 3657ec681f3Smrg regval >>= bf->typeinfo.low; 3667ec681f3Smrg regval <<= bf->typeinfo.shr; 3677ec681f3Smrg 3687ec681f3Smrg DBG("name=%s, info=%p, subelemsnum=%d, type=%d, regval=%x", name, info, 3697ec681f3Smrg rnndoff->elem->subelemsnum, bf->typeinfo.type, regval); 3707ec681f3Smrg 3717ec681f3Smrg return pushdecval(L, rnndoff->rnn, regval, &bf->typeinfo); 3727ec681f3Smrg } 3737ec681f3Smrg } 3747ec681f3Smrg 3757ec681f3Smrg printf("invalid member: %s\n", name); 3767ec681f3Smrg return 0; 3777ec681f3Smrg} 3787ec681f3Smrg 3797ec681f3Smrgstatic int 3807ec681f3Smrgl_rnn_reg_meta_tostring(lua_State *L) 3817ec681f3Smrg{ 3827ec681f3Smrg struct rnndoff *rnndoff = lua_touserdata(L, 1); 3837ec681f3Smrg uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset); 3847ec681f3Smrg struct rnndecaddrinfo *info = rnn_reginfo(rnndoff->rnn, rnndoff->offset); 3857ec681f3Smrg char *decoded; 3867ec681f3Smrg if (info && info->typeinfo) { 3877ec681f3Smrg decoded = rnndec_decodeval(rnndoff->rnn->vc, info->typeinfo, regval); 3887ec681f3Smrg } else { 3897ec681f3Smrg asprintf(&decoded, "%08x", regval); 3907ec681f3Smrg } 3917ec681f3Smrg lua_pushstring(L, decoded); 3927ec681f3Smrg free(decoded); 3937ec681f3Smrg if (info) { 3947ec681f3Smrg free(info->name); 3957ec681f3Smrg free(info); 3967ec681f3Smrg } 3977ec681f3Smrg return 1; 3987ec681f3Smrg} 3997ec681f3Smrg 4007ec681f3Smrgstatic int 4017ec681f3Smrgl_rnn_reg_meta_tonumber(lua_State *L) 4027ec681f3Smrg{ 4037ec681f3Smrg struct rnndoff *rnndoff = lua_touserdata(L, 1); 4047ec681f3Smrg uint32_t regval = rnn_val(rnndoff->rnn, rnndoff->offset); 4057ec681f3Smrg 4067ec681f3Smrg regval <<= rnndoff->elem->typeinfo.shr; 4077ec681f3Smrg 4087ec681f3Smrg lua_pushnumber(L, regval); 4097ec681f3Smrg return 1; 4107ec681f3Smrg} 4117ec681f3Smrg 4127ec681f3Smrgstatic const struct luaL_Reg l_meta_rnn_reg[] = { 4137ec681f3Smrg {"__index", l_rnn_reg_meta_index}, 4147ec681f3Smrg {"__tostring", l_rnn_reg_meta_tostring}, 4157ec681f3Smrg {"__tonumber", l_rnn_reg_meta_tonumber}, 4167ec681f3Smrg {NULL, NULL} /* sentinel */ 4177ec681f3Smrg}; 4187ec681f3Smrg 4197ec681f3Smrgstatic int 4207ec681f3Smrgl_rnn_etype_reg(lua_State *L, struct rnn *rnn, struct rnndelem *elem, 4217ec681f3Smrg uint64_t offset) 4227ec681f3Smrg{ 4237ec681f3Smrg push_rnndoff(L, rnn, elem, offset); 4247ec681f3Smrg 4257ec681f3Smrg luaL_newmetatable(L, "rnnmetareg"); 4267ec681f3Smrg luaL_setfuncs(L, l_meta_rnn_reg, 0); 4277ec681f3Smrg lua_pop(L, 1); 4287ec681f3Smrg 4297ec681f3Smrg luaL_setmetatable(L, "rnnmetareg"); 4307ec681f3Smrg 4317ec681f3Smrg return 1; 4327ec681f3Smrg} 4337ec681f3Smrg 4347ec681f3Smrg/* 4357ec681f3Smrg * 4367ec681f3Smrg */ 4377ec681f3Smrg 4387ec681f3Smrgstatic int 4397ec681f3Smrgl_rnn_meta_index(lua_State *L) 4407ec681f3Smrg{ 4417ec681f3Smrg struct rnn *rnn = lua_touserdata(L, 1); 4427ec681f3Smrg const char *name = lua_tostring(L, 2); 4437ec681f3Smrg struct rnndelem *elem; 4447ec681f3Smrg 4457ec681f3Smrg elem = rnn_regelem(rnn, name); 4467ec681f3Smrg if (!elem) 4477ec681f3Smrg return 0; 4487ec681f3Smrg 4497ec681f3Smrg return l_rnn_etype(L, rnn, elem, elem->offset); 4507ec681f3Smrg} 4517ec681f3Smrg 4527ec681f3Smrgstatic int 4537ec681f3Smrgl_rnn_meta_gc(lua_State *L) 4547ec681f3Smrg{ 4557ec681f3Smrg // TODO 4567ec681f3Smrg // struct rnn *rnn = lua_touserdata(L, 1); 4577ec681f3Smrg // rnn_deinit(rnn); 4587ec681f3Smrg return 0; 4597ec681f3Smrg} 4607ec681f3Smrg 4617ec681f3Smrgstatic const struct luaL_Reg l_meta_rnn[] = { 4627ec681f3Smrg {"__index", l_rnn_meta_index}, 4637ec681f3Smrg {"__gc", l_rnn_meta_gc}, 4647ec681f3Smrg {NULL, NULL} /* sentinel */ 4657ec681f3Smrg}; 4667ec681f3Smrg 4677ec681f3Smrgstatic int 4687ec681f3Smrgl_rnn_init(lua_State *L) 4697ec681f3Smrg{ 4707ec681f3Smrg const char *gpuname = lua_tostring(L, 1); 4717ec681f3Smrg struct rnndec *rnndec = lua_newuserdata(L, sizeof(*rnndec)); 4727ec681f3Smrg _rnn_init(&rnndec->base, 0); 4737ec681f3Smrg rnn_load(&rnndec->base, gpuname); 4747ec681f3Smrg rnndec->sizedwords = 0; 4757ec681f3Smrg 4767ec681f3Smrg luaL_newmetatable(L, "rnnmeta"); 4777ec681f3Smrg luaL_setfuncs(L, l_meta_rnn, 0); 4787ec681f3Smrg lua_pop(L, 1); 4797ec681f3Smrg 4807ec681f3Smrg luaL_setmetatable(L, "rnnmeta"); 4817ec681f3Smrg 4827ec681f3Smrg return 1; 4837ec681f3Smrg} 4847ec681f3Smrg 4857ec681f3Smrgstatic int 4867ec681f3Smrgl_rnn_enumname(lua_State *L) 4877ec681f3Smrg{ 4887ec681f3Smrg struct rnn *rnn = lua_touserdata(L, 1); 4897ec681f3Smrg const char *name = lua_tostring(L, 2); 4907ec681f3Smrg uint32_t val = (uint32_t)lua_tonumber(L, 3); 4917ec681f3Smrg lua_pushstring(L, rnn_enumname(rnn, name, val)); 4927ec681f3Smrg return 1; 4937ec681f3Smrg} 4947ec681f3Smrg 4957ec681f3Smrgstatic int 4967ec681f3Smrgl_rnn_regname(lua_State *L) 4977ec681f3Smrg{ 4987ec681f3Smrg struct rnn *rnn = lua_touserdata(L, 1); 4997ec681f3Smrg uint32_t regbase = (uint32_t)lua_tonumber(L, 2); 5007ec681f3Smrg lua_pushstring(L, rnn_regname(rnn, regbase, 1)); 5017ec681f3Smrg return 1; 5027ec681f3Smrg} 5037ec681f3Smrg 5047ec681f3Smrgstatic int 5057ec681f3Smrgl_rnn_regval(lua_State *L) 5067ec681f3Smrg{ 5077ec681f3Smrg struct rnn *rnn = lua_touserdata(L, 1); 5087ec681f3Smrg uint32_t regbase = (uint32_t)lua_tonumber(L, 2); 5097ec681f3Smrg uint32_t regval = (uint32_t)lua_tonumber(L, 3); 5107ec681f3Smrg struct rnndecaddrinfo *info = rnn_reginfo(rnn, regbase); 5117ec681f3Smrg char *decoded; 5127ec681f3Smrg if (info && info->typeinfo) { 5137ec681f3Smrg decoded = rnndec_decodeval(rnn->vc, info->typeinfo, regval); 5147ec681f3Smrg } else { 5157ec681f3Smrg asprintf(&decoded, "%08x", regval); 5167ec681f3Smrg } 5177ec681f3Smrg lua_pushstring(L, decoded); 5187ec681f3Smrg free(decoded); 5197ec681f3Smrg if (info) { 5207ec681f3Smrg free(info->name); 5217ec681f3Smrg free(info); 5227ec681f3Smrg } 5237ec681f3Smrg return 1; 5247ec681f3Smrg} 5257ec681f3Smrg 5267ec681f3Smrgstatic const struct luaL_Reg l_rnn[] = { 5277ec681f3Smrg {"init", l_rnn_init}, 5287ec681f3Smrg {"enumname", l_rnn_enumname}, 5297ec681f3Smrg {"regname", l_rnn_regname}, 5307ec681f3Smrg {"regval", l_rnn_regval}, 5317ec681f3Smrg {NULL, NULL} /* sentinel */ 5327ec681f3Smrg}; 5337ec681f3Smrg 5347ec681f3Smrg/* Expose the register state to script enviroment as a "regs" library: 5357ec681f3Smrg */ 5367ec681f3Smrg 5377ec681f3Smrgstatic int 5387ec681f3Smrgl_reg_written(lua_State *L) 5397ec681f3Smrg{ 5407ec681f3Smrg uint32_t regbase = (uint32_t)lua_tonumber(L, 1); 5417ec681f3Smrg lua_pushnumber(L, reg_written(regbase)); 5427ec681f3Smrg return 1; 5437ec681f3Smrg} 5447ec681f3Smrg 5457ec681f3Smrgstatic int 5467ec681f3Smrgl_reg_lastval(lua_State *L) 5477ec681f3Smrg{ 5487ec681f3Smrg uint32_t regbase = (uint32_t)lua_tonumber(L, 1); 5497ec681f3Smrg lua_pushnumber(L, reg_lastval(regbase)); 5507ec681f3Smrg return 1; 5517ec681f3Smrg} 5527ec681f3Smrg 5537ec681f3Smrgstatic int 5547ec681f3Smrgl_reg_val(lua_State *L) 5557ec681f3Smrg{ 5567ec681f3Smrg uint32_t regbase = (uint32_t)lua_tonumber(L, 1); 5577ec681f3Smrg lua_pushnumber(L, reg_val(regbase)); 5587ec681f3Smrg return 1; 5597ec681f3Smrg} 5607ec681f3Smrg 5617ec681f3Smrgstatic const struct luaL_Reg l_regs[] = { 5627ec681f3Smrg {"written", l_reg_written}, 5637ec681f3Smrg {"lastval", l_reg_lastval}, 5647ec681f3Smrg {"val", l_reg_val}, 5657ec681f3Smrg {NULL, NULL} /* sentinel */ 5667ec681f3Smrg}; 5677ec681f3Smrg 5687ec681f3Smrg/* Expose API to lookup snapshot buffers: 5697ec681f3Smrg */ 5707ec681f3Smrg 5717ec681f3Smrguint64_t gpubaseaddr(uint64_t gpuaddr); 5727ec681f3Smrgunsigned hostlen(uint64_t gpuaddr); 5737ec681f3Smrg 5747ec681f3Smrg/* given address, return base-address of buffer: */ 5757ec681f3Smrgstatic int 5767ec681f3Smrgl_bo_base(lua_State *L) 5777ec681f3Smrg{ 5787ec681f3Smrg uint64_t addr = (uint64_t)lua_tonumber(L, 1); 5797ec681f3Smrg lua_pushnumber(L, gpubaseaddr(addr)); 5807ec681f3Smrg return 1; 5817ec681f3Smrg} 5827ec681f3Smrg 5837ec681f3Smrg/* given address, return the remaining size of the buffer: */ 5847ec681f3Smrgstatic int 5857ec681f3Smrgl_bo_size(lua_State *L) 5867ec681f3Smrg{ 5877ec681f3Smrg uint64_t addr = (uint64_t)lua_tonumber(L, 1); 5887ec681f3Smrg lua_pushnumber(L, hostlen(addr)); 5897ec681f3Smrg return 1; 5907ec681f3Smrg} 5917ec681f3Smrg 5927ec681f3Smrgstatic const struct luaL_Reg l_bos[] = { 5937ec681f3Smrg {"base", l_bo_base}, {"size", l_bo_size}, {NULL, NULL} /* sentinel */ 5947ec681f3Smrg}; 5957ec681f3Smrg 5967ec681f3Smrgstatic void 5977ec681f3Smrgopenlib(const char *lib, const luaL_Reg *reg) 5987ec681f3Smrg{ 5997ec681f3Smrg lua_newtable(L); 6007ec681f3Smrg luaL_setfuncs(L, reg, 0); 6017ec681f3Smrg lua_setglobal(L, lib); 6027ec681f3Smrg} 6037ec681f3Smrg 6047ec681f3Smrg/* called at start to load the script: */ 6057ec681f3Smrgint 6067ec681f3Smrgscript_load(const char *file) 6077ec681f3Smrg{ 6087ec681f3Smrg int ret; 6097ec681f3Smrg 6107ec681f3Smrg assert(!L); 6117ec681f3Smrg 6127ec681f3Smrg L = luaL_newstate(); 6137ec681f3Smrg luaL_openlibs(L); 6147ec681f3Smrg openlib("bos", l_bos); 6157ec681f3Smrg openlib("regs", l_regs); 6167ec681f3Smrg openlib("rnn", l_rnn); 6177ec681f3Smrg 6187ec681f3Smrg ret = luaL_loadfile(L, file); 6197ec681f3Smrg if (ret) 6207ec681f3Smrg error("%s\n"); 6217ec681f3Smrg 6227ec681f3Smrg ret = lua_pcall(L, 0, LUA_MULTRET, 0); 6237ec681f3Smrg if (ret) 6247ec681f3Smrg error("%s\n"); 6257ec681f3Smrg 6267ec681f3Smrg return 0; 6277ec681f3Smrg} 6287ec681f3Smrg 6297ec681f3Smrg/* called at start of each cmdstream file: */ 6307ec681f3Smrgvoid 6317ec681f3Smrgscript_start_cmdstream(const char *name) 6327ec681f3Smrg{ 6337ec681f3Smrg if (!L) 6347ec681f3Smrg return; 6357ec681f3Smrg 6367ec681f3Smrg lua_getglobal(L, "start_cmdstream"); 6377ec681f3Smrg 6387ec681f3Smrg /* if no handler just ignore it: */ 6397ec681f3Smrg if (!lua_isfunction(L, -1)) { 6407ec681f3Smrg lua_pop(L, 1); 6417ec681f3Smrg return; 6427ec681f3Smrg } 6437ec681f3Smrg 6447ec681f3Smrg lua_pushstring(L, name); 6457ec681f3Smrg 6467ec681f3Smrg /* do the call (1 arguments, 0 result) */ 6477ec681f3Smrg if (lua_pcall(L, 1, 0, 0) != 0) 6487ec681f3Smrg error("error running function `f': %s\n"); 6497ec681f3Smrg} 6507ec681f3Smrg 6517ec681f3Smrg/* called at each DRAW_INDX, calls script drawidx fxn to process 6527ec681f3Smrg * the current state 6537ec681f3Smrg */ 6547ec681f3Smrgvoid 6557ec681f3Smrgscript_draw(const char *primtype, uint32_t nindx) 6567ec681f3Smrg{ 6577ec681f3Smrg if (!L) 6587ec681f3Smrg return; 6597ec681f3Smrg 6607ec681f3Smrg lua_getglobal(L, "draw"); 6617ec681f3Smrg 6627ec681f3Smrg /* if no handler just ignore it: */ 6637ec681f3Smrg if (!lua_isfunction(L, -1)) { 6647ec681f3Smrg lua_pop(L, 1); 6657ec681f3Smrg return; 6667ec681f3Smrg } 6677ec681f3Smrg 6687ec681f3Smrg lua_pushstring(L, primtype); 6697ec681f3Smrg lua_pushnumber(L, nindx); 6707ec681f3Smrg 6717ec681f3Smrg /* do the call (2 arguments, 0 result) */ 6727ec681f3Smrg if (lua_pcall(L, 2, 0, 0) != 0) 6737ec681f3Smrg error("error running function `f': %s\n"); 6747ec681f3Smrg} 6757ec681f3Smrg 6767ec681f3Smrgstatic int 6777ec681f3Smrgl_rnn_meta_dom_index(lua_State *L) 6787ec681f3Smrg{ 6797ec681f3Smrg struct rnn *rnn = lua_touserdata(L, 1); 6807ec681f3Smrg uint32_t offset = (uint32_t)lua_tonumber(L, 2); 6817ec681f3Smrg struct rnndelem *elem; 6827ec681f3Smrg 6837ec681f3Smrg /* TODO might be nicer if the arg isn't a number, to search the domain 6847ec681f3Smrg * for matching bitfields.. so that the script could do something like 6857ec681f3Smrg * 'pkt.WIDTH' insteadl of 'pkt[1].WIDTH', ie. not have to remember the 6867ec681f3Smrg * offset of the dword containing the bitfield.. 6877ec681f3Smrg */ 6887ec681f3Smrg 6897ec681f3Smrg elem = rnn_regoff(rnn, offset); 6907ec681f3Smrg if (!elem) 6917ec681f3Smrg return 0; 6927ec681f3Smrg 6937ec681f3Smrg return l_rnn_etype(L, rnn, elem, elem->offset); 6947ec681f3Smrg} 6957ec681f3Smrg 6967ec681f3Smrg/* 6977ec681f3Smrg * A wrapper object for rnndomain based decoding of an array of dwords 6987ec681f3Smrg * (ie. for pm4 packet decoding). Mostly re-uses the register-value 6997ec681f3Smrg * decoding for the individual dwords and bitfields. 7007ec681f3Smrg */ 7017ec681f3Smrg 7027ec681f3Smrgstatic int 7037ec681f3Smrgl_rnn_meta_dom_gc(lua_State *L) 7047ec681f3Smrg{ 7057ec681f3Smrg // TODO 7067ec681f3Smrg // struct rnn *rnn = lua_touserdata(L, 1); 7077ec681f3Smrg // rnn_deinit(rnn); 7087ec681f3Smrg return 0; 7097ec681f3Smrg} 7107ec681f3Smrg 7117ec681f3Smrgstatic const struct luaL_Reg l_meta_rnn_dom[] = { 7127ec681f3Smrg {"__index", l_rnn_meta_dom_index}, 7137ec681f3Smrg {"__gc", l_rnn_meta_dom_gc}, 7147ec681f3Smrg {NULL, NULL} /* sentinel */ 7157ec681f3Smrg}; 7167ec681f3Smrg 7177ec681f3Smrg/* called to general pm4 packet decoding, such as texture/sampler state 7187ec681f3Smrg */ 7197ec681f3Smrgvoid 7207ec681f3Smrgscript_packet(uint32_t *dwords, uint32_t sizedwords, struct rnn *rnn, 7217ec681f3Smrg struct rnndomain *dom) 7227ec681f3Smrg{ 7237ec681f3Smrg if (!L) 7247ec681f3Smrg return; 7257ec681f3Smrg 7267ec681f3Smrg lua_getglobal(L, dom->name); 7277ec681f3Smrg 7287ec681f3Smrg /* if no handler for the packet, just ignore it: */ 7297ec681f3Smrg if (!lua_isfunction(L, -1)) { 7307ec681f3Smrg lua_pop(L, 1); 7317ec681f3Smrg return; 7327ec681f3Smrg } 7337ec681f3Smrg 7347ec681f3Smrg struct rnndec *rnndec = lua_newuserdata(L, sizeof(*rnndec)); 7357ec681f3Smrg 7367ec681f3Smrg rnndec->base = *rnn; 7377ec681f3Smrg rnndec->base.dom[0] = dom; 7387ec681f3Smrg rnndec->base.dom[1] = NULL; 7397ec681f3Smrg rnndec->dwords = dwords; 7407ec681f3Smrg rnndec->sizedwords = sizedwords; 7417ec681f3Smrg 7427ec681f3Smrg luaL_newmetatable(L, "rnnmetadom"); 7437ec681f3Smrg luaL_setfuncs(L, l_meta_rnn_dom, 0); 7447ec681f3Smrg lua_pop(L, 1); 7457ec681f3Smrg 7467ec681f3Smrg luaL_setmetatable(L, "rnnmetadom"); 7477ec681f3Smrg 7487ec681f3Smrg lua_pushnumber(L, sizedwords); 7497ec681f3Smrg 7507ec681f3Smrg if (lua_pcall(L, 2, 0, 0) != 0) 7517ec681f3Smrg error("error running function `f': %s\n"); 7527ec681f3Smrg} 7537ec681f3Smrg 7547ec681f3Smrg/* helper to call fxn that takes and returns void: */ 7557ec681f3Smrgstatic void 7567ec681f3Smrgsimple_call(const char *name) 7577ec681f3Smrg{ 7587ec681f3Smrg if (!L) 7597ec681f3Smrg return; 7607ec681f3Smrg 7617ec681f3Smrg lua_getglobal(L, name); 7627ec681f3Smrg 7637ec681f3Smrg /* if no handler just ignore it: */ 7647ec681f3Smrg if (!lua_isfunction(L, -1)) { 7657ec681f3Smrg lua_pop(L, 1); 7667ec681f3Smrg return; 7677ec681f3Smrg } 7687ec681f3Smrg 7697ec681f3Smrg /* do the call (0 arguments, 0 result) */ 7707ec681f3Smrg if (lua_pcall(L, 0, 0, 0) != 0) 7717ec681f3Smrg error("error running function `f': %s\n"); 7727ec681f3Smrg} 7737ec681f3Smrg 7747ec681f3Smrg/* called at end of each cmdstream file: */ 7757ec681f3Smrgvoid 7767ec681f3Smrgscript_end_cmdstream(void) 7777ec681f3Smrg{ 7787ec681f3Smrg simple_call("end_cmdstream"); 7797ec681f3Smrg} 7807ec681f3Smrg 7817ec681f3Smrg/* called at start of submit/issueibcmds: */ 7827ec681f3Smrgvoid 7837ec681f3Smrgscript_start_submit(void) 7847ec681f3Smrg{ 7857ec681f3Smrg simple_call("start_submit"); 7867ec681f3Smrg} 7877ec681f3Smrg 7887ec681f3Smrg/* called at end of submit/issueibcmds: */ 7897ec681f3Smrgvoid 7907ec681f3Smrgscript_end_submit(void) 7917ec681f3Smrg{ 7927ec681f3Smrg simple_call("end_submit"); 7937ec681f3Smrg} 7947ec681f3Smrg 7957ec681f3Smrg/* called after last cmdstream file: */ 7967ec681f3Smrgvoid 7977ec681f3Smrgscript_finish(void) 7987ec681f3Smrg{ 7997ec681f3Smrg if (!L) 8007ec681f3Smrg return; 8017ec681f3Smrg 8027ec681f3Smrg simple_call("finish"); 8037ec681f3Smrg 8047ec681f3Smrg lua_close(L); 8057ec681f3Smrg L = NULL; 8067ec681f3Smrg} 807