diff options
Diffstat (limited to 'src/arch/arm64/armv8/secmon/smc.c')
-rw-r--r-- | src/arch/arm64/armv8/secmon/smc.c | 163 |
1 files changed, 0 insertions, 163 deletions
diff --git a/src/arch/arm64/armv8/secmon/smc.c b/src/arch/arm64/armv8/secmon/smc.c deleted file mode 100644 index 6fa6294933..0000000000 --- a/src/arch/arm64/armv8/secmon/smc.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright 2014 Google Inc. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#include <string.h> -#include <stdlib.h> -#include <arch/cpu.h> -#include <arch/smc.h> -#include <arch/exception.h> -#include <arch/lib_helpers.h> -#include <console/console.h> - -enum { - /* SMC called from AARCH32 */ - EC_SMC_AARCH32 = 0x13, - /* SMC called from AARCH64 */ - EC_SMC_AARCH64 = 0x17, - - SMC_NUM_RANGES = 8, -}; - -struct smc_range { - uint32_t func_begin; - uint32_t func_end; - int (*handler)(struct smc_call *); -}; - -struct smc_ranges { - size_t used; - struct smc_range handlers[SMC_NUM_RANGES]; -}; - -static struct smc_ranges smc_functions; - -static struct smc_range *smc_handler_by_function(uint32_t fid) -{ - int i; - - for (i = 0; i < smc_functions.used; i++) { - struct smc_range *r = &smc_functions.handlers[i]; - - if (fid >= r->func_begin && fid <= r->func_end) - return r; - } - - return NULL; -} - -int smc_register_range(uint32_t min, uint32_t max, int (*h)(struct smc_call *)) -{ - struct smc_range *r; - - if (smc_functions.used == SMC_NUM_RANGES) - return -1; - - if (min > max) - return -1; - - /* This check isn't exhaustive but it's fairly quick. */ - if (smc_handler_by_function(min) || smc_handler_by_function(max)) - return -1; - - r = &smc_functions.handlers[smc_functions.used]; - r->func_begin = min; - r->func_end = max; - r->handler = h; - smc_functions.used++; - - return 0; -} - -static int smc_cleanup(struct exc_state *state, struct smc_call *smc, int ret) -{ - memcpy(&state->regs.x, &smc->results, sizeof(smc->results)); - - return ret; -} - -static int smc_return_with_error(struct exc_state *state, struct smc_call *smc) -{ - smc32_return(smc, SMC_UNKNOWN_FUNC); - return smc_cleanup(state, smc, EXC_RET_HANDLED); -} - -static int smc_handler(struct exc_state *state, uint64_t vector_id) -{ - struct smc_call smc_storage; - struct smc_call *smc = &smc_storage; - uint32_t exception_class; - uint32_t esr; - struct smc_range *r; - - memcpy(&smc->args, &state->regs.x, sizeof(smc->args)); - memcpy(&smc->results, &state->regs.x, sizeof(smc->results)); - - esr = raw_read_esr_el3(); - exception_class = (esr >> 26) & 0x3f; - - /* No support for SMC calls from AARCH32 */ - if (exception_class == EC_SMC_AARCH32) - return smc_return_with_error(state, smc); - - /* Check to ensure this is an SMC from AARCH64. */ - if (exception_class != EC_SMC_AARCH64) - return EXC_RET_IGNORED; - - /* Ensure immediate value is 0. */ - if ((esr & 0xffff) != 0) - return smc_return_with_error(state, smc); - - r = smc_handler_by_function(smc_function_id(smc)); - - if (r != NULL) { - if (!r->handler(smc)) - return smc_cleanup(state, smc, EXC_RET_HANDLED); - } - - return smc_return_with_error(state, smc); -} - -/* SMC calls can be generated by 32-bit or 64-bit code. */ -static struct exception_handler smc_handler64 = { - .handler = &smc_handler, -}; - -static struct exception_handler smc_handler32 = { - .handler = &smc_handler, -}; - -static void enable_smc(void *arg) -{ - uint32_t scr; - - /* Enable SMC */ - scr = raw_read_scr_el3(); - scr &= ~(SCR_SMC_MASK); - scr |= SCR_SMC_ENABLE; - raw_write_scr_el3(scr); -} - -void smc_init(void) -{ - struct cpu_action action = { - .run = enable_smc, - }; - - arch_run_on_all_cpus_async(&action); - - /* Register SMC handlers. */ - exception_handler_register(EXC_VID_LOW64_SYNC, &smc_handler64); - exception_handler_register(EXC_VID_LOW32_SYNC, &smc_handler32); -} |