From f07857324b89f820532ca62643a3980f9a32449d Mon Sep 17 00:00:00 2001 From: BernardXiong Date: Tue, 18 May 2021 18:58:39 +0800 Subject: [PATCH] [bsp] Use sbi from freebsd --- bsp/qemu-riscv-virt64/driver/board.c | 5 +- bsp/qemu-riscv-virt64/driver/drv_uart.c | 8 +- bsp/qemu-riscv-virt64/driver/sbi.c | 265 ++++++++++++++++++++ bsp/qemu-riscv-virt64/driver/sbi.h | 308 ++++++++++++++++-------- 4 files changed, 485 insertions(+), 101 deletions(-) create mode 100644 bsp/qemu-riscv-virt64/driver/sbi.c diff --git a/bsp/qemu-riscv-virt64/driver/board.c b/bsp/qemu-riscv-virt64/driver/board.c index 3ed4aab43..ac021ed3c 100644 --- a/bsp/qemu-riscv-virt64/driver/board.c +++ b/bsp/qemu-riscv-virt64/driver/board.c @@ -38,7 +38,8 @@ void primary_cpu_entry(void) extern void entry(void); /* disable global interrupt */ - init_bss(); + rt_memset(&__bss_start, 0x0, &__bss_end - &__bss_start); + // init_bss(); rt_hw_interrupt_disable(); entry(); } @@ -76,7 +77,7 @@ void rt_hw_board_init(void) void rt_hw_cpu_reset(void) { - SBI_CALL_0(SBI_SHUTDOWN); + sbi_shutdown(); while(1); } MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine); diff --git a/bsp/qemu-riscv-virt64/driver/drv_uart.c b/bsp/qemu-riscv-virt64/driver/drv_uart.c index 8e0476321..63820175e 100644 --- a/bsp/qemu-riscv-virt64/driver/drv_uart.c +++ b/bsp/qemu-riscv-virt64/driver/drv_uart.c @@ -98,23 +98,25 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg static int drv_uart_putc(struct rt_serial_device *serial, char c) { - SBI_CALL_1(SBI_CONSOLE_PUTCHAR, c); + sbi_console_putchar(c); return (1); } static int drv_uart_getc(struct rt_serial_device *serial) { - return SBI_CALL_0(SBI_CONSOLE_GETCHAR); + return sbi_console_getchar(); } +#if 0 void drv_uart_puts(char *str) { sbi_console_putstr(str); } +#endif char rt_hw_console_getchar(void) { - return SBI_CALL_0(SBI_CONSOLE_GETCHAR); + return sbi_console_getchar(); } static void uart_rx(void *param) diff --git a/bsp/qemu-riscv-virt64/driver/sbi.c b/bsp/qemu-riscv-virt64/driver/sbi.c new file mode 100644 index 000000000..f848ec781 --- /dev/null +++ b/bsp/qemu-riscv-virt64/driver/sbi.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-18 Bernard port from FreeBSD + */ + +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2019 Mitchell Horne + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "sbi.h" +#include +#include + +/* SBI Implementation-Specific Definitions */ +#define OPENSBI_VERSION_MAJOR_OFFSET 16 +#define OPENSBI_VERSION_MINOR_MASK 0xFFFF + +unsigned long sbi_spec_version; +unsigned long sbi_impl_id; +unsigned long sbi_impl_version; + +static bool has_time_extension = false; +static bool has_ipi_extension = false; +static bool has_rfnc_extension = false; + +static struct sbi_ret +sbi_get_spec_version(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_SPEC_VERSION)); +} + +static struct sbi_ret +sbi_get_impl_id(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_ID)); +} + +static struct sbi_ret +sbi_get_impl_version(void) +{ + return (SBI_CALL0(SBI_EXT_ID_BASE, SBI_BASE_GET_IMPL_VERSION)); +} + +void +sbi_print_version(void) +{ + u_int major; + u_int minor; + + /* For legacy SBI implementations. */ + if (sbi_spec_version == 0) + { + rt_kprintf("SBI: Unknown (Legacy) Implementation\n"); + rt_kprintf("SBI Specification Version: 0.1\n"); + return; + } + + switch (sbi_impl_id) + { + case (SBI_IMPL_ID_BBL): + rt_kprintf("SBI: Berkely Boot Loader %lu\n", sbi_impl_version); + break; + case (SBI_IMPL_ID_XVISOR): + rt_kprintf("SBI: eXtensible Versatile hypervISOR %lu\n", sbi_impl_version); + break; + case (SBI_IMPL_ID_KVM): + rt_kprintf("SBI: Kernel-based Virtual Machine %lu\n", sbi_impl_version); + break; + case (SBI_IMPL_ID_RUSTSBI): + rt_kprintf("SBI: RustSBI %lu\n", sbi_impl_version); + break; + case (SBI_IMPL_ID_DIOSIX): + rt_kprintf("SBI: Diosix %lu\n", sbi_impl_version); + break; + case (SBI_IMPL_ID_OPENSBI): + major = sbi_impl_version >> OPENSBI_VERSION_MAJOR_OFFSET; + minor = sbi_impl_version & OPENSBI_VERSION_MINOR_MASK; + rt_kprintf("SBI: OpenSBI v%u.%u\n", major, minor); + break; + default: + rt_kprintf("SBI: Unrecognized Implementation: %lu\n", sbi_impl_id); + break; + } + + major = (sbi_spec_version & SBI_SPEC_VERS_MAJOR_MASK) >> + SBI_SPEC_VERS_MAJOR_OFFSET; + minor = (sbi_spec_version & SBI_SPEC_VERS_MINOR_MASK); + rt_kprintf("SBI Specification Version: %u.%u\n", major, minor); +} + +void +sbi_set_timer(uint64_t val) +{ + struct sbi_ret ret; + + /* Use the TIME legacy replacement extension, if available. */ + if (has_time_extension) + { + ret = SBI_CALL1(SBI_EXT_ID_TIME, SBI_TIME_SET_TIMER, val); + RT_ASSERT(ret.error == SBI_SUCCESS); + } + else + { + (void)SBI_CALL1(SBI_SET_TIMER, 0, val); + } +} + +void +sbi_send_ipi(const unsigned long *hart_mask) +{ + struct sbi_ret ret; + + /* Use the IPI legacy replacement extension, if available. */ + if (has_ipi_extension) + { + ret = SBI_CALL2(SBI_EXT_ID_IPI, SBI_IPI_SEND_IPI, + *hart_mask, 0); + RT_ASSERT(ret.error == SBI_SUCCESS); + } + else + { + (void)SBI_CALL1(SBI_SEND_IPI, 0, (uint64_t)hart_mask); + } +} + +void +sbi_remote_fence_i(const unsigned long *hart_mask) +{ + struct sbi_ret ret; + + /* Use the RFENCE legacy replacement extension, if available. */ + if (has_rfnc_extension) + { + ret = SBI_CALL2(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_FENCE_I, + *hart_mask, 0); + RT_ASSERT(ret.error == SBI_SUCCESS); + } + else + { + (void)SBI_CALL1(SBI_REMOTE_FENCE_I, 0, (uint64_t)hart_mask); + } +} + +void +sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size) +{ + struct sbi_ret ret; + + /* Use the RFENCE legacy replacement extension, if available. */ + if (has_rfnc_extension) + { + ret = SBI_CALL4(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA, + *hart_mask, 0, start, size); + RT_ASSERT(ret.error == SBI_SUCCESS); + } + else + { + (void)SBI_CALL3(SBI_REMOTE_SFENCE_VMA, 0, (uint64_t)hart_mask, + start, size); + } +} + +void +sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, unsigned long size, + unsigned long asid) +{ + struct sbi_ret ret; + + /* Use the RFENCE legacy replacement extension, if available. */ + if (has_rfnc_extension) + { + ret = SBI_CALL5(SBI_EXT_ID_RFNC, SBI_RFNC_REMOTE_SFENCE_VMA_ASID, + *hart_mask, 0, start, size, asid); + RT_ASSERT(ret.error == SBI_SUCCESS); + } + else + { + (void)SBI_CALL4(SBI_REMOTE_SFENCE_VMA_ASID, 0, + (uint64_t)hart_mask, start, size, asid); + } +} + +int +sbi_hsm_hart_start(unsigned long hart, unsigned long start_addr, unsigned long priv) +{ + struct sbi_ret ret; + + ret = SBI_CALL3(SBI_EXT_ID_HSM, SBI_HSM_HART_START, hart, start_addr, priv); + return (ret.error != 0 ? (int)ret.error : 0); +} + +void +sbi_hsm_hart_stop(void) +{ + (void)SBI_CALL0(SBI_EXT_ID_HSM, SBI_HSM_HART_STOP); +} + +int +sbi_hsm_hart_status(unsigned long hart) +{ + struct sbi_ret ret; + + ret = SBI_CALL1(SBI_EXT_ID_HSM, SBI_HSM_HART_STATUS, hart); + + return (ret.error != 0 ? (int)ret.error : (int)ret.value); +} + +void +sbi_init(void) +{ + struct sbi_ret sret; + + /* + * Get the spec version. For legacy SBI implementations this will + * return an error, otherwise it is guaranteed to succeed. + */ + sret = sbi_get_spec_version(); + if (sret.error != 0) + { + /* We are running a legacy SBI implementation. */ + sbi_spec_version = 0; + return; + } + + /* Set the SBI implementation info. */ + sbi_spec_version = sret.value; + sbi_impl_id = sbi_get_impl_id().value; + sbi_impl_version = sbi_get_impl_version().value; + + /* Probe for legacy replacement extensions. */ + if (sbi_probe_extension(SBI_EXT_ID_TIME) != 0) + has_time_extension = true; + if (sbi_probe_extension(SBI_EXT_ID_IPI) != 0) + has_ipi_extension = true; + if (sbi_probe_extension(SBI_EXT_ID_RFNC) != 0) + has_rfnc_extension = true; +} diff --git a/bsp/qemu-riscv-virt64/driver/sbi.h b/bsp/qemu-riscv-virt64/driver/sbi.h index 18d2bb7ee..b42d558f5 100644 --- a/bsp/qemu-riscv-virt64/driver/sbi.h +++ b/bsp/qemu-riscv-virt64/driver/sbi.h @@ -1,126 +1,242 @@ /* - * Copyright (C) 2015 Regents of the University of California + * Copyright (c) 2006-2021, RT-Thread Development Team * - * 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. + * SPDX-License-Identifier: Apache-2.0 * - * 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. + * Change Logs: + * Date Author Notes + * 2021-05-18 Bernard port from FreeBSD */ -#ifndef _ASM_RISCV_SBI_H -#define _ASM_RISCV_SBI_H - -#include -#include - -#define SBI_CALL(which, arg0, arg1, arg2) \ - ({ \ - register uintptr_t a0 asm("a0") = (uintptr_t)(arg0); \ - register uintptr_t a1 asm("a1") = (uintptr_t)(arg1); \ - register uintptr_t a2 asm("a2") = (uintptr_t)(arg2); \ - register uintptr_t a7 asm("a7") = (uintptr_t)(which); \ - asm volatile("ecall" \ - : "+r"(a0) \ - : "r"(a1), "r"(a2), "r"(a7) \ - : "memory"); \ - a0; \ - }) - -/* Lazy implementations until SBI is finalized */ -#define SBI_CALL_0(which) SBI_CALL(which, 0, 0, 0) -#define SBI_CALL_1(which, arg0) SBI_CALL(which, arg0, 0, 0) -#define SBI_CALL_2(which, arg0, arg1) \ - SBI_CALL(which, arg0, arg1, 0) -#define SBI_CALL_3(which, arg0, arg1, arg2) \ - SBI_CALL(which, arg0, arg1, arg2) - -static inline void sbi_console_putstr(char *str) -{ - // FIXME: machine mode cannot access `str` - // if `str` is a virtual address. So we use - // SBI_CONSOLE_PUTCHAR to implement this function. - while (*str != '\0') { - SBI_CALL_1(SBI_CONSOLE_PUTCHAR, *str++); - } -} +/*- + * Copyright (c) 2016-2017 Ruslan Bukin + * All rights reserved. + * Copyright (c) 2019 Mitchell Horne + * + * Portions of this software were developed by SRI International and the + * University of Cambridge Computer Laboratory under DARPA/AFRL contract + * FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme. + * + * Portions of this software were developed by the University of Cambridge + * Computer Laboratory as part of the CTSRD Project, with support from the + * UK Higher Education Innovation Fund (HEIF). + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ -static inline uintptr_t sbi_sd_write( - unsigned int mem_address, unsigned int num_of_blocks, - unsigned int block_id) -{ - return SBI_CALL_3( - SBI_SD_WRITE, mem_address, num_of_blocks, block_id); -} +#ifndef _MACHINE_SBI_H_ +#define _MACHINE_SBI_H_ + +#include + +/* SBI Specification Version */ +#define SBI_SPEC_VERS_MAJOR_OFFSET 24 +#define SBI_SPEC_VERS_MAJOR_MASK (0x7F << SBI_SPEC_VERS_MAJOR_OFFSET) +#define SBI_SPEC_VERS_MINOR_OFFSET 0 +#define SBI_SPEC_VERS_MINOR_MASK (0xFFFFFF << SBI_SPEC_VERS_MINOR_OFFSET) + +/* SBI Implementation IDs */ +#define SBI_IMPL_ID_BBL 0 +#define SBI_IMPL_ID_OPENSBI 1 +#define SBI_IMPL_ID_XVISOR 2 +#define SBI_IMPL_ID_KVM 3 +#define SBI_IMPL_ID_RUSTSBI 4 +#define SBI_IMPL_ID_DIOSIX 5 + +/* SBI Error Codes */ +#define SBI_SUCCESS 0 +#define SBI_ERR_FAILURE -1 +#define SBI_ERR_NOT_SUPPORTED -2 +#define SBI_ERR_INVALID_PARAM -3 +#define SBI_ERR_DENIED -4 +#define SBI_ERR_INVALID_ADDRESS -5 +#define SBI_ERR_ALREADY_AVAILABLE -6 + +/* SBI Base Extension */ +#define SBI_EXT_ID_BASE 0x10 +#define SBI_BASE_GET_SPEC_VERSION 0 +#define SBI_BASE_GET_IMPL_ID 1 +#define SBI_BASE_GET_IMPL_VERSION 2 +#define SBI_BASE_PROBE_EXTENSION 3 +#define SBI_BASE_GET_MVENDORID 4 +#define SBI_BASE_GET_MARCHID 5 +#define SBI_BASE_GET_MIMPID 6 + +/* Timer (TIME) Extension */ +#define SBI_EXT_ID_TIME 0x54494D45 +#define SBI_TIME_SET_TIMER 0 + +/* IPI (IPI) Extension */ +#define SBI_EXT_ID_IPI 0x735049 +#define SBI_IPI_SEND_IPI 0 + +/* RFENCE (RFNC) Extension */ +#define SBI_EXT_ID_RFNC 0x52464E43 +#define SBI_RFNC_REMOTE_FENCE_I 0 +#define SBI_RFNC_REMOTE_SFENCE_VMA 1 +#define SBI_RFNC_REMOTE_SFENCE_VMA_ASID 2 +#define SBI_RFNC_REMOTE_HFENCE_GVMA_VMID 3 +#define SBI_RFNC_REMOTE_HFENCE_GVMA 4 +#define SBI_RFNC_REMOTE_HFENCE_VVMA_ASID 5 +#define SBI_RFNC_REMOTE_HFENCE_VVMA 6 + +/* Hart State Management (HSM) Extension */ +#define SBI_EXT_ID_HSM 0x48534D +#define SBI_HSM_HART_START 0 +#define SBI_HSM_HART_STOP 1 +#define SBI_HSM_HART_STATUS 2 +#define SBI_HSM_STATUS_STARTED 0 +#define SBI_HSM_STATUS_STOPPED 1 +#define SBI_HSM_STATUS_START_PENDING 2 +#define SBI_HSM_STATUS_STOP_PENDING 3 + +/* Legacy Extensions */ +#define SBI_SET_TIMER 0 +#define SBI_CONSOLE_PUTCHAR 1 +#define SBI_CONSOLE_GETCHAR 2 +#define SBI_CLEAR_IPI 3 +#define SBI_SEND_IPI 4 +#define SBI_REMOTE_FENCE_I 5 +#define SBI_REMOTE_SFENCE_VMA 6 +#define SBI_REMOTE_SFENCE_VMA_ASID 7 +#define SBI_SHUTDOWN 8 + +#define SBI_CALL0(e, f) SBI_CALL5(e, f, 0, 0, 0, 0, 0) +#define SBI_CALL1(e, f, p1) SBI_CALL5(e, f, p1, 0, 0, 0, 0) +#define SBI_CALL2(e, f, p1, p2) SBI_CALL5(e, f, p1, p2, 0, 0, 0) +#define SBI_CALL3(e, f, p1, p2, p3) SBI_CALL5(e, f, p1, p2, p3, 0, 0) +#define SBI_CALL4(e, f, p1, p2, p3, p4) SBI_CALL5(e, f, p1, p2, p3, p4, 0) +#define SBI_CALL5(e, f, p1, p2, p3, p4, p5) sbi_call(e, f, p1, p2, p3, p4, p5) -static inline uintptr_t sbi_sd_read( - unsigned int mem_address, unsigned int num_of_blocks, - unsigned int block_id) -{ - return SBI_CALL_3( - SBI_SD_READ, mem_address, num_of_blocks, block_id); -} +/* + * Documentation available at + * https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.adoc + */ -static inline void sbi_console_putchar(int ch) +struct sbi_ret { - SBI_CALL_1(SBI_CONSOLE_PUTCHAR, ch); -} + long error; + long value; +}; -static inline int sbi_console_getchar(void) +static __inline struct sbi_ret +sbi_call(uint64_t arg7, uint64_t arg6, uint64_t arg0, uint64_t arg1, + uint64_t arg2, uint64_t arg3, uint64_t arg4) { - return SBI_CALL_0(SBI_CONSOLE_GETCHAR); + struct sbi_ret ret; + + register uintptr_t a0 __asm("a0") = (uintptr_t)(arg0); + register uintptr_t a1 __asm("a1") = (uintptr_t)(arg1); + register uintptr_t a2 __asm("a2") = (uintptr_t)(arg2); + register uintptr_t a3 __asm("a3") = (uintptr_t)(arg3); + register uintptr_t a4 __asm("a4") = (uintptr_t)(arg4); + register uintptr_t a6 __asm("a6") = (uintptr_t)(arg6); + register uintptr_t a7 __asm("a7") = (uintptr_t)(arg7); + + __asm __volatile(\ + "ecall" \ + : "+r"(a0), "+r"(a1) \ + : "r"(a2), "r"(a3), "r"(a4), "r"(a6), "r"(a7) \ + : "memory"); + + ret.error = a0; + ret.value = a1; + return (ret); } -static inline void sbi_set_timer(uint64_t stime_value) +/* Base extension functions and variables. */ +extern unsigned long sbi_spec_version; +extern unsigned long sbi_impl_id; +extern unsigned long sbi_impl_version; + +static __inline long +sbi_probe_extension(long id) { -#if __riscv_xlen == 32 - SBI_CALL_2(SBI_SET_TIMER, stime_value, stime_value >> 32); -#else - SBI_CALL_1(SBI_SET_TIMER, stime_value); -#endif + return (SBI_CALL1(SBI_EXT_ID_BASE, SBI_BASE_PROBE_EXTENSION, id).value); } -static inline void sbi_shutdown(void) { SBI_CALL_0(SBI_SHUTDOWN); } +/* TIME extension functions. */ +void sbi_set_timer(uint64_t val); -static inline void sbi_clear_ipi(void) -{ - SBI_CALL_0(SBI_CLEAR_IPI); -} +/* IPI extension functions. */ +void sbi_send_ipi(const unsigned long *hart_mask); -static inline void sbi_send_ipi(const unsigned long *hart_mask) -{ - SBI_CALL_1(SBI_SEND_IPI, hart_mask); -} +/* RFENCE extension functions. */ +void sbi_remote_fence_i(const unsigned long *hart_mask); +void sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size); +void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, + unsigned long size, unsigned long asid); + +/* Hart State Management extension functions. */ + +/* + * Start execution on the specified hart at physical address start_addr. The + * register a0 will contain the hart's ID, and a1 will contain the value of + * priv. + */ +int sbi_hsm_hart_start(unsigned long hart, unsigned long start_addr, unsigned long priv); -static inline void sbi_remote_fence_i( - const unsigned long *hart_mask) +/* + * Stop execution on the current hart. Interrupts should be disabled, or this + * function may return. + */ +void sbi_hsm_hart_stop(void); + +/* + * Get the execution status of the specified hart. The status will be one of: + * - SBI_HSM_STATUS_STARTED + * - SBI_HSM_STATUS_STOPPED + * - SBI_HSM_STATUS_START_PENDING + * - SBI_HSM_STATUS_STOP_PENDING + */ +int sbi_hsm_hart_status(unsigned long hart); + +/* Legacy extension functions. */ +static __inline void +sbi_console_putchar(int ch) { - SBI_CALL_1(SBI_REMOTE_FENCE_I, hart_mask); + (void)SBI_CALL1(SBI_CONSOLE_PUTCHAR, 0, ch); } -static inline void sbi_remote_sfence_vma( - const unsigned long *hart_mask, unsigned long start, - unsigned long size) +static __inline int +sbi_console_getchar(void) { - SBI_CALL_1(SBI_REMOTE_SFENCE_VMA, hart_mask); + /* + * XXX: The "error" is returned here because legacy SBI functions + * continue to return their value in a0. + */ + return (SBI_CALL0(SBI_CONSOLE_GETCHAR, 0).error); } -static inline void sbi_remote_sfence_vma_asid( - const unsigned long *hart_mask, unsigned long start, - unsigned long size, unsigned long asid) +static __inline void +sbi_shutdown(void) { - SBI_CALL_1(SBI_REMOTE_SFENCE_VMA_ASID, hart_mask); -} -static inline void sbi_net_write(char * buffer, int length) { - SBI_CALL_2(SBI_NET_WRITE, buffer, length); + (void)SBI_CALL0(SBI_SHUTDOWN, 0); } -static inline void sbi_net_read() { - SBI_CALL_0(SBI_NET_READ); -} +void sbi_print_version(void); +void sbi_init(void); -#endif +#endif /* !_MACHINE_SBI_H_ */ -- GitLab