From 967a05a18a55402af45a566317935defb4800162 Mon Sep 17 00:00:00 2001 From: Sagar Kamble Date: Tue, 13 Aug 2019 10:31:01 +0530 Subject: [PATCH] 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 Reviewed-on: https://git-master.nvidia.com/r/2174187 GVS: Gerrit_Virtual_Submit Reviewed-by: Divya Singhatwaria Reviewed-by: Nicolas Benech Reviewed-by: Vaibhav Kachore Reviewed-by: mobile promotions Tested-by: mobile promotions --- userspace/units/falcon/falcon_tests/falcon.c | 85 +++++++++- userspace/units/falcon/falcon_utf.c | 159 ++++--------------- userspace/units/falcon/falcon_utf.h | 15 +- userspace/units/falcon/libfalcon_utf.export | 3 +- 4 files changed, 120 insertions(+), 142 deletions(-) diff --git a/userspace/units/falcon/falcon_tests/falcon.c b/userspace/units/falcon/falcon_tests/falcon.c index ca45f5bd0..8e68a2f94 100644 --- a/userspace/units/falcon/falcon_tests/falcon.c +++ b/userspace/units/falcon/falcon_tests/falcon.c @@ -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; } diff --git a/userspace/units/falcon/falcon_utf.c b/userspace/units/falcon/falcon_utf.c index a0ed883b0..3fcd90e1b 100644 --- a/userspace/units/falcon/falcon_utf.c +++ b/userspace/units/falcon/falcon_utf.c @@ -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, diff --git a/userspace/units/falcon/falcon_utf.h b/userspace/units/falcon/falcon_utf.h index 0b2721d58..3ca6cb73e 100644 --- a/userspace/units/falcon/falcon_utf.h +++ b/userspace/units/falcon/falcon_utf.h @@ -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 diff --git a/userspace/units/falcon/libfalcon_utf.export b/userspace/units/falcon/libfalcon_utf.export index 53554f557..50a81d377 100644 --- a/userspace/units/falcon/libfalcon_utf.export +++ b/userspace/units/falcon/libfalcon_utf.export @@ -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