sbi.c (a1ff5a7d78a036d6c2178ee5acd6ba4946243800) | sbi.c (1ff95eb2bebda50c4c5406caaf201e0fcb24cc8f) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * SBI initialilization and all extension implementation. 4 * 5 * Copyright (c) 2020 Western Digital Corporation or its affiliates. 6 */ 7 8#include <linux/bits.h> 9#include <linux/init.h> 10#include <linux/mm.h> 11#include <linux/pm.h> 12#include <linux/reboot.h> 13#include <asm/sbi.h> 14#include <asm/smp.h> 15#include <asm/tlbflush.h> 16 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * SBI initialilization and all extension implementation. 4 * 5 * Copyright (c) 2020 Western Digital Corporation or its affiliates. 6 */ 7 8#include <linux/bits.h> 9#include <linux/init.h> 10#include <linux/mm.h> 11#include <linux/pm.h> 12#include <linux/reboot.h> 13#include <asm/sbi.h> 14#include <asm/smp.h> 15#include <asm/tlbflush.h> 16 |
17#define CREATE_TRACE_POINTS 18#include <asm/trace.h> 19 | |
20/* default SBI version is 0.1 */ 21unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; 22EXPORT_SYMBOL(sbi_spec_version); 23 24static void (*__sbi_set_timer)(uint64_t stime) __ro_after_init; 25static void (*__sbi_send_ipi)(unsigned int cpu) __ro_after_init; 26static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask, 27 unsigned long start, unsigned long size, 28 unsigned long arg4, unsigned long arg5) __ro_after_init; 29 | 17/* default SBI version is 0.1 */ 18unsigned long sbi_spec_version __ro_after_init = SBI_SPEC_VERSION_DEFAULT; 19EXPORT_SYMBOL(sbi_spec_version); 20 21static void (*__sbi_set_timer)(uint64_t stime) __ro_after_init; 22static void (*__sbi_send_ipi)(unsigned int cpu) __ro_after_init; 23static int (*__sbi_rfence)(int fid, const struct cpumask *cpu_mask, 24 unsigned long start, unsigned long size, 25 unsigned long arg4, unsigned long arg5) __ro_after_init; 26 |
30struct sbiret __sbi_ecall(unsigned long arg0, unsigned long arg1, 31 unsigned long arg2, unsigned long arg3, 32 unsigned long arg4, unsigned long arg5, 33 int fid, int ext) 34{ 35 struct sbiret ret; 36 37 trace_sbi_call(ext, fid); 38 39 register uintptr_t a0 asm ("a0") = (uintptr_t)(arg0); 40 register uintptr_t a1 asm ("a1") = (uintptr_t)(arg1); 41 register uintptr_t a2 asm ("a2") = (uintptr_t)(arg2); 42 register uintptr_t a3 asm ("a3") = (uintptr_t)(arg3); 43 register uintptr_t a4 asm ("a4") = (uintptr_t)(arg4); 44 register uintptr_t a5 asm ("a5") = (uintptr_t)(arg5); 45 register uintptr_t a6 asm ("a6") = (uintptr_t)(fid); 46 register uintptr_t a7 asm ("a7") = (uintptr_t)(ext); 47 asm volatile ("ecall" 48 : "+r" (a0), "+r" (a1) 49 : "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6), "r" (a7) 50 : "memory"); 51 ret.error = a0; 52 ret.value = a1; 53 54 trace_sbi_return(ext, ret.error, ret.value); 55 56 return ret; 57} 58EXPORT_SYMBOL(__sbi_ecall); 59 60int sbi_err_map_linux_errno(int err) 61{ 62 switch (err) { 63 case SBI_SUCCESS: 64 return 0; 65 case SBI_ERR_DENIED: 66 return -EPERM; 67 case SBI_ERR_INVALID_PARAM: 68 return -EINVAL; 69 case SBI_ERR_INVALID_ADDRESS: 70 return -EFAULT; 71 case SBI_ERR_NOT_SUPPORTED: 72 case SBI_ERR_FAILURE: 73 default: 74 return -ENOTSUPP; 75 }; 76} 77EXPORT_SYMBOL(sbi_err_map_linux_errno); 78 | |
79#ifdef CONFIG_RISCV_SBI_V01 80static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mask) 81{ 82 unsigned long cpuid, hartid; 83 unsigned long hmask = 0; 84 85 /* 86 * There is no maximum hartid concept in RISC-V and NR_CPUS must not be --- 443 unchanged lines hidden (view full) --- 530 0, 0, 0, 0, 0); 531 if (!ret.error) 532 return ret.value; 533 534 return 0; 535} 536EXPORT_SYMBOL(sbi_probe_extension); 537 | 27#ifdef CONFIG_RISCV_SBI_V01 28static unsigned long __sbi_v01_cpumask_to_hartmask(const struct cpumask *cpu_mask) 29{ 30 unsigned long cpuid, hartid; 31 unsigned long hmask = 0; 32 33 /* 34 * There is no maximum hartid concept in RISC-V and NR_CPUS must not be --- 443 unchanged lines hidden (view full) --- 478 0, 0, 0, 0, 0); 479 if (!ret.error) 480 return ret.value; 481 482 return 0; 483} 484EXPORT_SYMBOL(sbi_probe_extension); 485 |
538static long __sbi_base_ecall(int fid) 539{ 540 struct sbiret ret; 541 542 ret = sbi_ecall(SBI_EXT_BASE, fid, 0, 0, 0, 0, 0, 0); 543 if (!ret.error) 544 return ret.value; 545 else 546 return sbi_err_map_linux_errno(ret.error); 547} 548 | |
549static inline long sbi_get_spec_version(void) 550{ 551 return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION); 552} 553 554static inline long sbi_get_firmware_id(void) 555{ 556 return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID); --- 137 unchanged lines hidden --- | 486static inline long sbi_get_spec_version(void) 487{ 488 return __sbi_base_ecall(SBI_EXT_BASE_GET_SPEC_VERSION); 489} 490 491static inline long sbi_get_firmware_id(void) 492{ 493 return __sbi_base_ecall(SBI_EXT_BASE_GET_IMP_ID); --- 137 unchanged lines hidden --- |