/* * Copyright 2011 Jerome Glisse * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * on the rights to use, copy, modify, merge, publish, distribute, sub * license, and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice (including the next * paragraph) shall be included in all copies or substantial portions of the * Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE * USE OR OTHER DEALINGS IN THE SOFTWARE. * * Authors: * Jerome Glisse */ #include #include #include #include #include #include "bof.h" struct bo { unsigned size; uint64_t offset; uint32_t handle; void *data; }; struct cs { unsigned pm4_ndw; unsigned reloc_ndw; unsigned nbo; struct bo *bo; uint32_t device_id; uint32_t *pm4; uint32_t *reloc; }; void *copy_object(void *ptr, unsigned size) { void *copy; copy = calloc(1, size); if (copy == NULL) return NULL; memcpy(copy, ptr, size); return copy; } int cs_bof_load(struct cs *cs, const char *filename) { bof_t *bof; bof_t *tmp, *array, *bo; int r, i; memset(cs, 0, sizeof(struct cs)); bof = bof_load_file(filename); if (bof == NULL) { fprintf(stderr, "%s:%d failed to load %s\n", __func__, __LINE__, filename); return -EINVAL; } /* device id */ tmp = bof_object_get(bof, "device_id"); if (tmp == NULL) { fprintf(stderr, "no device object\n"); goto out_err; } cs->device_id = bof_int32_value(tmp); /* pm4 */ tmp = bof_object_get(bof, "pm4"); if (tmp == NULL) { fprintf(stderr, "no pm4 object\n"); goto out_err; } cs->pm4_ndw = bof_blob_size(tmp) / 4; cs->pm4 = copy_object(bof_blob_value(tmp), bof_blob_size(tmp)); if (cs->pm4 == NULL) { goto out_err; } /* reloc */ tmp = bof_object_get(bof, "reloc"); if (tmp == NULL) { fprintf(stderr, "no reloc object\n"); r = -EINVAL; goto out_err; } cs->reloc_ndw = bof_blob_size(tmp) / 4; cs->reloc = copy_object(bof_blob_value(tmp), bof_blob_size(tmp)); if (cs->reloc == NULL) { fprintf(stderr, "%s failed to allocate reloc\n", __func__); goto out_err; } /* bo */ array = bof_object_get(bof, "bo"); if (array == NULL) { fprintf(stderr, "no bo array object\n"); r = -EINVAL; goto out_err; } cs->nbo = bof_array_size(array); if ((cs->reloc_ndw / 4) > cs->nbo) { cs->reloc_ndw = cs->nbo * 4; } cs->bo = calloc(1, sizeof(struct bo) * cs->nbo); if (cs->bo == NULL) { fprintf(stderr, "%s failed to allocate bo\n", __func__); goto out_err; } for (i = 0; i < bof_array_size(array); i++) { bo = bof_array_get(array, i); if (bo == NULL) { fprintf(stderr, "can't get %d bo\n", i); goto out_err; } tmp = bof_object_get(bo, "size"); if (tmp == NULL) { fprintf(stderr, "can't get %d bo size\n", i); goto out_err; } cs->bo[i].size = bof_int32_value(tmp); tmp = bof_object_get(bo, "offset"); if (tmp == NULL) { fprintf(stderr, "can't get %d bo offset\n", i); goto out_err; } cs->bo[i].offset = bof_int64_value(tmp); tmp = bof_object_get(bo, "handle"); if (tmp == NULL) { fprintf(stderr, "can't get %d bo handle\n", i); goto out_err; } cs->bo[i].handle = bof_int32_value(tmp); tmp = bof_object_get(bo, "data"); if (tmp == NULL) { fprintf(stderr, "can't get %d bo data from %p of %p\n", i, bo, array); goto out_err; } cs->bo[i].data = copy_object(bof_blob_value(tmp), bof_blob_size(tmp)); if (cs->bo[i].data == NULL) { fprintf(stderr, "%s failed to allocate bo (%d)\n", __func__, cs->bo[i].size); goto out_err; } } bof_decref(bof); return 0; out_err: bof_decref(bof); for (i = 0; i < cs->nbo; i++) { free(cs->bo[i].data); } free(cs->pm4); free(cs->reloc); free(cs->bo); memset(cs, 0, sizeof(struct cs)); return -EINVAL; } json_t *copy_to_array(unsigned size, void *data) { uint32_t *ptr = data; unsigned i; json_t *array, *value; char tmp[16]; array = json_array(); if (array == NULL) { return NULL; } for (i = 0; i < size / 4; i++) { sprintf(tmp, "0x%08X", ptr[i]); value = json_string(tmp); if (value == NULL) { goto out_err; } if (json_array_append_new(array, value)) { goto out_err; } } return array; out_err: json_decref(array); return NULL; } int cs_json_dump(struct cs *cs, const char *filename) { json_t *json, *tmp, *bo_array, *bo; unsigned i; int r = 0; json = json_object(); if (json == NULL) { return -ENOMEM; } /* device id */ tmp = json_integer(cs->device_id); if (tmp == NULL) { fprintf(stderr, "%s failed to create json device_id object\n", __func__); r = -EINVAL; goto out_err; } json_object_set_new(json, "device_id", tmp); /* pm4 */ tmp = copy_to_array(cs->pm4_ndw * 4, cs->pm4); if (tmp == NULL) { fprintf(stderr, "%s failed to create json pm4 object\n", __func__); r = -EINVAL; goto out_err; } json_object_set_new(json, "pm4", tmp); /* reloc */ tmp = copy_to_array(cs->reloc_ndw * 4, cs->reloc); if (tmp == NULL) { fprintf(stderr, "%s failed to create json reloc object\n", __func__); r = -EINVAL; goto out_err; } json_object_set_new(json, "reloc", tmp); /* draw array */ bo_array = json_array(); if (bo_array == NULL) { fprintf(stderr, "%s failed to create json bo array\n", __func__); r = -EINVAL; goto out_err; } json_object_set_new(json, "bo", bo_array); for (i = 0; i < cs->nbo; i++) { bo = json_object(); if (bo == NULL) { fprintf(stderr, "%s failed to create json bo[%d]\n", __func__, i); r = -EINVAL; goto out_err; } if (json_array_append_new(bo_array, bo)) { json_decref(bo); r = -EINVAL; goto out_err; } tmp = json_integer(cs->bo[i].size); if (tmp == NULL) { fprintf(stderr, "%s failed to create bo[%d] size object\n", __func__, i); r = -EINVAL; goto out_err; } json_object_set_new(bo, "size", tmp); tmp = json_integer(cs->bo[i].offset); if (tmp == NULL) { fprintf(stderr, "%s failed to create bo[%d] offset object\n", __func__, i); r = -EINVAL; goto out_err; } json_object_set_new(bo, "offset", tmp); tmp = json_integer(cs->bo[i].handle); if (tmp == NULL) { fprintf(stderr, "%s failed to create bo[%d] size object\n", __func__, i); r = -EINVAL; goto out_err; } json_object_set_new(bo, "handle", tmp); tmp = copy_to_array(cs->bo[i].size, cs->bo[i].data); if (tmp == NULL) { fprintf(stderr, "%s failed to create bo[%d] data object\n", __func__, i); r = -EINVAL; goto out_err; } json_object_set_new(bo, "data", tmp); } r = json_dump_file(json, filename, JSON_INDENT(2) | JSON_SORT_KEYS); out_err: json_decref(json); return r; } int main(int argc, char *argv[]) { struct cs cs; if (argc != 3) { fprintf(stderr, "usage : %s bofile jsonfile\n", argv[0]); return -EINVAL; } if (cs_bof_load(&cs, argv[1])) { return -EINVAL; } if (cs_json_dump(&cs, argv[2])) { return -EINVAL; } return 0; }