mirror of
git://nv-tegra.nvidia.com/linux-nvgpu.git
synced 2025-12-24 02:22:34 +03:00
Open source GPL/LGPL release
This commit is contained in:
303
drivers/gpu/nvgpu/common/sim/sim.c
Normal file
303
drivers/gpu/nvgpu/common/sim/sim.c
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021, 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 <nvgpu/log.h>
|
||||
#include <nvgpu/bitops.h>
|
||||
#include <nvgpu/nvgpu_mem.h>
|
||||
#include <nvgpu/dma.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/hw_sim.h>
|
||||
#include <nvgpu/sim.h>
|
||||
#include <nvgpu/utils.h>
|
||||
#include <nvgpu/bug.h>
|
||||
#include <nvgpu/string.h>
|
||||
|
||||
void sim_writel(struct sim_nvgpu *sim, u32 r, u32 v)
|
||||
{
|
||||
nvgpu_os_writel(v, sim->regs + r);
|
||||
}
|
||||
|
||||
u32 sim_readl(struct sim_nvgpu *sim, u32 r)
|
||||
{
|
||||
return nvgpu_os_readl(sim->regs + r);
|
||||
}
|
||||
|
||||
int nvgpu_alloc_sim_buffer(struct gk20a *g, struct nvgpu_mem *mem)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
if (!nvgpu_mem_is_valid(mem)) {
|
||||
err = nvgpu_dma_alloc_sys(g, NVGPU_CPU_PAGE_SIZE, mem);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
void nvgpu_free_sim_buffer(struct gk20a *g, struct nvgpu_mem *mem)
|
||||
{
|
||||
if (nvgpu_mem_is_valid(mem)) {
|
||||
nvgpu_dma_free(g, mem);
|
||||
}
|
||||
|
||||
(void) memset(mem, 0, sizeof(*mem));
|
||||
}
|
||||
|
||||
void nvgpu_free_sim_support(struct gk20a *g)
|
||||
{
|
||||
nvgpu_free_sim_buffer(g, &g->sim->send_bfr);
|
||||
nvgpu_free_sim_buffer(g, &g->sim->recv_bfr);
|
||||
nvgpu_free_sim_buffer(g, &g->sim->msg_bfr);
|
||||
}
|
||||
|
||||
void nvgpu_remove_sim_support(struct gk20a *g)
|
||||
{
|
||||
if (g->sim) {
|
||||
nvgpu_free_sim_support(g);
|
||||
}
|
||||
}
|
||||
|
||||
void sim_write_hdr(struct gk20a *g, u32 func, u32 size)
|
||||
{
|
||||
/*memset(g->sim->msg_bfr.kvaddr,0,min(NVGPU_CPU_PAGE_SIZE,size));*/
|
||||
*sim_msg_hdr(g, sim_msg_signature_r()) = sim_msg_signature_valid_v();
|
||||
*sim_msg_hdr(g, sim_msg_result_r()) = sim_msg_result_rpc_pending_v();
|
||||
*sim_msg_hdr(g, sim_msg_spare_r()) = sim_msg_spare__init_v();
|
||||
*sim_msg_hdr(g, sim_msg_function_r()) = func;
|
||||
*sim_msg_hdr(g, sim_msg_length_r()) = size + sim_msg_header_size();
|
||||
}
|
||||
|
||||
static u32 *sim_send_ring_bfr(struct gk20a *g, u32 byte_offset)
|
||||
{
|
||||
u8 *cpu_va;
|
||||
|
||||
cpu_va = (u8 *)g->sim->send_bfr.cpu_va;
|
||||
|
||||
return (u32 *)(cpu_va + byte_offset);
|
||||
}
|
||||
|
||||
static int rpc_send_message(struct gk20a *g)
|
||||
{
|
||||
/* calculations done in units of u32s */
|
||||
u32 send_base = sim_send_put_pointer_v(g->sim->send_ring_put) * 2;
|
||||
u32 dma_offset = send_base + sim_dma_r()/sizeof(u32);
|
||||
u32 dma_hi_offset = send_base + sim_dma_hi_r()/sizeof(u32);
|
||||
|
||||
*sim_send_ring_bfr(g, dma_offset*sizeof(u32)) =
|
||||
sim_dma_target_phys_pci_coherent_f() |
|
||||
sim_dma_status_valid_f() |
|
||||
sim_dma_size_4kb_f() |
|
||||
sim_dma_addr_lo_f(nvgpu_mem_get_addr(g, &g->sim->msg_bfr)
|
||||
>> sim_dma_addr_lo_b());
|
||||
|
||||
*sim_send_ring_bfr(g, dma_hi_offset*sizeof(u32)) =
|
||||
u64_hi32(nvgpu_mem_get_addr(g, &g->sim->msg_bfr));
|
||||
|
||||
*sim_msg_hdr(g, sim_msg_sequence_r()) = g->sim->sequence_base++;
|
||||
|
||||
g->sim->send_ring_put = (g->sim->send_ring_put + 2 * sizeof(u32))
|
||||
% SIM_BFR_SIZE;
|
||||
|
||||
/* Update the put pointer. This will trap into the host. */
|
||||
sim_writel(g->sim, sim_send_put_r(), g->sim->send_ring_put);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 *sim_recv_ring_bfr(struct gk20a *g, u32 byte_offset)
|
||||
{
|
||||
u8 *cpu_va;
|
||||
|
||||
cpu_va = (u8 *)g->sim->recv_bfr.cpu_va;
|
||||
|
||||
return (u32 *)(cpu_va + byte_offset);
|
||||
}
|
||||
|
||||
static int rpc_recv_poll(struct gk20a *g)
|
||||
{
|
||||
u64 recv_phys_addr;
|
||||
|
||||
/* XXX This read is not required (?) */
|
||||
/*pVGpu->recv_ring_get = VGPU_REG_RD32(pGpu, NV_VGPU_RECV_GET);*/
|
||||
|
||||
/* Poll the recv ring get pointer in an infinite loop*/
|
||||
do {
|
||||
g->sim->recv_ring_put = sim_readl(g->sim, sim_recv_put_r());
|
||||
} while (g->sim->recv_ring_put == g->sim->recv_ring_get);
|
||||
|
||||
/* process all replies */
|
||||
while (g->sim->recv_ring_put != g->sim->recv_ring_get) {
|
||||
/* these are in u32 offsets*/
|
||||
u32 dma_lo_offset =
|
||||
sim_recv_put_pointer_v(g->sim->recv_ring_get)*2 + 0;
|
||||
u32 dma_hi_offset = dma_lo_offset + 1;
|
||||
u32 recv_phys_addr_lo = sim_dma_addr_lo_v(
|
||||
*sim_recv_ring_bfr(g, dma_lo_offset*4));
|
||||
u32 recv_phys_addr_hi = sim_dma_hi_addr_v(
|
||||
*sim_recv_ring_bfr(g, dma_hi_offset*4));
|
||||
|
||||
recv_phys_addr = (u64)recv_phys_addr_hi << 32 |
|
||||
(u64)recv_phys_addr_lo << sim_dma_addr_lo_b();
|
||||
|
||||
if (recv_phys_addr !=
|
||||
nvgpu_mem_get_addr(g, &g->sim->msg_bfr)) {
|
||||
nvgpu_err(g, "%s Error in RPC reply",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Update GET pointer */
|
||||
g->sim->recv_ring_get = (g->sim->recv_ring_get + 2*sizeof(u32))
|
||||
% SIM_BFR_SIZE;
|
||||
|
||||
sim_writel(g->sim, sim_recv_get_r(), g->sim->recv_ring_get);
|
||||
|
||||
g->sim->recv_ring_put = sim_readl(g->sim, sim_recv_put_r());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int issue_rpc_and_wait(struct gk20a *g)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rpc_send_message(g);
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "%s failed rpc_send_message",
|
||||
__func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = rpc_recv_poll(g);
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "%s failed rpc_recv_poll",
|
||||
__func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Now check if RPC really succeeded */
|
||||
if (*sim_msg_hdr(g, sim_msg_result_r()) != sim_msg_result_success_v()) {
|
||||
nvgpu_err(g, "%s received failed status!",
|
||||
__func__);
|
||||
return -(*sim_msg_hdr(g, sim_msg_result_r()));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nvgpu_sim_esc_readl(struct gk20a *g,
|
||||
const char *path, u32 index, u32 *data)
|
||||
{
|
||||
int err;
|
||||
size_t pathlen = strlen(path);
|
||||
u32 data_offset;
|
||||
|
||||
sim_write_hdr(g, sim_msg_function_sim_escape_read_v(),
|
||||
sim_escape_read_hdr_size());
|
||||
*sim_msg_param(g, 0) = index;
|
||||
*sim_msg_param(g, 4) = sizeof(u32);
|
||||
data_offset = round_up(0xc + pathlen + 1, sizeof(u32));
|
||||
*sim_msg_param(g, 8) = data_offset;
|
||||
strcpy((char *)sim_msg_param(g, 0xc), path);
|
||||
|
||||
err = issue_rpc_and_wait(g);
|
||||
|
||||
if (err == 0) {
|
||||
nvgpu_memcpy((u8 *)data, (u8 *)sim_msg_param(g, data_offset),
|
||||
sizeof(u32));
|
||||
} else {
|
||||
*data = 0xffffffff;
|
||||
WARN(1, "issue_rpc_and_wait failed err=%d", err);
|
||||
}
|
||||
}
|
||||
|
||||
static int nvgpu_sim_init_late(struct gk20a *g)
|
||||
{
|
||||
u64 phys;
|
||||
int err = -ENOMEM;
|
||||
|
||||
if (!g->sim) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nvgpu_info(g, "sim init late");
|
||||
|
||||
/* allocate sim event/msg buffers */
|
||||
err = nvgpu_alloc_sim_buffer(g, &g->sim->send_bfr);
|
||||
err = err || nvgpu_alloc_sim_buffer(g, &g->sim->recv_bfr);
|
||||
err = err || nvgpu_alloc_sim_buffer(g, &g->sim->msg_bfr);
|
||||
|
||||
if (err != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/*mark send ring invalid*/
|
||||
sim_writel(g->sim, sim_send_ring_r(), sim_send_ring_status_invalid_f());
|
||||
|
||||
/*read get pointer and make equal to put*/
|
||||
g->sim->send_ring_put = sim_readl(g->sim, sim_send_get_r());
|
||||
sim_writel(g->sim, sim_send_put_r(), g->sim->send_ring_put);
|
||||
|
||||
/*write send ring address and make it valid*/
|
||||
phys = nvgpu_mem_get_addr(g, &g->sim->send_bfr);
|
||||
sim_writel(g->sim, sim_send_ring_hi_r(),
|
||||
sim_send_ring_hi_addr_f(u64_hi32(phys)));
|
||||
sim_writel(g->sim, sim_send_ring_r(),
|
||||
sim_send_ring_status_valid_f() |
|
||||
sim_send_ring_target_phys_pci_coherent_f() |
|
||||
sim_send_ring_size_4kb_f() |
|
||||
sim_send_ring_addr_lo_f(phys >> sim_send_ring_addr_lo_b()));
|
||||
|
||||
/*repeat for recv ring (but swap put,get as roles are opposite) */
|
||||
sim_writel(g->sim, sim_recv_ring_r(), sim_recv_ring_status_invalid_f());
|
||||
|
||||
/*read put pointer and make equal to get*/
|
||||
g->sim->recv_ring_get = sim_readl(g->sim, sim_recv_put_r());
|
||||
sim_writel(g->sim, sim_recv_get_r(), g->sim->recv_ring_get);
|
||||
|
||||
/*write send ring address and make it valid*/
|
||||
phys = nvgpu_mem_get_addr(g, &g->sim->recv_bfr);
|
||||
sim_writel(g->sim, sim_recv_ring_hi_r(),
|
||||
sim_recv_ring_hi_addr_f(u64_hi32(phys)));
|
||||
sim_writel(g->sim, sim_recv_ring_r(),
|
||||
sim_recv_ring_status_valid_f() |
|
||||
sim_recv_ring_target_phys_pci_coherent_f() |
|
||||
sim_recv_ring_size_4kb_f() |
|
||||
sim_recv_ring_addr_lo_f(phys >> sim_recv_ring_addr_lo_b()));
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
nvgpu_free_sim_support(g);
|
||||
return err;
|
||||
}
|
||||
|
||||
int nvgpu_init_sim_support(struct gk20a *g)
|
||||
{
|
||||
if (!g->sim) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
g->sim->sim_init_late = nvgpu_sim_init_late;
|
||||
g->sim->remove_support = nvgpu_remove_sim_support;
|
||||
g->sim->esc_readl = nvgpu_sim_esc_readl;
|
||||
return 0;
|
||||
}
|
||||
820
drivers/gpu/nvgpu/common/sim/sim_netlist.c
Normal file
820
drivers/gpu/nvgpu/common/sim/sim_netlist.c
Normal file
@@ -0,0 +1,820 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2020, 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 <nvgpu/gk20a.h>
|
||||
#include <nvgpu/sim.h>
|
||||
#include <nvgpu/netlist.h>
|
||||
#include <nvgpu/log.h>
|
||||
#if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
|
||||
#include "nvgpu/nvgpu_next_sim.h"
|
||||
#endif
|
||||
|
||||
int nvgpu_init_sim_netlist_ctx_vars(struct gk20a *g)
|
||||
{
|
||||
int err = -ENOMEM;
|
||||
u32 i, temp;
|
||||
u32 fecs_inst_count, fecs_data_count;
|
||||
u32 gpccs_inst_count, gpccs_data_count;
|
||||
struct netlist_av_list *sw_bundle_init;
|
||||
struct netlist_av_list *sw_method_init;
|
||||
struct netlist_aiv_list *sw_ctx_load;
|
||||
struct netlist_av_list *sw_non_ctx_load;
|
||||
struct netlist_av_list *sw_veid_bundle_init;
|
||||
struct netlist_av64_list *sw_bundle64_init;
|
||||
#ifdef CONFIG_NVGPU_DEBUGGER
|
||||
struct netlist_aiv_list *sys_ctxsw_regs;
|
||||
struct netlist_aiv_list *gpc_ctxsw_regs;
|
||||
struct netlist_aiv_list *tpc_ctxsw_regs;
|
||||
#ifdef CONFIG_NVGPU_GRAPHICS
|
||||
struct netlist_aiv_list *zcull_gpc_ctxsw_regs;
|
||||
#endif
|
||||
struct netlist_aiv_list *pm_sys_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_gpc_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_tpc_ctxsw_regs;
|
||||
struct netlist_aiv_list *ppc_ctxsw_regs;
|
||||
struct netlist_aiv_list *etpc_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_ppc_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_sys_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_sysrouter_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_sys_control_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_pma_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_fbp_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_fbprouter_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_gpc_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_gpcrouter_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_ltc_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_rop_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_ucgpc_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_cau_ctxsw_regs;
|
||||
struct netlist_aiv_list *pm_fbpa_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_fbp_control_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_gpc_control_ctxsw_regs;
|
||||
struct netlist_aiv_list *perf_pma_control_ctxsw_regs;
|
||||
#endif /* CONFIG_NVGPU_DEBUGGER */
|
||||
struct netlist_u32_list *fecs_inst, *fecs_data;
|
||||
struct netlist_u32_list *gpccs_inst, *gpccs_data;
|
||||
u32 regs_base_index;
|
||||
|
||||
nvgpu_log(g, gpu_dbg_fn | gpu_dbg_info,
|
||||
"querying grctx info from chiplib");
|
||||
|
||||
nvgpu_netlist_vars_set_dynamic(g, true);
|
||||
|
||||
if (g->sim->esc_readl == NULL) {
|
||||
nvgpu_err(g, "Invalid pointer to query function.");
|
||||
err = -ENOENT;
|
||||
return err;
|
||||
}
|
||||
|
||||
sw_bundle_init = nvgpu_netlist_get_sw_bundle_init_av_list(g);
|
||||
sw_method_init = nvgpu_netlist_get_sw_method_init_av_list(g);
|
||||
sw_ctx_load = nvgpu_netlist_get_sw_ctx_load_aiv_list(g);
|
||||
sw_non_ctx_load = nvgpu_netlist_get_sw_non_ctx_load_av_list(g);
|
||||
sw_veid_bundle_init = nvgpu_netlist_get_sw_veid_bundle_init_av_list(g);
|
||||
sw_bundle64_init = nvgpu_netlist_get_sw_bundle64_init_av64_list(g);
|
||||
|
||||
#ifdef CONFIG_NVGPU_DEBUGGER
|
||||
sys_ctxsw_regs = nvgpu_netlist_get_sys_ctxsw_regs(g);
|
||||
gpc_ctxsw_regs = nvgpu_netlist_get_gpc_ctxsw_regs(g);
|
||||
tpc_ctxsw_regs = nvgpu_netlist_get_tpc_ctxsw_regs(g);
|
||||
#ifdef CONFIG_NVGPU_GRAPHICS
|
||||
zcull_gpc_ctxsw_regs = nvgpu_netlist_get_zcull_gpc_ctxsw_regs(g);
|
||||
#endif
|
||||
pm_sys_ctxsw_regs = nvgpu_netlist_get_pm_sys_ctxsw_regs(g);
|
||||
pm_gpc_ctxsw_regs = nvgpu_netlist_get_pm_gpc_ctxsw_regs(g);
|
||||
pm_tpc_ctxsw_regs = nvgpu_netlist_get_pm_tpc_ctxsw_regs(g);
|
||||
ppc_ctxsw_regs = nvgpu_netlist_get_ppc_ctxsw_regs(g);
|
||||
etpc_ctxsw_regs = nvgpu_netlist_get_etpc_ctxsw_regs(g);
|
||||
|
||||
pm_ppc_ctxsw_regs = nvgpu_netlist_get_pm_ppc_ctxsw_regs(g);
|
||||
perf_sys_ctxsw_regs = nvgpu_netlist_get_perf_sys_ctxsw_regs(g);
|
||||
perf_sysrouter_ctxsw_regs =
|
||||
nvgpu_netlist_get_perf_sys_router_ctxsw_regs(g);
|
||||
perf_sys_control_ctxsw_regs =
|
||||
nvgpu_netlist_get_perf_sys_control_ctxsw_regs(g);
|
||||
perf_pma_ctxsw_regs = nvgpu_netlist_get_perf_pma_ctxsw_regs(g);
|
||||
perf_fbp_ctxsw_regs = nvgpu_netlist_get_fbp_ctxsw_regs(g);
|
||||
perf_fbprouter_ctxsw_regs =
|
||||
nvgpu_netlist_get_fbp_router_ctxsw_regs(g);
|
||||
perf_gpc_ctxsw_regs = nvgpu_netlist_get_perf_gpc_ctxsw_regs(g);
|
||||
perf_gpcrouter_ctxsw_regs =
|
||||
nvgpu_netlist_get_gpc_router_ctxsw_regs(g);
|
||||
pm_ltc_ctxsw_regs = nvgpu_netlist_get_pm_ltc_ctxsw_regs(g);
|
||||
pm_rop_ctxsw_regs = nvgpu_netlist_get_pm_rop_ctxsw_regs(g);
|
||||
pm_ucgpc_ctxsw_regs = nvgpu_netlist_get_pm_ucgpc_ctxsw_regs(g);
|
||||
pm_cau_ctxsw_regs = nvgpu_netlist_get_pm_cau_ctxsw_regs(g);
|
||||
pm_fbpa_ctxsw_regs = nvgpu_netlist_get_pm_fbpa_ctxsw_regs(g);
|
||||
perf_fbp_control_ctxsw_regs =
|
||||
nvgpu_netlist_get_perf_fbp_control_ctxsw_regs(g);
|
||||
perf_gpc_control_ctxsw_regs =
|
||||
nvgpu_netlist_get_perf_gpc_control_ctxsw_regs(g);
|
||||
perf_pma_control_ctxsw_regs =
|
||||
nvgpu_netlist_get_perf_pma_control_ctxsw_regs(g);
|
||||
|
||||
#endif /* CONFIG_NVGPU_DEBUGGER */
|
||||
|
||||
fecs_inst = nvgpu_netlist_get_fecs_inst(g);
|
||||
fecs_data = nvgpu_netlist_get_fecs_data(g);
|
||||
gpccs_inst = nvgpu_netlist_get_gpccs_inst(g);
|
||||
gpccs_data = nvgpu_netlist_get_gpccs_data(g);
|
||||
|
||||
/* query sizes and counts */
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_INST_FECS_COUNT", 0,
|
||||
&fecs_inst_count);
|
||||
nvgpu_netlist_set_fecs_inst_count(g, fecs_inst_count);
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_DATA_FECS_COUNT", 0,
|
||||
&fecs_data_count);
|
||||
nvgpu_netlist_set_fecs_data_count(g, fecs_data_count);
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_INST_GPCCS_COUNT", 0,
|
||||
&gpccs_inst_count);
|
||||
nvgpu_netlist_set_gpccs_inst_count(g, gpccs_inst_count);
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_DATA_GPCCS_COUNT", 0,
|
||||
&gpccs_data_count);
|
||||
nvgpu_netlist_set_gpccs_data_count(g, gpccs_data_count);
|
||||
g->sim->esc_readl(g, "GRCTX_ALL_CTX_TOTAL_WORDS", 0, &temp);
|
||||
nvgpu_netlist_vars_set_buffer_size(g, (temp << 2));
|
||||
g->sim->esc_readl(g, "GRCTX_SW_BUNDLE_INIT_SIZE", 0,
|
||||
&sw_bundle_init->count);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_METHOD_INIT_SIZE", 0,
|
||||
&sw_method_init->count);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD_SIZE", 0,
|
||||
&sw_ctx_load->count);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_VEID_BUNDLE_INIT_SIZE", 0,
|
||||
&sw_veid_bundle_init->count);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT_SIZE", 0,
|
||||
&sw_bundle64_init->count);
|
||||
g->sim->esc_readl(g, "GRCTX_NONCTXSW_REG_SIZE", 0,
|
||||
&sw_non_ctx_load->count);
|
||||
#ifdef CONFIG_NVGPU_DEBUGGER
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS_COUNT", 0,
|
||||
&sys_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC_COUNT", 0,
|
||||
&gpc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC_COUNT", 0,
|
||||
&tpc_ctxsw_regs->count);
|
||||
#ifdef CONFIG_NVGPU_GRAPHICS
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC_COUNT", 0,
|
||||
&zcull_gpc_ctxsw_regs->count);
|
||||
#endif
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS_COUNT", 0,
|
||||
&pm_sys_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC_COUNT", 0,
|
||||
&pm_gpc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC_COUNT", 0,
|
||||
&pm_tpc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC_COUNT", 0,
|
||||
&ppc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC_COUNT", 0,
|
||||
&etpc_ctxsw_regs->count);
|
||||
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_PPC_COUNT", 0,
|
||||
&pm_ppc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS_COUNT", 0,
|
||||
&perf_sys_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYSROUTER_COUNT", 0,
|
||||
&perf_sysrouter_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS_CONTROL_COUNT", 0,
|
||||
&perf_sys_control_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA_COUNT", 0,
|
||||
&perf_pma_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP_COUNT", 0,
|
||||
&perf_fbp_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBPROUTER_COUNT", 0,
|
||||
&perf_fbprouter_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC_COUNT", 0,
|
||||
&perf_gpc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPCROUTER_COUNT", 0,
|
||||
&perf_gpcrouter_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_LTC_COUNT", 0,
|
||||
&pm_ltc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_ROP_COUNT", 0,
|
||||
&pm_rop_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_UNICAST_GPC_COUNT", 0,
|
||||
&pm_ucgpc_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_CAU_COUNT", 0,
|
||||
&pm_cau_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_FBPA_COUNT", 0,
|
||||
&pm_fbpa_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP_CONTROL_COUNT", 0,
|
||||
&perf_fbp_control_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC_CONTROL_COUNT", 0,
|
||||
&perf_gpc_control_ctxsw_regs->count);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA_CONTROL_COUNT", 0,
|
||||
&perf_pma_control_ctxsw_regs->count);
|
||||
|
||||
#endif /* CONFIG_NVGPU_DEBUGGER */
|
||||
|
||||
if (nvgpu_netlist_alloc_u32_list(g, fecs_inst) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_u32_list(g, fecs_data) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_u32_list(g, gpccs_inst) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_u32_list(g, gpccs_data) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_av_list(g, sw_bundle_init) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_av64_list(g, sw_bundle64_init) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_av_list(g, sw_method_init) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, sw_ctx_load) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_av_list(g, sw_non_ctx_load) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_av_list(g, sw_veid_bundle_init) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
#ifdef CONFIG_NVGPU_DEBUGGER
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, sys_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, gpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, tpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
#ifdef CONFIG_NVGPU_GRAPHICS
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, zcull_gpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
#endif
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, ppc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_sys_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_gpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_tpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, etpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_ppc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_sys_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_sysrouter_ctxsw_regs)
|
||||
== NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_sys_control_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_pma_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_fbp_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_fbprouter_ctxsw_regs)
|
||||
== NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_gpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_gpcrouter_ctxsw_regs)
|
||||
== NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_ltc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_rop_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_ucgpc_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_cau_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, pm_fbpa_ctxsw_regs) == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_fbp_control_ctxsw_regs)
|
||||
== NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_gpc_control_ctxsw_regs)
|
||||
== NULL) {
|
||||
goto fail;
|
||||
}
|
||||
if (nvgpu_netlist_alloc_aiv_list(g, perf_pma_control_ctxsw_regs)
|
||||
== NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
|
||||
nvgpu_next_init_sim_netlist_ctxsw_regs(g);
|
||||
#endif
|
||||
#endif /* CONFIG_NVGPU_DEBUGGER */
|
||||
#if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
|
||||
nvgpu_next_init_sim_netlist_ctx_vars(g);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < nvgpu_netlist_get_fecs_inst_count(g); i++) {
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_INST_FECS",
|
||||
i, &fecs_inst->l[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < nvgpu_netlist_get_fecs_data_count(g); i++) {
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_DATA_FECS",
|
||||
i, &fecs_data->l[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < nvgpu_netlist_get_gpccs_inst_count(g); i++) {
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_INST_GPCCS",
|
||||
i, &gpccs_inst->l[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < nvgpu_netlist_get_gpccs_data_count(g); i++) {
|
||||
g->sim->esc_readl(g, "GRCTX_UCODE_DATA_GPCCS",
|
||||
i, &gpccs_data->l[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw_bundle_init->count; i++) {
|
||||
struct netlist_av *l = sw_bundle_init->l;
|
||||
g->sim->esc_readl(g, "GRCTX_SW_BUNDLE_INIT:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_BUNDLE_INIT:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw_method_init->count; i++) {
|
||||
struct netlist_av *l = sw_method_init->l;
|
||||
g->sim->esc_readl(g, "GRCTX_SW_METHOD_INIT:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_METHOD_INIT:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw_ctx_load->count; i++) {
|
||||
struct netlist_aiv *l = sw_ctx_load->l;
|
||||
g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_CTX_LOAD:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw_non_ctx_load->count; i++) {
|
||||
struct netlist_av *l = sw_non_ctx_load->l;
|
||||
g->sim->esc_readl(g, "GRCTX_NONCTXSW_REG:REG",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_NONCTXSW_REG:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw_veid_bundle_init->count; i++) {
|
||||
struct netlist_av *l = sw_veid_bundle_init->l;
|
||||
|
||||
g->sim->esc_readl(g, "GRCTX_SW_VEID_BUNDLE_INIT:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_VEID_BUNDLE_INIT:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw_bundle64_init->count; i++) {
|
||||
struct netlist_av64 *l = sw_bundle64_init->l;
|
||||
|
||||
g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT:VALUE_LO",
|
||||
i, &l[i].value_lo);
|
||||
g->sim->esc_readl(g, "GRCTX_SW_BUNDLE64_INIT:VALUE_HI",
|
||||
i, &l[i].value_hi);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NVGPU_DEBUGGER
|
||||
for (i = 0; i < sys_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = sys_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_SYS:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < gpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = gpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_GPC:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < tpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = tpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_TPC:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < ppc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = ppc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PPC:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NVGPU_GRAPHICS
|
||||
for (i = 0; i < zcull_gpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = zcull_gpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ZCULL_GPC:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < pm_sys_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_sys_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_SYS:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < pm_gpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_gpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_GPC:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
for (i = 0; i < pm_tpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_tpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_TPC:VALUE",
|
||||
i, &l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_ETPC");
|
||||
for (i = 0; i < etpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = etpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_ETPC:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PM_PPC");
|
||||
for (i = 0; i < pm_ppc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_ppc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_PPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_PPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_PPC:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_SYS");
|
||||
for (i = 0; i < perf_sys_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_sys_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_SYSROUTER");
|
||||
for (i = 0; i < perf_sysrouter_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_sysrouter_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYSROUTER:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYSROUTER:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYSROUTER:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_SYS_CONTROL");
|
||||
for (i = 0; i < perf_sys_control_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_sys_control_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS_CONTROL:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS_CONTROL:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_SYS_CONTROL:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_PMA");
|
||||
for (i = 0; i < perf_pma_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_pma_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_FBP");
|
||||
for (i = 0; i < perf_fbp_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_fbp_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_FBPROUTER");
|
||||
for (i = 0; i < perf_fbprouter_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_fbprouter_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBPROUTER:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBPROUTER:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBPROUTER:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_GPC");
|
||||
for (i = 0; i < perf_gpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_gpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_GPCROUTER");
|
||||
for (i = 0; i < perf_gpcrouter_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_gpcrouter_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPCROUTER:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPCROUTER:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPCROUTER:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PM_LTC");
|
||||
for (i = 0; i < pm_ltc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_ltc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_LTC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_LTC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_LTC:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PM_ROP");
|
||||
for (i = 0; i < pm_rop_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_rop_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_ROP:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_ROP:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_ROP:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PM_UNICAST_GPC");
|
||||
for (i = 0; i < pm_ucgpc_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_ucgpc_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_UNICAST_GPC:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_UNICAST_GPC:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_UNICAST_GPC:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PM_CAU");
|
||||
for (i = 0; i < pm_cau_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_cau_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_CAU:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_CAU:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_CAU:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PM_FBPA_COUNT");
|
||||
for (i = 0; i < pm_fbpa_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = pm_fbpa_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_FBPA:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_FBPA:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PM_FBPA:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_FBP_CONTROL");
|
||||
for (i = 0; i < perf_fbp_control_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_fbp_control_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP_CONTROL:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP_CONTROL:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_FBP_CONTROL:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_GPC_CONTROL");
|
||||
for (i = 0; i < perf_gpc_control_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_gpc_control_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC_CONTROL:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC_CONTROL:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_GPC_CONTROL:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "query GRCTX_REG_LIST_PERF_PMA_CONTROL");
|
||||
for (i = 0; i < perf_pma_control_ctxsw_regs->count; i++) {
|
||||
struct netlist_aiv *l = perf_pma_control_ctxsw_regs->l;
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA_CONTROL:ADDR",
|
||||
i, &l[i].addr);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA_CONTROL:INDEX",
|
||||
i, &l[i].index);
|
||||
g->sim->esc_readl(g, "GRCTX_REG_LIST_PERF_PMA_CONTROL:VALUE",
|
||||
i, &l[i].value);
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn,
|
||||
"addr:0x%#08x index:0x%08x value:0x%08x",
|
||||
l[i].addr, l[i].index, l[i].value);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NVGPU_DEBUGGER */
|
||||
|
||||
g->netlist_valid = true;
|
||||
|
||||
g->sim->esc_readl(g, "GRCTX_GEN_CTX_REGS_BASE_INDEX", 0,
|
||||
®s_base_index);
|
||||
nvgpu_netlist_vars_set_regs_base_index(g, regs_base_index);
|
||||
|
||||
nvgpu_log(g, gpu_dbg_info | gpu_dbg_fn, "finished querying grctx info from chiplib");
|
||||
return 0;
|
||||
fail:
|
||||
nvgpu_err(g, "failed querying grctx info from chiplib");
|
||||
|
||||
nvgpu_kfree(g, fecs_inst->l);
|
||||
nvgpu_kfree(g, fecs_data->l);
|
||||
nvgpu_kfree(g, gpccs_inst->l);
|
||||
nvgpu_kfree(g, gpccs_data->l);
|
||||
nvgpu_kfree(g, sw_bundle_init->l);
|
||||
nvgpu_kfree(g, sw_bundle64_init->l);
|
||||
nvgpu_kfree(g, sw_method_init->l);
|
||||
nvgpu_kfree(g, sw_ctx_load->l);
|
||||
nvgpu_kfree(g, sw_non_ctx_load->l);
|
||||
#if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
|
||||
nvgpu_next_init_sim_netlist_ctx_vars_free(g);
|
||||
#endif
|
||||
nvgpu_kfree(g, sw_veid_bundle_init->l);
|
||||
#ifdef CONFIG_NVGPU_DEBUGGER
|
||||
nvgpu_kfree(g, sys_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, gpc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, tpc_ctxsw_regs->l);
|
||||
#ifdef CONFIG_NVGPU_GRAPHICS
|
||||
nvgpu_kfree(g, zcull_gpc_ctxsw_regs->l);
|
||||
#endif
|
||||
nvgpu_kfree(g, ppc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_sys_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_gpc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_tpc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, etpc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_ppc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_sys_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_sysrouter_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_pma_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_fbp_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_fbprouter_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_gpc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_gpcrouter_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_ltc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_ucgpc_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_cau_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, pm_fbpa_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_fbp_control_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_gpc_control_ctxsw_regs->l);
|
||||
nvgpu_kfree(g, perf_pma_control_ctxsw_regs->l);
|
||||
#if defined(CONFIG_NVGPU_NON_FUSA) && defined(CONFIG_NVGPU_NEXT)
|
||||
nvgpu_next_init_sim_netlist_ctxsw_regs_free(g);
|
||||
#endif
|
||||
#endif /* CONFIG_NVGPU_DEBUGGER */
|
||||
|
||||
return err;
|
||||
}
|
||||
269
drivers/gpu/nvgpu/common/sim/sim_pci.c
Normal file
269
drivers/gpu/nvgpu/common/sim/sim_pci.c
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2020, 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 <nvgpu/log.h>
|
||||
#include <nvgpu/bitops.h>
|
||||
#include <nvgpu/nvgpu_mem.h>
|
||||
#include <nvgpu/dma.h>
|
||||
#include <nvgpu/hw_sim_pci.h>
|
||||
#include <nvgpu/sim.h>
|
||||
#include <nvgpu/io.h>
|
||||
#include <nvgpu/utils.h>
|
||||
#include <nvgpu/bug.h>
|
||||
#include <nvgpu/string.h>
|
||||
|
||||
static inline u32 pci_sim_msg_header_size(void)
|
||||
{
|
||||
return 32U;
|
||||
}
|
||||
|
||||
static inline u32 *pci_sim_msg_param(struct gk20a *g, u32 byte_offset)
|
||||
{
|
||||
/* starts after msg header/cmn */
|
||||
return sim_msg_bfr(g, byte_offset + pci_sim_msg_header_size());
|
||||
}
|
||||
|
||||
static inline void pci_sim_write_hdr(struct gk20a *g, u32 func, u32 size)
|
||||
{
|
||||
*sim_msg_hdr(g, sim_msg_header_version_r()) =
|
||||
sim_msg_header_version_major_tot_v() |
|
||||
sim_msg_header_version_minor_tot_v();
|
||||
*sim_msg_hdr(g, sim_msg_signature_r()) = sim_msg_signature_valid_v();
|
||||
*sim_msg_hdr(g, sim_msg_result_r()) = sim_msg_result_rpc_pending_v();
|
||||
*sim_msg_hdr(g, sim_msg_spare_r()) = sim_msg_spare__init_v();
|
||||
*sim_msg_hdr(g, sim_msg_function_r()) = func;
|
||||
*sim_msg_hdr(g, sim_msg_length_r()) =
|
||||
size + pci_sim_msg_header_size();
|
||||
}
|
||||
|
||||
static u32 *sim_send_ring_bfr(struct gk20a *g, u32 byte_offset)
|
||||
{
|
||||
u8 *cpu_va;
|
||||
|
||||
cpu_va = (u8 *)g->sim->send_bfr.cpu_va;
|
||||
|
||||
return (u32 *)(cpu_va + byte_offset);
|
||||
}
|
||||
|
||||
static int rpc_send_message(struct gk20a *g)
|
||||
{
|
||||
/* calculations done in units of u32s */
|
||||
u32 send_base = sim_send_put_pointer_v(g->sim->send_ring_put) * 2;
|
||||
u32 dma_offset = send_base + sim_dma_r()/sizeof(u32);
|
||||
u32 dma_hi_offset = send_base + sim_dma_hi_r()/sizeof(u32);
|
||||
|
||||
*sim_send_ring_bfr(g, dma_offset*sizeof(u32)) =
|
||||
sim_dma_target_phys_pci_coherent_f() |
|
||||
sim_dma_status_valid_f() |
|
||||
sim_dma_size_4kb_f() |
|
||||
sim_dma_addr_lo_f(nvgpu_mem_get_phys_addr(g, &g->sim->msg_bfr)
|
||||
>> sim_dma_addr_lo_b());
|
||||
|
||||
*sim_send_ring_bfr(g, dma_hi_offset*sizeof(u32)) =
|
||||
u64_hi32(nvgpu_mem_get_phys_addr(g, &g->sim->msg_bfr));
|
||||
|
||||
*sim_msg_hdr(g, sim_msg_sequence_r()) = g->sim->sequence_base++;
|
||||
|
||||
g->sim->send_ring_put = (g->sim->send_ring_put + 2 * sizeof(u32)) %
|
||||
SIM_BFR_SIZE;
|
||||
|
||||
/* Update the put pointer. This will trap into the host. */
|
||||
sim_writel(g->sim, sim_send_put_r(), g->sim->send_ring_put);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline u32 *sim_recv_ring_bfr(struct gk20a *g, u32 byte_offset)
|
||||
{
|
||||
u8 *cpu_va;
|
||||
|
||||
cpu_va = (u8 *)g->sim->recv_bfr.cpu_va;
|
||||
|
||||
return (u32 *)(cpu_va + byte_offset);
|
||||
}
|
||||
|
||||
static int rpc_recv_poll(struct gk20a *g)
|
||||
{
|
||||
u64 recv_phys_addr;
|
||||
|
||||
/* Poll the recv ring get pointer in an infinite loop */
|
||||
do {
|
||||
g->sim->recv_ring_put = sim_readl(g->sim, sim_recv_put_r());
|
||||
} while (g->sim->recv_ring_put == g->sim->recv_ring_get);
|
||||
|
||||
/* process all replies */
|
||||
while (g->sim->recv_ring_put != g->sim->recv_ring_get) {
|
||||
/* these are in u32 offsets */
|
||||
u32 dma_lo_offset =
|
||||
sim_recv_put_pointer_v(g->sim->recv_ring_get)*2 + 0;
|
||||
u32 dma_hi_offset = dma_lo_offset + 1;
|
||||
u32 recv_phys_addr_lo = sim_dma_addr_lo_v(
|
||||
*sim_recv_ring_bfr(g, dma_lo_offset*4));
|
||||
u32 recv_phys_addr_hi = sim_dma_hi_addr_v(
|
||||
*sim_recv_ring_bfr(g, dma_hi_offset*4));
|
||||
|
||||
recv_phys_addr = (u64)recv_phys_addr_hi << 32 |
|
||||
(u64)recv_phys_addr_lo << sim_dma_addr_lo_b();
|
||||
|
||||
if (recv_phys_addr !=
|
||||
nvgpu_mem_get_phys_addr(g, &g->sim->msg_bfr)) {
|
||||
nvgpu_err(g, "Error in RPC reply");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Update GET pointer */
|
||||
g->sim->recv_ring_get = (g->sim->recv_ring_get + 2*sizeof(u32))
|
||||
% SIM_BFR_SIZE;
|
||||
|
||||
sim_writel(g->sim, sim_recv_get_r(), g->sim->recv_ring_get);
|
||||
|
||||
g->sim->recv_ring_put = sim_readl(g->sim, sim_recv_put_r());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pci_issue_rpc_and_wait(struct gk20a *g)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = rpc_send_message(g);
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "failed rpc_send_message");
|
||||
return err;
|
||||
}
|
||||
|
||||
err = rpc_recv_poll(g);
|
||||
if (err != 0) {
|
||||
nvgpu_err(g, "failed rpc_recv_poll");
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Now check if RPC really succeeded */
|
||||
if (*sim_msg_hdr(g, sim_msg_result_r()) != sim_msg_result_success_v()) {
|
||||
nvgpu_err(g, "received failed status!");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void nvgpu_sim_esc_readl(struct gk20a *g,
|
||||
const char *path, u32 index, u32 *data)
|
||||
{
|
||||
int err;
|
||||
size_t pathlen = strlen(path);
|
||||
u32 data_offset;
|
||||
|
||||
pci_sim_write_hdr(g, sim_msg_function_sim_escape_read_v(),
|
||||
sim_escape_read_hdr_size());
|
||||
*pci_sim_msg_param(g, 0) = index;
|
||||
*pci_sim_msg_param(g, 4) = sizeof(u32);
|
||||
data_offset = round_up(pathlen + 1, sizeof(u32));
|
||||
*pci_sim_msg_param(g, 8) = data_offset;
|
||||
strcpy((char *)pci_sim_msg_param(g, sim_escape_read_hdr_size()), path);
|
||||
|
||||
err = pci_issue_rpc_and_wait(g);
|
||||
|
||||
if (err == 0) {
|
||||
nvgpu_memcpy((u8 *)data,
|
||||
(u8 *)pci_sim_msg_param(g,
|
||||
nvgpu_safe_add_u32(data_offset,
|
||||
sim_escape_read_hdr_size())),
|
||||
sizeof(u32));
|
||||
} else {
|
||||
*data = 0xffffffff;
|
||||
WARN(1, "pci_issue_rpc_and_wait failed err=%d", err);
|
||||
}
|
||||
}
|
||||
|
||||
static int nvgpu_sim_init_late(struct gk20a *g)
|
||||
{
|
||||
u64 phys;
|
||||
int err = -ENOMEM;
|
||||
|
||||
nvgpu_info(g, "sim init late pci");
|
||||
|
||||
if (!g->sim) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* allocate sim event/msg buffers */
|
||||
err = nvgpu_alloc_sim_buffer(g, &g->sim->send_bfr);
|
||||
err = err || nvgpu_alloc_sim_buffer(g, &g->sim->recv_bfr);
|
||||
err = err || nvgpu_alloc_sim_buffer(g, &g->sim->msg_bfr);
|
||||
|
||||
if (err != 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* mark send ring invalid */
|
||||
sim_writel(g->sim, sim_send_ring_r(), sim_send_ring_status_invalid_f());
|
||||
|
||||
/* read get pointer and make equal to put */
|
||||
g->sim->send_ring_put = sim_readl(g->sim, sim_send_get_r());
|
||||
sim_writel(g->sim, sim_send_put_r(), g->sim->send_ring_put);
|
||||
|
||||
/* write send ring address and make it valid */
|
||||
phys = nvgpu_mem_get_phys_addr(g, &g->sim->send_bfr);
|
||||
sim_writel(g->sim, sim_send_ring_hi_r(),
|
||||
sim_send_ring_hi_addr_f(u64_hi32(phys)));
|
||||
sim_writel(g->sim, sim_send_ring_r(),
|
||||
sim_send_ring_status_valid_f() |
|
||||
sim_send_ring_target_phys_pci_coherent_f() |
|
||||
sim_send_ring_size_4kb_f() |
|
||||
sim_send_ring_addr_lo_f(phys >> sim_send_ring_addr_lo_b()));
|
||||
|
||||
/* repeat for recv ring (but swap put,get as roles are opposite) */
|
||||
sim_writel(g->sim, sim_recv_ring_r(), sim_recv_ring_status_invalid_f());
|
||||
|
||||
/* read put pointer and make equal to get */
|
||||
g->sim->recv_ring_get = sim_readl(g->sim, sim_recv_put_r());
|
||||
sim_writel(g->sim, sim_recv_get_r(), g->sim->recv_ring_get);
|
||||
|
||||
/* write send ring address and make it valid */
|
||||
phys = nvgpu_mem_get_phys_addr(g, &g->sim->recv_bfr);
|
||||
sim_writel(g->sim, sim_recv_ring_hi_r(),
|
||||
sim_recv_ring_hi_addr_f(u64_hi32(phys)));
|
||||
sim_writel(g->sim, sim_recv_ring_r(),
|
||||
sim_recv_ring_status_valid_f() |
|
||||
sim_recv_ring_target_phys_pci_coherent_f() |
|
||||
sim_recv_ring_size_4kb_f() |
|
||||
sim_recv_ring_addr_lo_f(phys >> sim_recv_ring_addr_lo_b()));
|
||||
|
||||
return 0;
|
||||
fail:
|
||||
nvgpu_free_sim_support(g);
|
||||
return err;
|
||||
}
|
||||
|
||||
int nvgpu_init_sim_support_pci(struct gk20a *g)
|
||||
{
|
||||
|
||||
if(!g->sim) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
g->sim->sim_init_late = nvgpu_sim_init_late;
|
||||
g->sim->remove_support = nvgpu_remove_sim_support;
|
||||
g->sim->esc_readl = nvgpu_sim_esc_readl;
|
||||
return 0;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user