gpu: nvgpu: remove globals from falcon utf shared library

utf_falcons in libfalcon_utf.so are used by multiple unit tests and
since unit tests are run out of order it might lead to inconsistent
access to these structs.
Move these to falcon unit test. Updated the logic in the falcon utf
shared library to only export the interfaces to read/write to flcn
registers/memory.

JIRA NVGPU-2159

Change-Id: I3a1f80cce205747de4085802199ecc355bb95d6f
Signed-off-by: Sagar Kamble <skamble@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/2174187
GVS: Gerrit_Virtual_Submit
Reviewed-by: Divya Singhatwaria <dsinghatwari@nvidia.com>
Reviewed-by: Nicolas Benech <nbenech@nvidia.com>
Reviewed-by: Vaibhav Kachore <vkachore@nvidia.com>
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
This commit is contained in:
Sagar Kamble
2019-08-13 10:31:01 +05:30
committed by mobile promotions
parent 58f174b29e
commit 967a05a18a
4 changed files with 120 additions and 142 deletions

View File

@@ -33,6 +33,8 @@
#include "../falcon_utf.h"
struct utf_falcon *utf_falcons[FALCON_ID_END];
static struct nvgpu_falcon *pmu_flcn;
static struct nvgpu_falcon *gpccs_flcn;
static struct nvgpu_falcon *uninit_flcn;
@@ -45,6 +47,71 @@ static u32 *rand_test_data;
#define RAND_DATA_SIZE (SZ_4K)
static struct utf_falcon *get_utf_falcon_from_addr(struct gk20a *g, u32 addr)
{
struct utf_falcon *flcn = NULL;
u32 flcn_base;
u32 i;
for (i = 0; i < FALCON_ID_END; i++) {
if (utf_falcons[i] == NULL || utf_falcons[i]->flcn == NULL) {
continue;
}
flcn_base = utf_falcons[i]->flcn->flcn_base;
if ((addr >= flcn_base) &&
(addr < (flcn_base + UTF_FALCON_MAX_REG_OFFSET))) {
flcn = utf_falcons[i];
break;
}
}
return flcn;
}
static void writel_access_reg_fn(struct gk20a *g,
struct nvgpu_reg_access *access)
{
struct utf_falcon *flcn = NULL;
flcn = get_utf_falcon_from_addr(g, access->addr);
if (flcn != NULL) {
nvgpu_utf_falcon_writel_access_reg_fn(g, flcn, access);
} else {
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
}
nvgpu_posix_io_record_access(g, access);
}
static void readl_access_reg_fn(struct gk20a *g,
struct nvgpu_reg_access *access)
{
struct utf_falcon *flcn = NULL;
flcn = get_utf_falcon_from_addr(g, access->addr);
if (flcn != NULL) {
nvgpu_utf_falcon_readl_access_reg_fn(g, flcn, access);
} else {
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
}
}
static struct nvgpu_posix_io_callbacks utf_falcon_reg_callbacks = {
.writel = writel_access_reg_fn,
.writel_check = writel_access_reg_fn,
.bar1_writel = writel_access_reg_fn,
.usermode_writel = writel_access_reg_fn,
.__readl = readl_access_reg_fn,
.readl = readl_access_reg_fn,
.bar1_readl = readl_access_reg_fn,
};
static void utf_falcon_register_io(struct gk20a *g)
{
nvgpu_posix_register_io(g, &utf_falcon_reg_callbacks);
}
static void init_rand_buffer(void)
{
u32 i;
@@ -64,7 +131,7 @@ static int init_falcon_test_env(struct unit_module *m, struct gk20a *g)
int err = 0;
nvgpu_posix_io_init_reg_space(g);
nvgpu_utf_falcon_register_io(g);
utf_falcon_register_io(g);
/*
* Fuse register fuse_opt_priv_sec_en_r() is read during init_hal hence
@@ -87,14 +154,15 @@ static int init_falcon_test_env(struct unit_module *m, struct gk20a *g)
}
/* Initialize utf & nvgpu falcon for test usage */
err = nvgpu_utf_falcon_init(m, g, FALCON_ID_PMU);
if (err) {
return err;
utf_falcons[FALCON_ID_PMU] = nvgpu_utf_falcon_init(m, g, FALCON_ID_PMU);
if (utf_falcons[FALCON_ID_PMU] == NULL) {
return -ENODEV;
}
err = nvgpu_utf_falcon_init(m, g, FALCON_ID_GPCCS);
if (err) {
return err;
utf_falcons[FALCON_ID_GPCCS] =
nvgpu_utf_falcon_init(m, g, FALCON_ID_GPCCS);
if (utf_falcons[FALCON_ID_GPCCS] == NULL) {
return -ENODEV;
}
/* Set falcons for test usage */
@@ -120,7 +188,8 @@ static int free_falcon_test_env(struct unit_module *m, struct gk20a *g,
}
nvgpu_kfree(g, rand_test_data);
nvgpu_utf_falcon_free(g, FALCON_ID_PMU);
nvgpu_utf_falcon_free(g, utf_falcons[FALCON_ID_GPCCS]);
nvgpu_utf_falcon_free(g, utf_falcons[FALCON_ID_PMU]);
return UNIT_SUCCESS;
}

View File

@@ -29,56 +29,9 @@
#include "falcon_utf.h"
struct utf_falcon utf_falcons[FALCON_ID_END];
static struct utf_falcon *get_utf_falcon_from_id(struct gk20a *g, u32 falcon_id)
{
struct utf_falcon *flcn = NULL;
switch (falcon_id) {
case FALCON_ID_PMU:
case FALCON_ID_FECS:
case FALCON_ID_GPCCS:
#ifdef CONFIG_NVGPU_DGPU
case FALCON_ID_GSPLITE:
case FALCON_ID_NVDEC:
case FALCON_ID_SEC2:
case FALCON_ID_MINION:
#endif
flcn = &utf_falcons[falcon_id];
break;
default:
break;
}
return flcn;
}
static struct utf_falcon *get_utf_falcon_from_addr(struct gk20a *g, u32 addr)
{
struct utf_falcon *flcn = NULL;
u32 flcn_base;
u32 i;
for (i = 0; i < FALCON_ID_END; i++) {
if (utf_falcons[i].flcn == NULL) {
continue;
}
flcn_base = utf_falcons[i].flcn->flcn_base;
if ((addr >= flcn_base) &&
(addr < (flcn_base + UTF_FALCON_MAX_REG_OFFSET))) {
flcn = get_utf_falcon_from_id(g, i);
break;
}
}
return flcn;
}
static void falcon_writel_access_reg_fn(struct gk20a *g,
struct utf_falcon *flcn,
struct nvgpu_reg_access *access)
void nvgpu_utf_falcon_writel_access_reg_fn(struct gk20a *g,
struct utf_falcon *flcn,
struct nvgpu_reg_access *access)
{
u32 addr_mask = falcon_falcon_dmemc_offs_m() |
falcon_falcon_dmemc_blk_m();
@@ -123,9 +76,9 @@ static void falcon_writel_access_reg_fn(struct gk20a *g,
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
}
static void falcon_readl_access_reg_fn(struct gk20a *g,
struct utf_falcon *flcn,
struct nvgpu_reg_access *access)
void nvgpu_utf_falcon_readl_access_reg_fn(struct gk20a *g,
struct utf_falcon *flcn,
struct nvgpu_reg_access *access)
{
u32 addr_mask = falcon_falcon_dmemc_offs_m() |
falcon_falcon_dmemc_blk_m();
@@ -176,72 +129,27 @@ static void falcon_readl_access_reg_fn(struct gk20a *g,
}
}
static void writel_access_reg_fn(struct gk20a *g,
struct nvgpu_reg_access *access)
{
struct utf_falcon *flcn = NULL;
flcn = get_utf_falcon_from_addr(g, access->addr);
if (flcn != NULL) {
falcon_writel_access_reg_fn(g, flcn, access);
} else {
nvgpu_posix_io_writel_reg_space(g, access->addr, access->value);
}
nvgpu_posix_io_record_access(g, access);
}
static void readl_access_reg_fn(struct gk20a *g,
struct nvgpu_reg_access *access)
{
struct utf_falcon *flcn = NULL;
flcn = get_utf_falcon_from_addr(g, access->addr);
if (flcn != NULL) {
falcon_readl_access_reg_fn(g, flcn, access);
} else {
access->value = nvgpu_posix_io_readl_reg_space(g, access->addr);
}
}
static struct nvgpu_posix_io_callbacks utf_falcon_reg_callbacks = {
.writel = writel_access_reg_fn,
.writel_check = writel_access_reg_fn,
.bar1_writel = writel_access_reg_fn,
.usermode_writel = writel_access_reg_fn,
.__readl = readl_access_reg_fn,
.readl = readl_access_reg_fn,
.bar1_readl = readl_access_reg_fn,
};
void nvgpu_utf_falcon_register_io(struct gk20a *g)
{
nvgpu_posix_register_io(g, &utf_falcon_reg_callbacks);
}
int nvgpu_utf_falcon_init(struct unit_module *m, struct gk20a *g, u32 flcn_id)
struct utf_falcon *nvgpu_utf_falcon_init(struct unit_module *m,
struct gk20a *g, u32 flcn_id)
{
struct utf_falcon *utf_flcn;
struct nvgpu_falcon *flcn;
u32 flcn_size;
u32 flcn_base;
u32 hwcfg_r, hwcfg1_r, ports;
int err = 0;
if (utf_falcons[flcn_id].flcn != NULL) {
unit_err(m, "Falcon already initialized!\n");
return -EINVAL;
}
err = nvgpu_falcon_sw_init(g, flcn_id);
if (err != 0) {
if (nvgpu_falcon_sw_init(g, flcn_id) != 0) {
unit_err(m, "nvgpu Falcon init failed!\n");
return err;
return NULL;
}
flcn = nvgpu_falcon_get_instance(g, flcn_id);
utf_flcn = &utf_falcons[flcn_id];
utf_flcn = (struct utf_falcon *) malloc(sizeof(struct utf_falcon));
if (!utf_flcn) {
return NULL;
}
utf_flcn->flcn = flcn;
flcn_base = flcn->flcn_base;
@@ -249,8 +157,7 @@ int nvgpu_utf_falcon_init(struct unit_module *m, struct gk20a *g, u32 flcn_id)
flcn_base,
UTF_FALCON_MAX_REG_OFFSET) != 0) {
unit_err(m, "Falcon add reg space failed!\n");
nvgpu_falcon_sw_free(g, flcn_id);
return -ENOMEM;
goto out;
}
/*
@@ -269,52 +176,46 @@ int nvgpu_utf_falcon_init(struct unit_module *m, struct gk20a *g, u32 flcn_id)
utf_flcn->imem = (u32 *) nvgpu_kzalloc(g, UTF_FALCON_IMEM_DMEM_SIZE);
if (utf_flcn->imem == NULL) {
err = -ENOMEM;
unit_err(m, "Falcon imem alloc failed!\n");
goto out;
goto out_reg_space;
}
utf_flcn->dmem = (u32 *) nvgpu_kzalloc(g, UTF_FALCON_IMEM_DMEM_SIZE);
if (utf_flcn->dmem == NULL) {
err = -ENOMEM;
unit_err(m, "Falcon dmem alloc failed!\n");
goto clean_imem;
goto free_imem;
}
return 0;
return utf_flcn;
clean_imem:
free_imem:
nvgpu_kfree(g, utf_flcn->imem);
out:
out_reg_space:
nvgpu_posix_io_delete_reg_space(g, flcn_base);
out:
nvgpu_falcon_sw_free(g, flcn_id);
free(utf_flcn);
return err;
return NULL;
}
void nvgpu_utf_falcon_free(struct gk20a *g, u32 flcn_id)
void nvgpu_utf_falcon_free(struct gk20a *g, struct utf_falcon *utf_flcn)
{
struct utf_falcon *utf_flcn;
utf_flcn = &utf_falcons[flcn_id];
if (utf_flcn->flcn == NULL)
if (utf_flcn == NULL || utf_flcn->flcn == NULL)
return;
nvgpu_kfree(g, utf_flcn->dmem);
nvgpu_kfree(g, utf_flcn->imem);
nvgpu_posix_io_delete_reg_space(g, utf_flcn->flcn->flcn_base);
nvgpu_falcon_sw_free(g, flcn_id);
utf_flcn->flcn = NULL;
nvgpu_falcon_sw_free(g, utf_flcn->flcn->flcn_id);
free(utf_flcn);
}
void nvgpu_utf_falcon_set_dmactl(struct gk20a *g, u32 flcn_id, u32 reg_data)
void nvgpu_utf_falcon_set_dmactl(struct gk20a *g, struct utf_falcon *utf_flcn,
u32 reg_data)
{
struct utf_falcon *utf_flcn;
u32 flcn_base;
utf_flcn = &utf_falcons[flcn_id];
flcn_base = utf_flcn->flcn->flcn_base;
nvgpu_posix_io_writel_reg_space(g,

View File

@@ -38,9 +38,16 @@ struct utf_falcon {
u32 *dmem;
};
void nvgpu_utf_falcon_register_io(struct gk20a *g);
int nvgpu_utf_falcon_init(struct unit_module *m, struct gk20a *g, u32 flcn_id);
void nvgpu_utf_falcon_set_dmactl(struct gk20a *g, u32 flcn_id, u32 reg_data);
void nvgpu_utf_falcon_free(struct gk20a *g, u32 flcn_id);
void nvgpu_utf_falcon_writel_access_reg_fn(struct gk20a *g,
struct utf_falcon *flcn,
struct nvgpu_reg_access *access);
void nvgpu_utf_falcon_readl_access_reg_fn(struct gk20a *g,
struct utf_falcon *flcn,
struct nvgpu_reg_access *access);
struct utf_falcon *nvgpu_utf_falcon_init(struct unit_module *m,
struct gk20a *g, u32 flcn_id);
void nvgpu_utf_falcon_free(struct gk20a *g, struct utf_falcon *utf_flcn);
void nvgpu_utf_falcon_set_dmactl(struct gk20a *g, struct utf_falcon *utf_flcn,
u32 reg_data);
#endif

View File

@@ -22,5 +22,6 @@
nvgpu_utf_falcon_free
nvgpu_utf_falcon_init
nvgpu_utf_falcon_register_io
nvgpu_utf_falcon_readl_access_reg_fn
nvgpu_utf_falcon_set_dmactl
nvgpu_utf_falcon_writel_access_reg_fn