From 01e6fac4d61fdd7fff5433942ec93fc2ea1e4df1 Mon Sep 17 00:00:00 2001 From: Joshua Bakita Date: Wed, 28 Jun 2023 18:24:25 -0400 Subject: Include nvgpu headers These are needed to build on NVIDIA's Jetson boards for the time being. Only a couple structs are required, so it should be fairly easy to remove this dependency at some point in the future. --- include/boardobj/boardobj.c | 102 ++++ include/boardobj/boardobj.h | 104 ++++ include/boardobj/boardobjgrp.c | 1046 +++++++++++++++++++++++++++++++++++ include/boardobj/boardobjgrp.h | 441 +++++++++++++++ include/boardobj/boardobjgrp_e255.c | 91 +++ include/boardobj/boardobjgrp_e255.h | 51 ++ include/boardobj/boardobjgrp_e32.c | 89 +++ include/boardobj/boardobjgrp_e32.h | 66 +++ include/boardobj/boardobjgrpmask.c | 411 ++++++++++++++ include/boardobj/boardobjgrpmask.h | 119 ++++ 10 files changed, 2520 insertions(+) create mode 100644 include/boardobj/boardobj.c create mode 100644 include/boardobj/boardobj.h create mode 100644 include/boardobj/boardobjgrp.c create mode 100644 include/boardobj/boardobjgrp.h create mode 100644 include/boardobj/boardobjgrp_e255.c create mode 100644 include/boardobj/boardobjgrp_e255.h create mode 100644 include/boardobj/boardobjgrp_e32.c create mode 100644 include/boardobj/boardobjgrp_e32.h create mode 100644 include/boardobj/boardobjgrpmask.c create mode 100644 include/boardobj/boardobjgrpmask.h (limited to 'include/boardobj') diff --git a/include/boardobj/boardobj.c b/include/boardobj/boardobj.c new file mode 100644 index 0000000..2044b5b --- /dev/null +++ b/include/boardobj/boardobj.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#include +#include + +#include "boardobj.h" +#include "ctrl/ctrlboardobj.h" + +int boardobj_construct_super(struct gk20a *g, struct boardobj **ppboardobj, + u16 size, void *args) +{ + struct boardobj *pboardobj = NULL; + struct boardobj *devtmp = (struct boardobj *)args; + + nvgpu_log_info(g, " "); + + if (devtmp == NULL) { + return -EINVAL; + } + + if (*ppboardobj == NULL) { + *ppboardobj = nvgpu_kzalloc(g, size); + if (*ppboardobj == NULL) { + return -ENOMEM; + } + (*ppboardobj)->allocated = true; + } + + pboardobj = *ppboardobj; + pboardobj->g = g; + pboardobj->type = devtmp->type; + pboardobj->idx = CTRL_BOARDOBJ_IDX_INVALID; + pboardobj->type_mask = BIT(pboardobj->type) | devtmp->type_mask; + + pboardobj->implements = boardobj_implements_super; + pboardobj->destruct = boardobj_destruct_super; + pboardobj->pmudatainit = boardobj_pmudatainit_super; + + nvgpu_list_add(&pboardobj->node, &g->boardobj_head); + + return 0; +} + +int boardobj_destruct_super(struct boardobj *pboardobj) +{ + struct gk20a *g = pboardobj->g; + + nvgpu_log_info(g, " "); + if (pboardobj == NULL) { + return -EINVAL; + } + + nvgpu_list_del(&pboardobj->node); + if (pboardobj->allocated) { + nvgpu_kfree(pboardobj->g, pboardobj); + } + + return 0; +} + +bool boardobj_implements_super(struct gk20a *g, struct boardobj *pboardobj, + u8 type) +{ + nvgpu_log_info(g, " "); + + return (0 != (pboardobj->type_mask & BIT(type))); +} + +int boardobj_pmudatainit_super(struct gk20a *g, struct boardobj *pboardobj, + struct nv_pmu_boardobj *pmudata) +{ + nvgpu_log_info(g, " "); + if (pboardobj == NULL) { + return -EINVAL; + } + if (pmudata == NULL) { + return -EINVAL; + } + pmudata->type = pboardobj->type; + nvgpu_log_info(g, " Done"); + return 0; +} diff --git a/include/boardobj/boardobj.h b/include/boardobj/boardobj.h new file mode 100644 index 0000000..b1be9bd --- /dev/null +++ b/include/boardobj/boardobj.h @@ -0,0 +1,104 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#ifndef NVGPU_BOARDOBJ_H +#define NVGPU_BOARDOBJ_H + +#include +#include + +#include "ctrl/ctrlboardobj.h" + +struct boardobj; +struct nvgpu_list_node; + +/* +* check whether the specified BOARDOBJ object implements the queried +* type/class enumeration. +*/ +typedef bool boardobj_implements(struct gk20a *g, struct boardobj *pboardobj, + u8 type); + +/* +* Fills out the appropriate the nv_pmu_xxxx_device_desc_ driver->PMU +* description structure, describing this BOARDOBJ board device to the PMU. +* +*/ +typedef int boardobj_pmudatainit(struct gk20a *g, struct boardobj *pboardobj, + struct nv_pmu_boardobj *pmudata); + +/* +* Constructor for the base Board Object. Called by each device-specific +* implementation of the BOARDOBJ interface to initialize the board object. +*/ +typedef int boardobj_construct(struct gk20a *g, struct boardobj **pboardobj, + u16 size, void *args); + +/* +* Destructor for the base board object. Called by each device-Specific +* implementation of the BOARDOBJ interface to destroy the board object. +* This has to be explicitly set by each device that extends from the +* board object. +*/ +typedef int boardobj_destruct(struct boardobj *pboardobj); + +/* +* Base Class for all physical or logical device on the PCB. +* Contains fields common to all devices on the board. Specific types of +* devices may extend this object adding any details specific to that +* device or device-type. +*/ + +struct boardobj { + struct gk20a *g; + + u8 type; /*type of the device*/ + u8 idx; /*index of boardobj within in its group*/ + /* true if allocated in constructor. destructor should free */ + u8 allocated; + u32 type_mask; /*mask of types this boardobjimplements*/ + boardobj_implements *implements; + boardobj_destruct *destruct; + /* + * Access interface apis which will be overridden by the devices + * that inherit from BOARDOBJ + */ + boardobj_pmudatainit *pmudatainit; + struct nvgpu_list_node node; +}; + +boardobj_construct boardobj_construct_super; +boardobj_destruct boardobj_destruct_super; +boardobj_implements boardobj_implements_super; +boardobj_pmudatainit boardobj_pmudatainit_super; + +#define BOARDOBJ_GET_TYPE(pobj) (((struct boardobj *)(pobj))->type) +#define BOARDOBJ_GET_IDX(pobj) (((struct boardobj *)(pobj))->idx) + +static inline struct boardobj * +boardobj_from_node(struct nvgpu_list_node *node) +{ + return (struct boardobj *) + ((uintptr_t)node - offsetof(struct boardobj, node)); +}; + +#endif /* NVGPU_BOARDOBJ_H */ diff --git a/include/boardobj/boardobjgrp.c b/include/boardobj/boardobjgrp.c new file mode 100644 index 0000000..6832070 --- /dev/null +++ b/include/boardobj/boardobjgrp.c @@ -0,0 +1,1046 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. +*/ +#include +#include + +#include "boardobjgrp.h" +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" + +static boardobjgrp_objinsert boardobjgrp_objinsert_final; +static boardobjgrp_objgetbyidx boardobjgrp_objgetbyidx_final; +static boardobjgrp_objgetnext boardobjgrp_objgetnext_final; +static boardobjgrp_objremoveanddestroy boardobjgrp_objremoveanddestroy_final; +static boardobjgrp_pmudatainstget boardobjgrp_pmudatainstget_stub; +static boardobjgrp_pmustatusinstget boardobjgrp_pmustatusinstget_stub; +static int boardobjgrp_pmucmdsend(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd); +static int boardobjgrp_pmucmdsend_rpc(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd, + bool copy_out); +struct boardobjgrp_pmucmdhandler_params { + /* Pointer to the BOARDOBJGRP associated with this CMD */ + struct boardobjgrp *pboardobjgrp; + /* Pointer to structure representing this NV_PMU_BOARDOBJ_CMD_GRP */ + struct boardobjgrp_pmu_cmd *pcmd; + /* Boolean indicating whether the PMU successfully handled the CMD */ + u32 success; +}; + +int boardobjgrp_construct_super(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobjgrp->ppobjects == NULL) { + return -EINVAL; + } + + if (pboardobjgrp->mask == NULL) { + return -EINVAL; + } + + pboardobjgrp->g = g; + pboardobjgrp->objmask = 0; + + pboardobjgrp->classid = 0; + pboardobjgrp->pmu.unitid = BOARDOBJGRP_UNIT_ID_INVALID; + pboardobjgrp->pmu.classid = BOARDOBJGRP_GRP_CLASS_ID_INVALID; + pboardobjgrp->pmu.bset = false; + pboardobjgrp->pmu.rpc_func_id = BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID; + pboardobjgrp->pmu.set.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; + pboardobjgrp->pmu.getstatus.id = BOARDOBJGRP_GRP_CMD_ID_INVALID; + + /* Initialize basic interfaces */ + pboardobjgrp->destruct = boardobjgrp_destruct_super; + pboardobjgrp->objinsert = boardobjgrp_objinsert_final; + pboardobjgrp->objgetbyidx = boardobjgrp_objgetbyidx_final; + pboardobjgrp->objgetnext = boardobjgrp_objgetnext_final; + pboardobjgrp->objremoveanddestroy = + boardobjgrp_objremoveanddestroy_final; + + pboardobjgrp->pmuinithandle = boardobjgrp_pmuinithandle_impl; + pboardobjgrp->pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_super; + pboardobjgrp->pmudatainit = boardobjgrp_pmudatainit_super; + pboardobjgrp->pmuset = + g->ops.pmu_ver.boardobj.boardobjgrp_pmuset_impl; + pboardobjgrp->pmugetstatus = + g->ops.pmu_ver.boardobj.boardobjgrp_pmugetstatus_impl; + + pboardobjgrp->pmudatainstget = boardobjgrp_pmudatainstget_stub; + pboardobjgrp->pmustatusinstget = boardobjgrp_pmustatusinstget_stub; + + pboardobjgrp->objmaxidx = CTRL_BOARDOBJ_IDX_INVALID; + pboardobjgrp->bconstructed = true; + + nvgpu_list_add(&pboardobjgrp->node, &g->boardobjgrp_head); + + return 0; +} + +int boardobjgrp_destruct_impl(struct boardobjgrp *pboardobjgrp) +{ + struct gk20a *g = pboardobjgrp->g; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (!pboardobjgrp->bconstructed) { + return 0; + } + + return pboardobjgrp->destruct(pboardobjgrp); +} + +int boardobjgrp_destruct_super(struct boardobjgrp *pboardobjgrp) +{ + struct boardobj *pboardobj; + struct gk20a *g = pboardobjgrp->g; + int status = 0; + int stat; + u8 index; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp->mask == NULL) { + return -EINVAL; + } + if (pboardobjgrp->ppobjects == NULL) { + return -EINVAL; + } + + BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { + stat = pboardobjgrp->objremoveanddestroy(pboardobjgrp, index); + if (status == 0) { + status = stat; + } + + pboardobjgrp->ppobjects[index] = NULL; + pboardobjgrp->objmask &= ~BIT(index); + } + + pboardobjgrp->objmask = 0; + + if (pboardobjgrp->objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { + if (status == 0) { + status = -EINVAL; + } + + WARN_ON(true); + } + + /* Destroy the PMU CMD data */ + stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.set); + if (status == 0) { + status = stat; + } + + stat = boardobjgrp_pmucmd_destroy_impl(g, &pboardobjgrp->pmu.getstatus); + if (status == 0) { + status = stat; + } + + nvgpu_list_del(&pboardobjgrp->node); + + pboardobjgrp->bconstructed = false; + + return status; +} + +int boardobjgrp_pmucmd_construct_impl(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, + u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id) +{ + nvgpu_log_info(g, " "); + + /* Copy the parameters into the CMD*/ + cmd->id = id; + cmd->msgid = msgid; + cmd->hdrsize = (u8) hdrsize; + cmd->entrysize = (u8) entrysize; + cmd->fbsize = fbsize; + + return 0; +} + +int boardobjgrp_pmucmd_construct_impl_v1(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, + u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id) +{ + nvgpu_log_fn(g, " "); + + /* Copy the parameters into the CMD*/ + cmd->dmem_buffer_size = ((hdrsize > entrysize) ? hdrsize : entrysize); + cmd->super_surface_offset = ss_offset; + pboardobjgrp->pmu.rpc_func_id = rpc_func_id; + cmd->fbsize = fbsize; + + nvgpu_log_fn(g, "DONE"); + return 0; +} + +int boardobjgrp_pmucmd_destroy_impl(struct gk20a *g, + struct boardobjgrp_pmu_cmd *cmd) +{ + struct nvgpu_mem *mem = &cmd->surf.sysmem_desc; + + nvgpu_pmu_surface_free(g, mem); + return 0; +} + +int is_boardobjgrp_pmucmd_id_valid_v0(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd) +{ + int err = 0; + + if (pcmd->id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { + err = -EINVAL; + } + + return err; +} + +int is_boardobjgrp_pmucmd_id_valid_v1(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd) +{ + int err = 0; + + if (pboardobjgrp->pmu.rpc_func_id == + BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID) { + err = -EINVAL; + } + + return err; +} + +int boardobjgrp_pmucmd_pmuinithandle_impl(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd) +{ + int status = 0; + struct nvgpu_mem *sysmem_desc = &pcmd->surf.sysmem_desc; + + nvgpu_log_info(g, " "); + + if (g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid(g, + pboardobjgrp, pcmd)) { + goto boardobjgrp_pmucmd_pmuinithandle_exit; + } + + if (!pcmd->fbsize) { + goto boardobjgrp_pmucmd_pmuinithandle_exit; + } + + nvgpu_pmu_sysmem_surface_alloc(g, sysmem_desc, pcmd->fbsize); + /* we only have got sysmem later this will get copied to vidmem + surface*/ + pcmd->surf.vidmem_desc.size = 0; + + pcmd->buf = (struct nv_pmu_boardobjgrp_super *)sysmem_desc->cpu_va; + +boardobjgrp_pmucmd_pmuinithandle_exit: + return status; +} + +int boardobjgrp_pmuinithandle_impl(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + int status = 0; + + nvgpu_log_info(g, " "); + + status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, + &pboardobjgrp->pmu.set); + if (status) { + nvgpu_err(g, "failed to init pmu set cmd"); + goto boardobjgrp_pmuinithandle_exit; + } + + status = boardobjgrp_pmucmd_pmuinithandle_impl(g, pboardobjgrp, + &pboardobjgrp->pmu.getstatus); + if (status) { + nvgpu_err(g, "failed to init get status command"); + goto boardobjgrp_pmuinithandle_exit; + } + + /* If the GRP_SET CMD has not been allocated, nothing left to do. */ + if ((g->ops.pmu_ver.boardobj.is_boardobjgrp_pmucmd_id_valid(g, + pboardobjgrp, &pboardobjgrp->pmu.set))|| + (BOARDOBJGRP_IS_EMPTY(pboardobjgrp))) { + goto boardobjgrp_pmuinithandle_exit; + } + + /* Send the BOARDOBJGRP to the pmu via RM_PMU_BOARDOBJ_CMD_GRP. */ + status = pboardobjgrp->pmuset(g, pboardobjgrp); + if (status) { + nvgpu_err(g, "failed to send boardobg grp to PMU"); + } + +boardobjgrp_pmuinithandle_exit: + return status; +} + + +int boardobjgrp_pmuhdrdatainit_super(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask) +{ + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + pboardobjgrppmu->type = pboardobjgrp->type; + pboardobjgrppmu->class_id = pboardobjgrp->classid; + pboardobjgrppmu->obj_slots = BOARDOBJGRP_PMU_SLOTS_GET(pboardobjgrp); + pboardobjgrppmu->flags = 0; + + nvgpu_log_info(g, " Done"); + return 0; +} + +static int boardobjgrp_pmudatainstget_stub(struct gk20a *g, + struct nv_pmu_boardobjgrp *boardobjgrppmu, + struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx) +{ + nvgpu_log_info(g, " "); + return -EINVAL; +} + + +static int boardobjgrp_pmustatusinstget_stub(struct gk20a *g, + void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx) +{ + nvgpu_log_info(g, " "); + return -EINVAL; +} + +int boardobjgrp_pmudatainit_legacy(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + int status = 0; + struct boardobj *pboardobj = NULL; + struct nv_pmu_boardobj *ppmudata = NULL; + u8 index; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + + boardobjgrpe32hdrset((struct nv_pmu_boardobjgrp *)pboardobjgrppmu, + pboardobjgrp->objmask); + + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(32, index, pboardobjgrp->objmask) { + /* Obtain pointer to the current instance of the Object from the Group */ + pboardobj = pboardobjgrp->objgetbyidx(pboardobjgrp, index); + if (NULL == pboardobj) { + nvgpu_err(g, "could not get object instance"); + status = -EINVAL; + goto boardobjgrppmudatainit_legacy_done; + } + + status = pboardobjgrp->pmudatainstget(g, + (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, + &ppmudata, index); + if (status) { + nvgpu_err(g, "could not get object instance"); + goto boardobjgrppmudatainit_legacy_done; + } + + /* Initialize the PMU Data */ + status = pboardobj->pmudatainit(g, pboardobj, ppmudata); + if (status) { + nvgpu_err(g, + "could not parse pmu for device %d", index); + goto boardobjgrppmudatainit_legacy_done; + } + } + BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END + +boardobjgrppmudatainit_legacy_done: + nvgpu_log_info(g, " Done"); + return status; +} + +int boardobjgrp_pmudatainit_super(struct gk20a *g, struct boardobjgrp + *pboardobjgrp, struct nv_pmu_boardobjgrp_super *pboardobjgrppmu) +{ + int status = 0; + struct boardobj *pboardobj = NULL; + struct nv_pmu_boardobj *ppmudata = NULL; + u8 index; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + + /* Initialize the PMU HDR data.*/ + status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, pboardobjgrppmu, + pboardobjgrp->mask); + if (status) { + nvgpu_err(g, "unable to init boardobjgrp pmuhdr data"); + goto boardobjgrppmudatainit_super_done; + } + + BOARDOBJGRP_FOR_EACH(pboardobjgrp, struct boardobj*, pboardobj, index) { + status = pboardobjgrp->pmudatainstget(g, + (struct nv_pmu_boardobjgrp *)pboardobjgrppmu, + &ppmudata, index); + if (status) { + nvgpu_err(g, "could not get object instance"); + goto boardobjgrppmudatainit_super_done; + } + + /* Initialize the PMU Data and send to PMU */ + status = pboardobj->pmudatainit(g, pboardobj, ppmudata); + if (status) { + nvgpu_err(g, + "could not parse pmu for device %d", index); + goto boardobjgrppmudatainit_super_done; + } + } + +boardobjgrppmudatainit_super_done: + nvgpu_log_info(g, " Done"); + return status; +} + +static int check_boardobjgrp_param(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (!pboardobjgrp->bconstructed) { + return -EINVAL; + } + + if (pboardobjgrp->pmu.unitid == BOARDOBJGRP_UNIT_ID_INVALID) { + return -EINVAL; + } + + if (pboardobjgrp->pmu.classid == BOARDOBJGRP_GRP_CLASS_ID_INVALID) { + return -EINVAL; + } + + /* If no objects in the group, return early */ + if (BOARDOBJGRP_IS_EMPTY(pboardobjgrp)) { + return -EINVAL; + } + + return 0; +} + +int boardobjgrp_pmuset_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp) +{ + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if (pboardobjgrp->pmu.set.id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { + return -EINVAL; + } + + if ((pcmd->hdrsize == 0) || + (pcmd->entrysize == 0) || + (pcmd->buf == NULL)) { + return -EINVAL; + } + + /* Initialize PMU buffer with BOARDOBJGRP data. */ + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmudatainit(g, pboardobjgrp, + pcmd->buf); + if (status) { + nvgpu_err(g, "could not parse pmu data"); + goto boardobjgrp_pmuset_exit; + } + + /* + * Reset the boolean that indicates set status for most recent + * instance of BOARDOBJGRP. + */ + pboardobjgrp->pmu.bset = false; + + /* + * alloc mem in vidmem & copy constructed pmu boardobjgrp data from + * sysmem to vidmem + */ + if (pcmd->surf.vidmem_desc.size == 0) { + nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc, + pcmd->fbsize); + } + nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize); + + /* Send the SET PMU CMD to the PMU */ + status = boardobjgrp_pmucmdsend(g, pboardobjgrp, + pcmd); + if (status) { + nvgpu_err(g, "could not send SET CMD to PMU"); + goto boardobjgrp_pmuset_exit; + } + + pboardobjgrp->pmu.bset = true; + +boardobjgrp_pmuset_exit: + return status; +} + +int boardobjgrp_pmuset_impl_v1(struct gk20a *g, + struct boardobjgrp *pboardobjgrp) +{ + struct nvgpu_pmu *pmu = &g->pmu; + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if ((pcmd->buf == NULL) && + (pboardobjgrp->pmu.rpc_func_id == + BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID)) { + return -EINVAL; + } + + /* Initialize PMU buffer with BOARDOBJGRP data. */ + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmudatainit(g, pboardobjgrp, + pcmd->buf); + if (status) { + nvgpu_err(g, "could not parse pmu data"); + goto boardobjgrp_pmuset_exit; + } + + /* + * Reset the boolean that indicates set status + * for most recent instance of BOARDOBJGRP. + */ + pboardobjgrp->pmu.bset = false; + + /* + * copy constructed pmu boardobjgrp data from + * sysmem to pmu super surface present in FB + */ + nvgpu_mem_wr_n(g, &pmu->super_surface_buf, + pcmd->super_surface_offset, pcmd->buf, + pcmd->fbsize); + + /* Send the SET PMU CMD to the PMU using RPC*/ + status = boardobjgrp_pmucmdsend_rpc(g, pboardobjgrp, + pcmd, false); + if (status) { + nvgpu_err(g, "could not send SET CMD to PMU"); + goto boardobjgrp_pmuset_exit; + } + + pboardobjgrp->pmu.bset = true; + +boardobjgrp_pmuset_exit: + return status; +} + +int +boardobjgrp_pmugetstatus_impl(struct gk20a *g, struct boardobjgrp *pboardobjgrp, + struct boardobjgrpmask *mask) +{ + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.getstatus); + struct boardobjgrp_pmu_cmd *pset = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.set); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if (pset->id == BOARDOBJGRP_GRP_CMD_ID_INVALID) { + return -EINVAL; + } + + if ((pcmd->hdrsize == 0) || + (pcmd->entrysize == 0) || + (pcmd->buf == NULL)) { + return -EINVAL; + } + + /* + * Can only GET_STATUS if the BOARDOBJGRP has been previously SET to the + * PMU + */ + if (!pboardobjgrp->pmu.bset) { + return -EINVAL; + } + + /* + * alloc mem in vidmem & copy constructed pmu boardobjgrp data from + * sysmem to vidmem + */ + if (pcmd->surf.vidmem_desc.size == 0) { + nvgpu_pmu_vidmem_surface_alloc(g, &pcmd->surf.vidmem_desc, + pcmd->fbsize); + } + + /* + * Initialize PMU buffer with the mask of BOARDOBJGRPs for which to + * retrieve status + */ + + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, + pcmd->buf, mask); + if (status) { + nvgpu_err(g, "could not init PMU HDR data"); + goto boardobjgrp_pmugetstatus_exit; + } + + nvgpu_mem_wr_n(g, &pcmd->surf.vidmem_desc, 0, pset->buf, pset->hdrsize); + /* Send the GET_STATUS PMU CMD to the PMU */ + status = boardobjgrp_pmucmdsend(g, pboardobjgrp, + &pboardobjgrp->pmu.getstatus); + if (status) { + nvgpu_err(g, "could not send GET_STATUS cmd to PMU"); + goto boardobjgrp_pmugetstatus_exit; + } + + /*copy the data back to sysmem buffer that belongs to command*/ + nvgpu_mem_rd_n(g, &pcmd->surf.vidmem_desc, 0, pcmd->buf, pcmd->fbsize); + +boardobjgrp_pmugetstatus_exit: + return status; +} + +int +boardobjgrp_pmugetstatus_impl_v1(struct gk20a *g, struct boardobjgrp *pboardobjgrp, + struct boardobjgrpmask *mask) +{ + struct nvgpu_pmu *pmu = &g->pmu; + int status = 0; + struct boardobjgrp_pmu_cmd *pcmd = + (struct boardobjgrp_pmu_cmd *)(&pboardobjgrp->pmu.getstatus); + + nvgpu_log_info(g, " "); + + if (check_boardobjgrp_param(g, pboardobjgrp)) { + return -EINVAL; + } + + if ((pcmd->buf == NULL) && + (pboardobjgrp->pmu.rpc_func_id == + BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID)) { + return -EINVAL; + } + + /* + * Can only GET_STATUS if the BOARDOBJGRP has been + * previously SET to the PMU + */ + if (!pboardobjgrp->pmu.bset) { + return -EINVAL; + } + + /* + * Initialize PMU buffer with the mask of + * BOARDOBJGRPs for which to retrieve status + */ + memset(pcmd->buf, 0x0, pcmd->fbsize); + status = pboardobjgrp->pmuhdrdatainit(g, pboardobjgrp, + pcmd->buf, mask); + if (status) { + nvgpu_err(g, "could not init PMU HDR data"); + goto boardobjgrp_pmugetstatus_exit; + } + + /* + * copy constructed pmu boardobjgrp data from + * sysmem to pmu super surface present in FB + */ + nvgpu_mem_wr_n(g, &pmu->super_surface_buf, pcmd->super_surface_offset, + pcmd->buf, pcmd->fbsize); + /* Send the GET_STATUS PMU CMD to the PMU */ + status = boardobjgrp_pmucmdsend_rpc(g, pboardobjgrp, + pcmd, true); + if (status) { + nvgpu_err(g, "could not send GET_STATUS cmd to PMU"); + goto boardobjgrp_pmugetstatus_exit; + } + + /*copy the data back to sysmem buffer that belongs to command*/ + nvgpu_mem_rd_n(g, &pmu->super_surface_buf,pcmd->super_surface_offset, + pcmd->buf, pcmd->fbsize); + +boardobjgrp_pmugetstatus_exit: + return status; +} + +static int +boardobjgrp_objinsert_final(struct boardobjgrp *pboardobjgrp, + struct boardobj *pboardobj, u8 index) +{ + struct gk20a *g = pboardobjgrp->g; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobj == NULL) { + return -EINVAL; + } + + if (index > pboardobjgrp->objslots) { + return -EINVAL; + } + + if (pboardobjgrp->ppobjects[index] != NULL) { + return -EINVAL; + } + + /* + * Check that this BOARDOBJ has not already been added to a + * BOARDOBJGRP + */ + if (pboardobj->idx != CTRL_BOARDOBJ_IDX_INVALID) { + return -EINVAL; + } + + pboardobjgrp->ppobjects[index] = pboardobj; + pboardobjgrp->objmaxidx = (u8)(BOARDOBJGRP_IS_EMPTY(pboardobjgrp) ? + index : max(pboardobjgrp->objmaxidx, index)); + pboardobj->idx = index; + + pboardobjgrp->objmask |= BIT(index); + + nvgpu_log_info(g, " Done"); + + return boardobjgrpmask_bitset(pboardobjgrp->mask, index); +} + +static struct boardobj *boardobjgrp_objgetbyidx_final( + struct boardobjgrp *pboardobjgrp, u8 index) +{ + if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) { + return NULL; + } + return pboardobjgrp->ppobjects[index]; +} + +static struct boardobj *boardobjgrp_objgetnext_final( + struct boardobjgrp *pboardobjgrp, u8 *currentindex, + struct boardobjgrpmask *mask) +{ + struct boardobj *pboardobjnext = NULL; + u8 objmaxidx; + u8 index; + + if (currentindex == NULL) { + return NULL; + } + + if (pboardobjgrp == NULL) { + return NULL; + } + + /* Search from next element unless first object was requested */ + index = (*currentindex != CTRL_BOARDOBJ_IDX_INVALID) ? + (*currentindex + 1) : 0; + + /* For the cases below in which we have to return NULL */ + *currentindex = CTRL_BOARDOBJ_IDX_INVALID; + + + /* Validate provided mask */ + if (mask != NULL) { + if (!(boardobjgrpmask_sizeeq(pboardobjgrp->mask, mask))) { + return NULL; + } + } + + objmaxidx = pboardobjgrp->objmaxidx; + + if (objmaxidx != CTRL_BOARDOBJ_IDX_INVALID) { + for (; index <= objmaxidx; index++) { + pboardobjnext = pboardobjgrp->ppobjects[index]; + if (pboardobjnext != NULL) { + /* Filter results using client provided mask.*/ + if (mask != NULL) { + if (!boardobjgrpmask_bitget(mask, + index)) { + pboardobjnext = NULL; + continue; + } + } + *currentindex = index; + break; + } + } + } + + return pboardobjnext; +} + +static int boardobjgrp_objremoveanddestroy_final( + struct boardobjgrp *pboardobjgrp, + u8 index) +{ + int status = 0; + int stat; + struct gk20a *g = pboardobjgrp->g; + + nvgpu_log_info(g, " "); + + if (!boardobjgrp_idxisvalid(pboardobjgrp, index)) { + return -EINVAL; + } + + if (pboardobjgrp->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID) { + return -EINVAL; + } + + status = pboardobjgrp->ppobjects[index]->destruct( + pboardobjgrp->ppobjects[index]); + + pboardobjgrp->ppobjects[index] = NULL; + + pboardobjgrp->objmask &= ~BIT(index); + + stat = boardobjgrpmask_bitclr(pboardobjgrp->mask, index); + if (stat) { + if (status == 0) { + status = stat; + } + } + + /* objmaxidx requires update only if that very object was removed */ + if (pboardobjgrp->objmaxidx == index) { + pboardobjgrp->objmaxidx = + boardobjgrpmask_bitidxhighest(pboardobjgrp->mask); + } + + return status; +} + +void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask) +{ + u32 slots = objmask; + + HIGHESTBITIDX_32(slots); + slots++; + + hdr->super.type = CTRL_BOARDOBJGRP_TYPE_E32; + hdr->super.class_id = 0; + hdr->super.obj_slots = (u8)slots; + hdr->obj_mask = objmask; +} + +static void boardobjgrp_pmucmdhandler(struct gk20a *g, struct pmu_msg *msg, + void *param, u32 handle, u32 status) +{ + struct nv_pmu_boardobj_msg_grp *pgrpmsg; + struct boardobjgrp_pmucmdhandler_params *phandlerparams = + (struct boardobjgrp_pmucmdhandler_params *)param; + struct boardobjgrp *pboardobjgrp = phandlerparams->pboardobjgrp; + struct boardobjgrp_pmu_cmd *pgrpcmd = phandlerparams->pcmd; + + nvgpu_log_info(g, " "); + + pgrpmsg = &msg->msg.boardobj.grp; + + if (pgrpmsg->class_id != pboardobjgrp->pmu.classid) { + nvgpu_err(g, + "Unrecognized GRP type: unit %x class id=0x%02x cmd id %x", + msg->hdr.unit_id, pboardobjgrp->pmu.classid, + pgrpcmd->id); + return; + } + + if (msg->msg.boardobj.msg_type != pgrpcmd->msgid) { + nvgpu_err(g, + "unsupported msg for unit %x class %x cmd id %x msg %x", + msg->hdr.unit_id, pboardobjgrp->pmu.classid, + pgrpcmd->id, msg->msg.boardobj.msg_type); + return; + } + + if (msg->msg.boardobj.grp_set.flcn_status != 0) { + nvgpu_err(g, + "cmd abort for unit %x class %x cmd id %x status %x", + msg->hdr.unit_id, pboardobjgrp->pmu.classid, + pgrpcmd->id, + msg->msg.boardobj.grp_set.flcn_status); + return; + } + + phandlerparams->success = pgrpmsg->b_success ? 1 : 0; + + if (!pgrpmsg->b_success) { + nvgpu_err(g, + "failed GRPCMD: msgtype=0x%x, classid=0x%x, cmd id %x", + pgrpmsg->msg_type, pgrpmsg->class_id, + pgrpcmd->id); + return; + } +} + +static int boardobjgrp_pmucmdsend(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd) +{ + struct boardobjgrp_pmucmdhandler_params handlerparams; + struct pmu_payload payload; + struct nv_pmu_boardobj_cmd_grp *pgrpcmd; + struct pmu_cmd cmd; + u32 seqdesc; + int status = 0; + + nvgpu_log_info(g, " "); + + memset(&payload, 0, sizeof(payload)); + memset(&handlerparams, 0, sizeof(handlerparams)); + memset(&cmd, 0, sizeof(struct pmu_cmd)); + cmd.hdr.unit_id = pboardobjgrp->pmu.unitid; + cmd.hdr.size = sizeof(struct nv_pmu_boardobj_cmd_grp) + + sizeof(struct pmu_hdr); + + pgrpcmd = &cmd.cmd.boardobj.grp; + pgrpcmd->cmd_type = pcmd->id; + pgrpcmd->class_id = pboardobjgrp->pmu.classid; + pgrpcmd->grp.hdr_size = pcmd->hdrsize; + pgrpcmd->grp.entry_size = pcmd->entrysize; + + /* + * copy vidmem information to boardobj_cmd_grp + */ + nvgpu_pmu_surface_describe(g, &pcmd->surf.vidmem_desc, + &pgrpcmd->grp.fb); + + /* + * PMU reads command from sysmem so assigned + * "payload.in.buf = pcmd->buf" + * but PMU access pmu boardobjgrp data from vidmem copied above + */ + payload.in.buf = pcmd->buf; + payload.in.size = max(pcmd->hdrsize, pcmd->entrysize); + payload.in.fb_size = PMU_CMD_SUBMIT_PAYLOAD_PARAMS_FB_SIZE_UNUSED; + payload.in.offset = offsetof(struct nv_pmu_boardobj_cmd_grp, grp); + + /* Setup the handler params to communicate back results.*/ + handlerparams.pboardobjgrp = pboardobjgrp; + handlerparams.pcmd = pcmd; + handlerparams.success = 0; + + status = nvgpu_pmu_cmd_post(g, &cmd, NULL, &payload, + PMU_COMMAND_QUEUE_LPQ, + boardobjgrp_pmucmdhandler, + (void *)&handlerparams, + &seqdesc, ~0); + if (status) { + nvgpu_err(g, + "unable to post boardobj grp cmd for unit %x cmd id %x", + cmd.hdr.unit_id, pcmd->id); + goto boardobjgrp_pmucmdsend_exit; + } + pmu_wait_message_cond(&g->pmu, + gk20a_get_gr_idle_timeout(g), + &handlerparams.success, 1); + if (handlerparams.success == 0) { + nvgpu_err(g, "could not process cmd"); + status = -ETIMEDOUT; + goto boardobjgrp_pmucmdsend_exit; + } + +boardobjgrp_pmucmdsend_exit: + return status; +} + +static int boardobjgrp_pmucmdsend_rpc(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *pcmd, + bool copy_out) +{ + struct nvgpu_pmu *pmu = &g->pmu; + struct nv_pmu_rpc_struct_board_obj_grp_cmd rpc; + int status = 0; + + nvgpu_log_fn(g, " "); + + memset(&rpc, 0, sizeof(struct nv_pmu_rpc_struct_board_obj_grp_cmd)); + + rpc.class_id = pboardobjgrp->pmu.classid; + rpc.command_id = copy_out ? + NV_PMU_BOARDOBJGRP_CMD_GET_STATUS : + NV_PMU_BOARDOBJGRP_CMD_SET; + + rpc.hdr.unit_id = pboardobjgrp->pmu.unitid; + rpc.hdr.function = pboardobjgrp->pmu.rpc_func_id; + rpc.hdr.flags = 0x0; + + status = nvgpu_pmu_rpc_execute(pmu, &(rpc.hdr), + (sizeof(rpc) - sizeof(rpc.scratch)), + pcmd->dmem_buffer_size, + NULL, NULL, copy_out); + + if (status) { + nvgpu_err(g, "Failed to execute RPC, status=0x%x", status); + } + + return status; +} diff --git a/include/boardobj/boardobjgrp.h b/include/boardobj/boardobjgrp.h new file mode 100644 index 0000000..cd13b85 --- /dev/null +++ b/include/boardobj/boardobjgrp.h @@ -0,0 +1,441 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#ifndef NVGPU_BOARDOBJGRP_H +#define NVGPU_BOARDOBJGRP_H + +struct boardobjgrp; +struct gk20a; +struct nvgpu_list_node; +struct pmu_surface; + + +/* ------------------------ Includes ----------------------------------------*/ +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" +#include "boardobjgrpmask.h" +#include +#include + +/* +* Board Object Group destructor. +* +*/ +typedef int boardobjgrp_destruct(struct boardobjgrp *pboardobjgrp); + +/* +* Inserts a previously constructed Board Object into a Board Object Group for +* tracking. Objects are inserted in the array based on the given index. +*/ +typedef int boardobjgrp_objinsert(struct boardobjgrp *pboardobjgrp, + struct boardobj *pboardobj, u8 index); + +/* +* Retrieves a Board Object from a Board Object Group using the group's index. +* +*/ +typedef struct boardobj *boardobjgrp_objgetbyidx( + struct boardobjgrp *pBobrdobjgrp, u8 index); + +/* +* Retrieve Board Object immediately following one pointed by @ref pcurrentindex +* filtered out by the provided mask. If (pMask == NULL) => no filtering. +*/ +typedef struct boardobj *boardobjgrp_objgetnext( + struct boardobjgrp *pboardobjgrp, + u8 *currentindex, struct boardobjgrpmask *mask); + +/* +* Board Object Group Remover and destructor. This is used to remove and +* destruct specific entry from the Board Object Group. +*/ +typedef int boardobjgrp_objremoveanddestroy(struct boardobjgrp *pboardobjgrp, + u8 index); + +/* +* BOARDOBJGRP handler for PMU_UNIT_INIT. Calls the PMU_UNIT_INIT handlers +* for the constructed PMU CMDs, and then sets the object via the +* PMU_BOARDOBJ_CMD_GRP interface (if constructed). +*/ +typedef int boardobjgrp_pmuinithandle(struct gk20a *g, + struct boardobjgrp *pboardobjGrp); + +/* +* Fills out the appropriate the PMU_BOARDOBJGRP_ driver<->PMU description +* header structure, more specifically a mask of BOARDOBJs. +*/ +typedef int boardobjgrp_pmuhdrdatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask); + +/* +* Fills out the appropriate the PMU_BOARDOBJGRP_ driver->PMU description +* structure, describing the BOARDOBJGRP and all of its BOARDOBJs to the PMU. +*/ +typedef int boardobjgrp_pmudatainit(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu); + +/* +* Sends a BOARDOBJGRP to the PMU via the PMU_BOARDOBJ_CMD_GRP interface. +* This interface leverages @ref boardobjgrp_pmudatainit to populate the +* structure. +*/ +typedef int boardobjgrp_pmuset(struct gk20a *g, + struct boardobjgrp *pboardobjgrp); + +/* +* Gets the dynamic status of the PMU BOARDOBJGRP via the +* PMU_BOARDOBJ_CMD_GRP GET_STATUS interface. +*/ +typedef int boardobjgrp_pmugetstatus(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrpmask *mask); + +typedef int boardobjgrp_pmudatainstget(struct gk20a *g, + struct nv_pmu_boardobjgrp *boardobjgrppmu, + struct nv_pmu_boardobj **ppboardobjpmudata, u8 idx); + +typedef int boardobjgrp_pmustatusinstget(struct gk20a *g, void *pboardobjgrppmu, + struct nv_pmu_boardobj_query **ppBoardobjpmustatus, u8 idx); + +/* +* Structure describing an PMU CMD for interacting with the representaition +* of this BOARDOBJGRP within the PMU. +*/ +struct boardobjgrp_pmu_cmd { + u8 id; + u8 msgid; + u8 hdrsize; + u8 entrysize; + u16 dmem_buffer_size; + u32 super_surface_offset; + u32 fbsize; + struct nv_pmu_boardobjgrp_super *buf; + struct pmu_surface surf; +}; + +/* +* Structure of state describing how to communicate with representation of this +* BOARDOBJGRP in the PMU. +*/ +struct boardobjgrp_pmu { + u8 unitid; + u8 classid; + bool bset; + u8 rpc_func_id; + struct boardobjgrp_pmu_cmd set; + struct boardobjgrp_pmu_cmd getstatus; +}; + +/* +* Function by which a class which implements BOARDOBJGRP can construct a PMU +* CMD. This provides the various information describing the PMU CMD including +* the CMD and MSG ID and the size of the various sturctures in the payload. +*/ +typedef int boardobjgrp_pmucmd_construct(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd, u8 id, u8 msgid, + u16 hdrsize, u16 entrysize, u16 fbsize, u32 ss_offset, u8 rpc_func_id); + +/* +* Destroys BOARDOBJGRP PMU SW state. CMD. +*/ +typedef int boardobjgrp_pmucmd_destroy(struct gk20a *g, + struct boardobjgrp_pmu_cmd *cmd); + +/* +* init handler for the BOARDOBJGRP PMU CMD. Allocates and maps the +* PMU CMD payload within both the PMU and driver so that it can be referenced +* at run-time. +*/ +typedef int boardobjgrp_pmucmd_pmuinithandle(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd); + +/* +* Base Class Group for all physical or logical device on the PCB. +* Contains fields common to all devices on the board. Specific types of +* devices groups may extend this object adding any details specific to that +* device group or device-type. +*/ +struct boardobjgrp { + struct gk20a *g; + u32 objmask; + bool bconstructed; + u8 type; + u8 classid; + struct boardobj **ppobjects; + struct boardobjgrpmask *mask; + u8 objslots; + u8 objmaxidx; + struct boardobjgrp_pmu pmu; + + /* Basic interfaces */ + boardobjgrp_destruct *destruct; + boardobjgrp_objinsert *objinsert; + boardobjgrp_objgetbyidx *objgetbyidx; + boardobjgrp_objgetnext *objgetnext; + boardobjgrp_objremoveanddestroy *objremoveanddestroy; + + /* PMU interfaces */ + boardobjgrp_pmuinithandle *pmuinithandle; + boardobjgrp_pmuhdrdatainit *pmuhdrdatainit; + boardobjgrp_pmudatainit *pmudatainit; + boardobjgrp_pmuset *pmuset; + boardobjgrp_pmugetstatus *pmugetstatus; + + boardobjgrp_pmudatainstget *pmudatainstget; + boardobjgrp_pmustatusinstget *pmustatusinstget; + struct nvgpu_list_node node; +}; + +/* +* Macro test whether a specified index into the BOARDOBJGRP is valid. +* +*/ +#define boardobjgrp_idxisvalid(_pboardobjgrp, _idx) \ + (((_idx) < (_pboardobjgrp)->objslots) && \ + ((_pboardobjgrp)->ppobjects[(_idx)] != NULL)) + +/* +* Macro test whether a specified BOARDOBJGRP is empty. +*/ +#define BOARDOBJGRP_IS_EMPTY(_pboardobjgrp) \ + ((!((_pboardobjgrp)->bconstructed)) || \ + ((_pboardobjgrp)->objmaxidx == CTRL_BOARDOBJ_IDX_INVALID)) + +#define boardobjgrp_objinsert(_pboardobjgrp, _pboardobj, _idx) \ + ((_pboardobjgrp)->objinsert((_pboardobjgrp), (_pboardobj), (_idx))) + +/* +* Helper macro to determine the "next" open/empty index after all allocated +* objects. This is intended to be used to find the index at which objects can +* be inserted contiguously (i.e. w/o fear of colliding with existing objects). +*/ +#define BOARDOBJGRP_NEXT_EMPTY_IDX(_pboardobjgrp) \ + ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0U : \ + ((((_pboardobjgrp)->objmaxidx + 1U) >= (_pboardobjgrp)->objslots) ? \ + (u8)CTRL_BOARDOBJ_IDX_INVALID : (u8)((_pboardobjgrp)->objmaxidx + 1U))) + +/* +* Helper macro to determine the number of @ref BOARDOBJ pointers +* that are required to be allocated in PMU @ref ppObjects. +*/ +#define BOARDOBJGRP_PMU_SLOTS_GET(_pboardobjgrp) \ + ((CTRL_BOARDOBJ_IDX_INVALID == (_pboardobjgrp)->objmaxidx) ? 0U : \ + (u8)((_pboardobjgrp)->objmaxidx + 1U)) + +#define BOARDOBJGRP_OBJ_GET_BY_IDX(_pboardobjgrp, _idx) \ + ((_pboardobjgrp)->objgetbyidx((_pboardobjgrp), (_idx))) + +/* +* macro to look-up next object while tolerating error if +* Board Object Group is not constructed. +*/ + +#define boardobjgrpobjgetnextsafe(_pgrp, _pindex, _pmask) \ + ((_pgrp)->bconstructed ? \ + (_pgrp)->objgetnext((_pgrp), (_pindex), (_pmask)) : NULL) + +/* +* Used to traverse all Board Objects stored within @ref _pgrp in the increasing +* index order. +* If @ref _pmask is provided only objects specified by the mask are traversed. +*/ +#define BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, _pmask) \ + for (_index = CTRL_BOARDOBJ_IDX_INVALID, \ + _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask));\ + _pobj != NULL; \ + _pobj = (_ptype)boardobjgrpobjgetnextsafe((_pgrp), &_index, (_pmask))) +#define BOARDOBJGRP_FOR_EACH(_pgrp, _ptype, _pobj, _index) \ + BOARDOBJGRP_ITERATOR(_pgrp, _ptype, _pobj, _index, NULL) + +#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK(mask_width, index, mask) \ +{ \ + u##mask_width lcl_msk = (u##mask_width)(mask); \ + for (index = 0; lcl_msk != 0U; index++, lcl_msk >>= 1U) { \ + if (((u##mask_width)((u64)1) & lcl_msk) == 0U) { \ + continue; \ + } + +#define BOARDOBJGRP_FOR_EACH_INDEX_IN_MASK_END \ + } \ +} + + +/*! +* Invalid UNIT_ID. Used to indicate that the implementing class has not set +* @ref BOARDOBJGRP::unitId and, thus, certain BOARDOBJGRP PMU interfaces are +* not supported. +*/ +#define BOARDOBJGRP_UNIT_ID_INVALID 255U + +/*! +* Invalid UNIT_ID. Used to indicate that the implementing class has not set +* @ref BOARDOBJGRP::grpType and, thus, certain BOARDOBJGRP PMU interfaces are +* not supported. +*/ +#define BOARDOBJGRP_GRP_CLASS_ID_INVALID 255U + +/*! +* Invalid UNIT_ID. Used to indicate that the implementing class has not set +* @ref BOARDOBJGRP::grpSetCmdId and, thus, certain BOARDOBJGRP PMU interfaces +* are not supported. +*/ +#define BOARDOBJGRP_GRP_CMD_ID_INVALID 255U +#define BOARDOBJGRP_GRP_RPC_FUNC_ID_INVALID 255U + +/*! +* Helper macro to construct a BOARDOBJGRP's PMU SW state. +* +* @param[out] pboardobjgrp BOARDOBJGRP pointer +* @param[in] _eng +* Implementing engine/unit which manages the BOARDOBJGRP. +* @param[in] _class +* Class ID of BOARDOBJGRP. +*/ +#define BOARDOBJGRP_PMU_CONSTRUCT(pboardobjgrp, _ENG, _CLASS) \ +do { \ + (pboardobjgrp)->pmu.unitid = PMU_UNIT_##_ENG; \ + (pboardobjgrp)->pmu.classid = \ + NV_PMU_##_ENG##_BOARDOBJGRP_CLASS_ID_##_CLASS; \ +} while (0) + +#define BOARDOBJGRP_PMU_CMD_GRP_SET_CONSTRUCT(g, pboardobjgrp, eng, ENG, \ + class, CLASS) \ + g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ + g, /* pgpu */ \ + pboardobjgrp, /* pboardobjgrp */ \ + &((pboardobjgrp)->pmu.set), /* pcmd */ \ + NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_SET, /* id */ \ + NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_SET, /* msgid */ \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_set_header_aligned), \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_set_union_aligned), \ + (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_set), \ + (u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_set), \ + NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) + +#define BOARDOBJGRP_PMU_CMD_GRP_GET_STATUS_CONSTRUCT(g, pboardobjgrp, \ + eng, ENG, class, CLASS) \ + g->ops.pmu_ver.boardobj.boardobjgrp_pmucmd_construct_impl( \ + g, /* pGpu */ \ + pboardobjgrp, /* pBoardObjGrp */ \ + &((pboardobjgrp)->pmu.getstatus), /* pCmd */ \ + NV_PMU_##ENG##_CMD_ID_BOARDOBJ_GRP_GET_STATUS, /* id */ \ + NV_PMU_##ENG##_MSG_ID_BOARDOBJ_GRP_GET_STATUS, /* msgid */ \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobjgrp_get_status_header_aligned), \ + (u32)sizeof(union nv_pmu_##eng##_##class##_boardobj_get_status_union_aligned), \ + (u32)sizeof(struct nv_pmu_##eng##_##class##_boardobj_grp_get_status), \ + (u32)offsetof(struct nv_pmu_super_surface, eng.class##_grp_get_status), \ + NV_PMU_RPC_ID_##ENG##_BOARD_OBJ_GRP_CMD) + +/* ------------------------ Function Prototypes ----------------------------- */ +/* Constructor and destructor */ +int boardobjgrp_construct_super(struct gk20a *g, + struct boardobjgrp *pboardobjgrp); +boardobjgrp_destruct boardobjgrp_destruct_impl; +boardobjgrp_destruct boardobjgrp_destruct_super; + +/* PMU_CMD interfaces */ +boardobjgrp_pmucmd_construct boardobjgrp_pmucmd_construct_impl; +boardobjgrp_pmucmd_destroy boardobjgrp_pmucmd_destroy_impl; +boardobjgrp_pmucmd_pmuinithandle boardobjgrp_pmucmd_pmuinithandle_impl; + +boardobjgrp_pmucmd_construct boardobjgrp_pmucmd_construct_impl_v1; + +/* BOARDOBJGRP interfaces */ +boardobjgrp_pmuinithandle boardobjgrp_pmuinithandle_impl; +boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_super; +boardobjgrp_pmudatainit boardobjgrp_pmudatainit_super; + +boardobjgrp_pmudatainit boardobjgrp_pmudatainit_legacy; +boardobjgrp_pmuset boardobjgrp_pmuset_impl; +boardobjgrp_pmugetstatus boardobjgrp_pmugetstatus_impl; +boardobjgrp_pmuset boardobjgrp_pmuset_impl_v1; +boardobjgrp_pmugetstatus boardobjgrp_pmugetstatus_impl_v1; + +void boardobjgrpe32hdrset(struct nv_pmu_boardobjgrp *hdr, u32 objmask); + +#define HIGHESTBITIDX_32(n32) \ +{ \ + u32 count = 0U; \ + while (n32 >>= 1U) { \ + count++; \ + } \ + n32 = count; \ +} + +#define LOWESTBIT(x) ((x) & (((x)-1U) ^ (x))) + +#define HIGHESTBIT(n32) \ +{ \ + HIGHESTBITIDX_32(n32); \ + n32 = NVBIT(n32); \ +} + +#define ONEBITSET(x) ((x) && (((x) & ((x)-1U)) == 0U)) + +#define LOWESTBITIDX_32(n32) \ +{ \ + n32 = LOWESTBIT(n32); \ + IDX_32(n32); \ +} + +#define NUMSETBITS_32(n32) \ +{ \ + n32 = n32 - ((n32 >> 1U) & 0x55555555U); \ + n32 = (n32 & 0x33333333U) + ((n32 >> 2U) & 0x33333333U); \ + n32 = (((n32 + (n32 >> 4U)) & 0x0F0F0F0FU) * 0x01010101U) >> 24U; \ +} + +#define IDX_32(n32) \ +{ \ + u32 idx = 0U; \ + if ((n32) & 0xFFFF0000U) \ + idx += 16U; \ + if ((n32) & 0xFF00FF00U) \ + idx += 8U; \ + if ((n32) & 0xF0F0F0F0U) \ + idx += 4U; \ + if ((n32) & 0xCCCCCCCCU) \ + idx += 2U; \ + if ((n32) & 0xAAAAAAAAU) \ + idx += 1U; \ + (n32) = idx; \ +} + +static inline struct boardobjgrp * +boardobjgrp_from_node(struct nvgpu_list_node *node) +{ + return (struct boardobjgrp *) + ((uintptr_t)node - offsetof(struct boardobjgrp, node)); +}; + +int is_boardobjgrp_pmucmd_id_valid_v0(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd); +int is_boardobjgrp_pmucmd_id_valid_v1(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct boardobjgrp_pmu_cmd *cmd); +#endif /* NVGPU_BOARDOBJGRP_H */ diff --git a/include/boardobj/boardobjgrp_e255.c b/include/boardobj/boardobjgrp_e255.c new file mode 100644 index 0000000..63546a9 --- /dev/null +++ b/include/boardobj/boardobjgrp_e255.c @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. +*/ + +#include + +#include "boardobj.h" +#include "boardobjgrp_e255.h" +#include "ctrl/ctrlboardobj.h" +#include "boardobjgrp.h" +#include "boardobjgrpmask.h" + +int boardobjgrpconstruct_e255(struct gk20a *g, + struct boardobjgrp_e255 *pboardobjgrp_e255) +{ + int status = 0; + u8 objslots; + + nvgpu_log_info(g, " "); + + objslots = 255; + status = boardobjgrpmask_e255_init(&pboardobjgrp_e255->mask, NULL); + if (status) { + goto boardobjgrpconstruct_e255_exit; + } + + pboardobjgrp_e255->super.type = CTRL_BOARDOBJGRP_TYPE_E255; + pboardobjgrp_e255->super.ppobjects = pboardobjgrp_e255->objects; + pboardobjgrp_e255->super.objslots = objslots; + pboardobjgrp_e255->super.mask = &(pboardobjgrp_e255->mask.super); + + status = boardobjgrp_construct_super(g, &pboardobjgrp_e255->super); + if (status) { + goto boardobjgrpconstruct_e255_exit; + } + + pboardobjgrp_e255->super.pmuhdrdatainit = + boardobjgrp_pmuhdrdatainit_e255; + +boardobjgrpconstruct_e255_exit: + return status; +} + +int boardobjgrp_pmuhdrdatainit_e255(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask) +{ + struct nv_pmu_boardobjgrp_e255 *pgrpe255 = + (struct nv_pmu_boardobjgrp_e255 *)pboardobjgrppmu; + int status; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + + status = boardobjgrpmask_export(mask, + mask->bitcount, + &pgrpe255->obj_mask.super); + if (status) { + nvgpu_err(g, "e255 init:failed export grpmask"); + return status; + } + + return boardobjgrp_pmuhdrdatainit_super(g, + pboardobjgrp, pboardobjgrppmu, mask); +} diff --git a/include/boardobj/boardobjgrp_e255.h b/include/boardobj/boardobjgrp_e255.h new file mode 100644 index 0000000..bc40541 --- /dev/null +++ b/include/boardobj/boardobjgrp_e255.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef NVGPU_BOARDOBJGRP_E255_H +#define NVGPU_BOARDOBJGRP_E255_H + +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" +#include "boardobjgrpmask.h" +#include "boardobj/boardobjgrp.h" + +/* + * boardobjgrp_e255 is @ref BOARDOBJGRP child class allowing storage of up + * to 255 @ref BOARDOBJ object pointers with single static 255-bit mask denoting + * valid object pointers. + */ +struct boardobjgrp_e255 { + struct boardobjgrp super; + struct boardobj *objects[CTRL_BOARDOBJGRP_E255_MAX_OBJECTS]; + struct boardobjgrpmask_e255 mask; +}; + +#define boardobjgrp_pmudatainit_e255(g, pboardpbjgrp, pboardobjgrppmu) \ + boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu) + +/* Constructor and destructor */ +int boardobjgrpconstruct_e255(struct gk20a *g, + struct boardobjgrp_e255 *pboardobjgrp); +boardobjgrp_destruct boardobjgrpdestruct_e255; +boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e255; + +#endif /* NVGPU_BOARDOBJGRP_E255_H */ diff --git a/include/boardobj/boardobjgrp_e32.c b/include/boardobj/boardobjgrp_e32.c new file mode 100644 index 0000000..d72e8cb --- /dev/null +++ b/include/boardobj/boardobjgrp_e32.c @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. +* + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. +*/ +#include + +#include "boardobj.h" +#include "boardobjgrp.h" +#include "boardobjgrp_e32.h" +#include "ctrl/ctrlboardobj.h" +#include "boardobjgrpmask.h" + + +int boardobjgrpconstruct_e32(struct gk20a *g, + struct boardobjgrp_e32 *pboardobjgrp_e32) +{ + int status; + u8 objslots; + + nvgpu_log_info(g, " "); + objslots = 32; + + status = boardobjgrpmask_e32_init(&pboardobjgrp_e32->mask, NULL); + if (status) { + goto boardobjgrpconstruct_e32_exit; + } + + pboardobjgrp_e32->super.type = CTRL_BOARDOBJGRP_TYPE_E32; + pboardobjgrp_e32->super.ppobjects = pboardobjgrp_e32->objects; + pboardobjgrp_e32->super.objslots = objslots; + pboardobjgrp_e32->super.mask = &(pboardobjgrp_e32->mask.super); + + status = boardobjgrp_construct_super(g, &pboardobjgrp_e32->super); + if (status) { + goto boardobjgrpconstruct_e32_exit; + } + + pboardobjgrp_e32->super.pmuhdrdatainit = boardobjgrp_pmuhdrdatainit_e32; + +boardobjgrpconstruct_e32_exit: + return status; +} + +int boardobjgrp_pmuhdrdatainit_e32(struct gk20a *g, + struct boardobjgrp *pboardobjgrp, + struct nv_pmu_boardobjgrp_super *pboardobjgrppmu, + struct boardobjgrpmask *mask) +{ + struct nv_pmu_boardobjgrp_e32 *pgrpe32 = + (struct nv_pmu_boardobjgrp_e32 *)pboardobjgrppmu; + int status; + + nvgpu_log_info(g, " "); + + if (pboardobjgrp == NULL) { + return -EINVAL; + } + + if (pboardobjgrppmu == NULL) { + return -EINVAL; + } + status = boardobjgrpmask_export(mask, + mask->bitcount, + &pgrpe32->obj_mask.super); + if (status) { + nvgpu_err(g, "e32 init:failed export grpmask"); + return status; + } + + return boardobjgrp_pmuhdrdatainit_super(g, + pboardobjgrp, pboardobjgrppmu, mask); +} diff --git a/include/boardobj/boardobjgrp_e32.h b/include/boardobj/boardobjgrp_e32.h new file mode 100644 index 0000000..d4beb47 --- /dev/null +++ b/include/boardobj/boardobjgrp_e32.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef NVGPU_BOARDOBJGRP_E32_H +#define NVGPU_BOARDOBJGRP_E32_H + +#include "ctrl/ctrlboardobj.h" +#include "boardobj.h" +#include "boardobjgrp.h" +#include "boardobjgrpmask.h" +#include "boardobj/boardobjgrp.h" + +/* + * boardobjgrp_e32 is @ref BOARDOBJGRP child class allowing storage of up to 32 + * @ref BOARDOBJ object pointers with single static 32-bit mask denoting valid + * object pointers. + */ +struct boardobjgrp_e32 { + /* + * BOARDOBJGRP super-class. Must be first element of the structure. + */ + struct boardobjgrp super; + /* + * Statically allocated array of PBOARDOBJ-s + */ + struct boardobj *objects[CTRL_BOARDOBJGRP_E32_MAX_OBJECTS]; + + /* + * Statically allocated mask strcuture referenced by super::pMask. + */ + struct boardobjgrpmask_e32 mask; +}; + +/* + * Wrapper to the _SUPER implementation. Provided for the child classes which + * implement this interface. + */ +#define boardobjgrp_pmudatainit_e32(g, pboardpbjgrp, pboardobjgrppmu) \ + boardobjgrp_pmudatainit_super(g, pboardpbjgrp, pboardobjgrppmu) + +/* Constructor and destructor */ +int boardobjgrpconstruct_e32(struct gk20a *g, + struct boardobjgrp_e32 *pboardobjgrp); +boardobjgrp_destruct boardobjgrpdestruct_e32; +boardobjgrp_pmuhdrdatainit boardobjgrp_pmuhdrdatainit_e32; + +#endif /* NVGPU_BOARDOBJGRP_E32_H */ diff --git a/include/boardobj/boardobjgrpmask.c b/include/boardobj/boardobjgrpmask.c new file mode 100644 index 0000000..a1dcd6d --- /dev/null +++ b/include/boardobj/boardobjgrpmask.c @@ -0,0 +1,411 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ +#include + +#include "boardobjgrp.h" +#include "ctrl/ctrlboardobj.h" + +/* +* Assures that unused bits (size .. (maskDataCount * 32 - 1)) are always zero. +*/ +#define BOARDOBJGRPMASK_NORMALIZE(_pmask) \ + ((_pmask)->data[(_pmask)->maskdatacount-1] &= (_pmask)->lastmaskfilter) + +u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask) +{ + if (mask == NULL) { + return -EINVAL; + } + if ((bitsize != CTRL_BOARDOBJGRP_E32_MAX_OBJECTS) && + (bitsize != CTRL_BOARDOBJGRP_E255_MAX_OBJECTS)) { + return -EINVAL; + } + + mask->bitcount = bitsize; + mask->maskdatacount = CTRL_BOARDOBJGRP_MASK_DATA_SIZE(bitsize); + mask->lastmaskfilter = bitsize % + CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; + + mask->lastmaskfilter = (mask->lastmaskfilter == 0) ? + 0xFFFFFFFF : (u32)(BIT(mask->lastmaskfilter) - 1); + + return (extmask == NULL) ? + boardobjgrpmask_clr(mask) : + boardobjgrpmask_import(mask, bitsize, extmask); +} + +u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + if (extmask == NULL) { + return -EINVAL; + } + if (mask->bitcount != bitsize) { + return -EINVAL; + } + + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = extmask->data[index]; + } + + BOARDOBJGRPMASK_NORMALIZE(mask); + + return 0; +} + +u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + if (extmask == NULL) { + return -EINVAL; + } + if (mask->bitcount != bitsize) { + return -EINVAL; + } + + for (index = 0; index < mask->maskdatacount; index++) { + extmask->data[index] = mask->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = 0; + } + + return 0; +} + +u32 boardobjgrpmask_set(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = 0xFFFFFFFF; + } + BOARDOBJGRPMASK_NORMALIZE(mask); + return 0; +} + +u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return -EINVAL; + } + for (index = 0; index < mask->maskdatacount; index++) { + mask->data[index] = ~mask->data[index]; + } + BOARDOBJGRPMASK_NORMALIZE(mask); + return 0; +} + +bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask) +{ + u8 index; + + if (mask == NULL) { + return true; + } + for (index = 0; index < mask->maskdatacount; index++) { + if (mask->data[index] != 0) { + return false; + } + } + return true; +} + +u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask) +{ + u8 index; + u8 result = 0; + + if (mask == NULL) { + return result; + } + + for (index = 0; index < mask->maskdatacount; index++) { + u32 m = mask->data[index]; + + NUMSETBITS_32(m); + result += (u8)m; + } + + return result; +} + +u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask) +{ + u8 index; + u8 result = CTRL_BOARDOBJ_IDX_INVALID; + + if (mask == NULL) { + return result; + } + + for (index = 0; index < mask->maskdatacount; index++) { + u32 m = mask->data[index]; + + if (m != 0) { + LOWESTBITIDX_32(m); + result = (u8)m + index * + CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; + break; + } + } + + return result; +} + +u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask) +{ + u8 index; + u8 result = CTRL_BOARDOBJ_IDX_INVALID; + + if (mask == NULL) { + return result; + } + + for (index = 0; index < mask->maskdatacount; index++) { + u32 m = mask->data[index]; + + if (m != 0) { + HIGHESTBITIDX_32(m); + result = (u8)m + index * + CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_BIT_SIZE; + break; + } + } + + return result; +} + +int boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return -EINVAL; + } + if (bitidx >= mask->bitcount) { + return -EINVAL; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + mask->data[index] &= ~BIT(offset); + + return 0; +} + +int boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return -EINVAL; + } + if (bitidx >= mask->bitcount) { + return -EINVAL; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + mask->data[index] |= BIT(offset); + + return 0; +} + +u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return -EINVAL; + } + if (bitidx >= mask->bitcount) { + return -EINVAL; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + mask->data[index] ^= ~BIT(offset); + + return 0; +} + +bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx) +{ + u8 index; + u8 offset; + + if (mask == NULL) { + return false; + } + if (bitidx >= mask->bitcount) { + return false; + } + + index = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_INDEX(bitidx); + offset = CTRL_BOARDOBJGRP_MASK_MASK_ELEMENT_OFFSET(bitidx); + + return (mask->data[index] & BIT(offset)) != 0; +} + +u32 boardobjgrpmask_and(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, op1)) { + return -EINVAL; + } + if (!boardobjgrpmask_sizeeq(dst, op2)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = op1->data[index] & op2->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, op1)) { + return -EINVAL; + } + if (!boardobjgrpmask_sizeeq(dst, op2)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = op1->data[index] | op2->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, op1)) { + return -EINVAL; + } + if (!boardobjgrpmask_sizeeq(dst, op2)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = op1->data[index] ^ op2->data[index]; + } + + return 0; +} + +u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst, + struct boardobjgrpmask *src) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(dst, src)) { + return -EINVAL; + } + + for (index = 0; index < dst->maskdatacount; index++) { + dst->data[index] = src->data[index]; + } + + return 0; +} + +bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + if (op1 == NULL) { + return false; + } + if (op2 == NULL) { + return false; + } + + return op1->bitcount == op2->bitcount; +} + +bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2) +{ + u8 index; + + if (!boardobjgrpmask_sizeeq(op2, op1)) { + return false; + } + + for (index = 0; index < op1->maskdatacount; index++) { + u32 op_1 = op1->data[index]; + u32 op_2 = op2->data[index]; + + if ((op_1 & op_2) != op_1) { + return false; + } + } + + return true; +} diff --git a/include/boardobj/boardobjgrpmask.h b/include/boardobj/boardobjgrpmask.h new file mode 100644 index 0000000..f4ed0af --- /dev/null +++ b/include/boardobj/boardobjgrpmask.h @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016-2018, NVIDIA CORPORATION. All rights reserved. + * + * 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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. + */ + +#ifndef NVGPU_BOARDOBJGRPMASK_H +#define NVGPU_BOARDOBJGRPMASK_H + +#include "ctrl/ctrlboardobj.h" + + +/* +* Board Object Group Mask super-structure. +* Used to unify access to all BOARDOBJGRPMASK_E** child classes +*/ +struct boardobjgrpmask { + /* Number of bits supported by the mask */ + u8 bitcount; + /* Number of 32-bit words required to store all @ref bitCount bits */ + u8 maskdatacount; + /* + * Bit-mask of used-bits within last 32-bit word. Used to + * normalize data + */ + u32 lastmaskfilter; + /* + * Start of the array of 32-bit words representing the bit-mask + * Must be the last element of the structure. + */ + u32 data[CTRL_BOARDOBJGRP_MASK_ARRAY_START_SIZE]; +}; + +struct boardobjgrpmask_e32 { + /* + * BOARDOBJGRPMASK super-class. Must be the first element of the + * structure. + */ + struct boardobjgrpmask super; + /*u32 data_e32[1]; */ +}; + +struct boardobjgrpmask_e255 { + /* + * BOARDOBJGRPMASK super-class. Must be the first element of the + * structure. + */ + struct boardobjgrpmask super; + u32 data_e255[254]; +}; + +/* Init and I/O operations.*/ +u32 boardobjgrpmask_init(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask); +u32 boardobjgrpmask_import(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask); +u32 boardobjgrpmask_export(struct boardobjgrpmask *mask, u8 bitsize, + struct ctrl_boardobjgrp_mask *extmask); + +/* Operations on all bits of a single mask.*/ +u32 boardobjgrpmask_clr(struct boardobjgrpmask *mask); +u32 boardobjgrpmask_set(struct boardobjgrpmask *mask); +u32 boardobjgrpmask_inv(struct boardobjgrpmask *mask); +bool boardobjgrpmask_iszero(struct boardobjgrpmask *mask); +u8 boardobjgrpmask_bitsetcount(struct boardobjgrpmask *mask); +u8 boardobjgrpmask_bitidxlowest(struct boardobjgrpmask *mask); +u8 boardobjgrpmask_bitidxhighest(struct boardobjgrpmask *mask); + +/* Operations on a single bit of a single mask */ +int boardobjgrpmask_bitclr(struct boardobjgrpmask *mask, u8 bitidx); +int boardobjgrpmask_bitset(struct boardobjgrpmask *mask, u8 bitidx); +u32 boardobjgrpmask_bitinv(struct boardobjgrpmask *mask, u8 bitidx); +bool boardobjgrpmask_bitget(struct boardobjgrpmask *mask, u8 bitidx); + +/* Operations on a multiple masks */ +u32 boardobjgrpmask_and(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); +u32 boardobjgrpmask_or(struct boardobjgrpmask *dst, struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); +u32 boardobjgrpmask_xor(struct boardobjgrpmask *dst, + struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); + +/* Special interfaces */ +u32 boardobjgrpmask_copy(struct boardobjgrpmask *dst, + struct boardobjgrpmask *src); +bool boardobjgrpmask_sizeeq(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); +bool boardobjgrpmask_issubset(struct boardobjgrpmask *op1, + struct boardobjgrpmask *op2); + +/* init boardobjgrpmask_e32 structure */ +#define boardobjgrpmask_e32_init(pmaske32, pextmask) \ + boardobjgrpmask_init(&(pmaske32)->super, \ + CTRL_BOARDOBJGRP_E32_MAX_OBJECTS, (pextmask)) + +/* init boardobjgrpmask_e255 structure */ +#define boardobjgrpmask_e255_init(pmaske255, pextmask) \ + boardobjgrpmask_init(&(pmaske255)->super, \ + CTRL_BOARDOBJGRP_E255_MAX_OBJECTS, (pextmask)) + +#endif /* NVGPU_BOARDOBJGRPMASK_H */ -- cgit v1.2.2