diff --git a/drivers/misc/mods/mods_acpi.c b/drivers/misc/mods/mods_acpi.c index e19f84fc..98e2a380 100644 --- a/drivers/misc/mods/mods_acpi.c +++ b/drivers/misc/mods/mods_acpi.c @@ -409,17 +409,23 @@ static int mods_eval_acpi_method(struct mods_client *client, &output); if (ACPI_FAILURE(status)) { - cl_info("ACPI method %s failed\n", p->method_name); + if (status == AE_NOT_FOUND) { + cl_debug(DEBUG_ACPI, "ACPI method %s not found\n", p->method_name); + err = -ENXIO; + } else { + cl_error("ACPI method %s failed\n", p->method_name); + err = -EIO; + } pci_dev_put(dev); LOG_EXT(); - return -EINVAL; + return err; } acpi_method = output.pointer; if (!acpi_method) { cl_error("missing output from ACPI method %s\n", p->method_name); - err = -EINVAL; + err = -EIO; } else { u8 *buf = p->out_buffer; diff --git a/drivers/misc/mods/mods_mem.c b/drivers/misc/mods/mods_mem.c index 6eb17400..5f9d64a3 100644 --- a/drivers/misc/mods/mods_mem.c +++ b/drivers/misc/mods/mods_mem.c @@ -338,7 +338,7 @@ static int create_dma_map(struct mods_client *client, int err; alloc_size = sizeof(struct MODS_DMA_MAP) + - (num_chunks - 1) * sizeof(struct scatterlist); + num_chunks * sizeof(struct scatterlist); p_dma_map = kzalloc(alloc_size, GFP_KERNEL | __GFP_NORETRY); @@ -1224,7 +1224,7 @@ static u32 estimate_num_chunks(u32 num_pages) static inline size_t calc_mem_info_size_no_bitmap(u32 num_chunks) { return sizeof(struct MODS_MEM_INFO) + - (num_chunks - 1) * sizeof(struct scatterlist); + num_chunks * sizeof(struct scatterlist); } static inline u32 calc_mem_info_size(u32 num_chunks, u8 cache_type) @@ -2761,11 +2761,11 @@ int esc_mods_flush_cpu_cache_range(struct mods_client *client, ***************************/ void mods_free_mem_reservations(void) { + struct mods_client * const client = mods_client_from_id(1); int i; - struct mods_client client; /* Dummy client used to ensure ensuing functions do not crash */ - memset(&client, 0, sizeof(client)); + memset(client, 0, sizeof(*client)); /* Clear reserved on claimed reservations and free unclaimed ones */ for (i = 0; i < MODS_MEM_MAX_RESERVATIONS; i++) { @@ -2773,7 +2773,7 @@ void mods_free_mem_reservations(void) /* Existing reservation */ if (p_reservation->p_mem_info) { - release_chunks(&client, p_reservation->p_mem_info); + release_chunks(client, p_reservation->p_mem_info); pci_dev_put(p_reservation->p_mem_info->dev); kfree(p_reservation->p_mem_info); memset(p_reservation, 0, sizeof(*p_reservation)); diff --git a/drivers/misc/mods/mods_oist.c b/drivers/misc/mods/mods_oist.c index 211fc281..669f00e8 100644 --- a/drivers/misc/mods/mods_oist.c +++ b/drivers/misc/mods/mods_oist.c @@ -1,25 +1,89 @@ // SPDX-License-Identifier: GPL-2.0-only -/* SPDX-FileCopyrightText: Copyright (c) 2022-2023, NVIDIA CORPORATION. All rights reserved. */ +/* SPDX-FileCopyrightText: Copyright (c) 2022-2024, NVIDIA CORPORATION. All rights reserved. */ #include "mods_internal.h" #include -#define SMCCC_VERSION 0x80000000 +#define SMCCC_VERSION 0x80000000 +#define TEGRA_SIP_RIST_SETUP 0xC200FF08 +#define TEGRA_SIP_RIST_STATUS 0xC200FF04 +#define TEGRA_SIP_RIST_STATUS_v2 0xC200FF09 +/* + * MODS_ESC_OIST_STATUS is used to make SMC calls to the ATF driver for + * OIST/RIST. + * + * The 'smc_func_id' is used to controal the SMC function ID. Potential SMC IDs + * include SMCCC_VERSION, TEGRA_SIP_RIST_STATUS, TEGRA_SIP_RIST_STATUS_v2, + * and TEGRA_SIP_RIST_SETUP. + * + * The 'aX' fields are used to populate the input parameters to the various SMC + * calls. The remaining fields ('smc_status', 'smc_retval', ist_status', + * 'rist_setup_done') are used to relay return information back to the caller + * + * Input parameters -- + * SMCCC_VERSION: + * a1 - unused, but a default value of 0 is passed + * TEGRA_SIP_RIST_STATUS: + * a1 - logical core ID to retrieve status for + * a2 - unused but expected to pass value of 1 + * TEGRA_SIP_RIST_STATUS_v2: + * a1 - physical core ID to retrieve status for + * TEGRA_SIP_RIST_SETUP: + * a1 - test vector data physical address + * a2 - test vector data size + * a3 - event timer buffer physical address + * a4 - 'pll_sel' (bit 0) feature enable/disable + */ int esc_mods_oist_status(struct mods_client *client, - struct MODS_TEGRA_OIST_STATUS *p) + struct MODS_TEGRA_OIST_STATUS *p) { int ret = 0; struct arm_smccc_res res = { 0 }; - if (p->smc_func_id == SMCCC_VERSION) { + LOG_ENT(); + switch (p->smc_func_id) { + case SMCCC_VERSION: // For SMC version, We are only reading res.a0 value, not a1,a2,a3 arm_smccc_1_1_smc(p->smc_func_id, res.a0, &res); p->smc_status = res.a0; - } else { + break; + + case TEGRA_SIP_RIST_STATUS: + // a1 - logical core ID + // a2 - unused on some implementations, but passed to be compatible arm_smccc_1_1_smc(p->smc_func_id, p->a1, p->a2, &res); + p->smc_retval = res.a0; p->smc_status = res.a1; + p->ist_status = res.a2; + break; + + case TEGRA_SIP_RIST_STATUS_v2: + // a1 - physical core ID + // a2 - unused on some implementations, but passed to be compatible + arm_smccc_1_1_smc(p->smc_func_id, p->a1, p->a2, &res); + p->smc_retval = res.a0; + p->smc_status = res.a1; + p->ist_status = res.a2; + break; + + case TEGRA_SIP_RIST_SETUP: + // a1 - tvt_addr + // a2 - tvt_size + // a3 - evt_buff + // a4 - pll_sel (bit 0) + arm_smccc_1_1_smc(p->smc_func_id, p->a1, p->a2, p->a3, p->a4, &res); + p->smc_retval = res.a0; + p->rist_setup_done = res.a1; + break; + + default: + cl_error("invalid smc_func_id 0x%llx\n", + (unsigned long long)p->smc_func_id); + LOG_EXT(); + ret = -EINVAL; } + LOG_EXT(); return ret; } diff --git a/include/uapi/misc/mods.h b/include/uapi/misc/mods.h index 0304a3cb..77669fd1 100644 --- a/include/uapi/misc/mods.h +++ b/include/uapi/misc/mods.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ -/* SPDX-FileCopyrightText: Copyright (c) 2008-2023, NVIDIA CORPORATION. All rights reserved. */ +/* SPDX-FileCopyrightText: Copyright (c) 2008-2024, NVIDIA CORPORATION. All rights reserved. */ #ifndef _UAPI_MODS_H_ #define _UAPI_MODS_H_ @@ -8,7 +8,7 @@ /* Driver version */ #define MODS_DRIVER_VERSION_MAJOR 4 -#define MODS_DRIVER_VERSION_MINOR 23 +#define MODS_DRIVER_VERSION_MINOR 24 #define MODS_DRIVER_VERSION ((MODS_DRIVER_VERSION_MAJOR << 8) | \ ((MODS_DRIVER_VERSION_MINOR / 10) << 4) | \ (MODS_DRIVER_VERSION_MINOR % 10)) @@ -1837,8 +1837,18 @@ struct MODS_TEGRA_OIST_STATUS { __u64 a1; /* IN */ __u64 a2; + /* IN */ + __u64 a3; + /* IN */ + __u64 a4; /* OUT */ __u64 smc_status; + /* OUT */ + __u64 smc_retval; + /* OUT */ + __u64 ist_status; + /* OUT */ + __u64 rist_setup_done; }; enum MODS_IPI_TYPE {