arch/riscv: add new SBI calls
This is just a start. We are playing catch up. 7 down, 70+ to go. Signed-off-by: Ronald G Minnich <rminnich@gmail.com> Change-Id: I5dac8613020e26ec74ac1c74158fc9791553693f Reviewed-on: https://review.coreboot.org/c/coreboot/+/81294 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Martin L Roth <gaumless@gmail.com>
This commit is contained in:
		
				
					committed by
					
						
						ron minnich
					
				
			
			
				
	
			
			
			
						parent
						
							c47fa32cb1
						
					
				
				
					commit
					595efe4f20
				
			@@ -1,5 +1,6 @@
 | 
			
		||||
/* SPDX-License-Identifier: GPL-2.0-only */
 | 
			
		||||
 | 
			
		||||
#include <console/console.h>
 | 
			
		||||
#include <mcall.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <arch/exception.h>
 | 
			
		||||
@@ -49,6 +50,54 @@ static uintptr_t sbi_clear_ipi(void)
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void print_sbi_trap(uintptr_t trap)
 | 
			
		||||
{
 | 
			
		||||
	switch (trap) {
 | 
			
		||||
	case SBI_SHUTDOWN:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_SHUTDOWN\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_REMOTE_SFENCE_VMA_ASID:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_REMOTE_SFENCE_VMA_ASID\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_REMOTE_SFENCE_VMA:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_REMOTE_SFENCE_VMA\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_REMOTE_FENCE_I:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_REMOTE_FENCE_I\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_SEND_IPI:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_SEND_IPI\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_CLEAR_IPI:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_CLEAR_IPI\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_CONSOLE_GETCHAR:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_CONSOLE_GETCHAR\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_CONSOLE_PUTCHAR:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_CONSOLE_PUTCHAR\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_SET_TIMER:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_SET_TIMER\n");
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_BASE_EXTENSION:
 | 
			
		||||
		printk(BIOS_EMERG, "SBI_BASE_EXTENSION\n");
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		printk(BIOS_EMERG, "%lx is an unknown SBI trap\n", trap);
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * These are the default SBI extension values.
 | 
			
		||||
 * They can be overridden, by specialized code,
 | 
			
		||||
 * but since this is a GPL SBI, it may be better
 | 
			
		||||
 * that they evolve as we extend this SBI.
 | 
			
		||||
 * over time, the will be updated.
 | 
			
		||||
 */
 | 
			
		||||
int sbi_features[] = {1, 0, 0, 0, 0, 0, 0};
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * sbi is triggered by the s-mode ecall
 | 
			
		||||
 * parameter : register a0 a1 a2
 | 
			
		||||
@@ -58,11 +107,14 @@ static uintptr_t sbi_clear_ipi(void)
 | 
			
		||||
void handle_sbi(struct trapframe *tf)
 | 
			
		||||
{
 | 
			
		||||
	uintptr_t ret = 0;
 | 
			
		||||
	uintptr_t sbiret = 0;
 | 
			
		||||
	uintptr_t arg0 = tf->gpr[10];
 | 
			
		||||
	__maybe_unused uintptr_t arg1 = tf->gpr[11];
 | 
			
		||||
	uintptr_t which = tf->gpr[17];
 | 
			
		||||
	uintptr_t fid = tf->gpr[16];
 | 
			
		||||
	uintptr_t eid = tf->gpr[17];
 | 
			
		||||
	uintptr_t retpc = read_csr(mepc) + 4;
 | 
			
		||||
 | 
			
		||||
	switch (which) {
 | 
			
		||||
	switch (eid) {
 | 
			
		||||
	case SBI_SET_TIMER:
 | 
			
		||||
#if __riscv_xlen == 32
 | 
			
		||||
		ret = sbi_set_timer(arg0 + ((uint64_t)arg1 << 32));
 | 
			
		||||
@@ -96,10 +148,23 @@ void handle_sbi(struct trapframe *tf)
 | 
			
		||||
	case SBI_SHUTDOWN:
 | 
			
		||||
		ret = send_ipi((uintptr_t *)arg0, IPI_SHUTDOWN);
 | 
			
		||||
		break;
 | 
			
		||||
	case SBI_BASE_EXTENSION:
 | 
			
		||||
		/* zero is an allowed return value for most features,
 | 
			
		||||
		 * and the only required one is feature 0.
 | 
			
		||||
		 * So this test will return legal values
 | 
			
		||||
		 * for all possible values of fid.
 | 
			
		||||
		 */
 | 
			
		||||
		if (fid < ARRAY_SIZE(sbi_features))
 | 
			
		||||
			ret = sbi_features[fid];
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		ret = -SBI_ENOSYS;
 | 
			
		||||
		print_sbi_trap(eid);
 | 
			
		||||
		printk(BIOS_EMERG, "SBI: %lx: ENOSYS\n", fid);
 | 
			
		||||
		sbiret = -SBI_ENOSYS;
 | 
			
		||||
		break;
 | 
			
		||||
	}
 | 
			
		||||
	tf->gpr[10] = ret;
 | 
			
		||||
	write_csr(mepc, read_csr(mepc) + 4);
 | 
			
		||||
	tf->gpr[10] = sbiret;
 | 
			
		||||
	tf->gpr[11] = ret;
 | 
			
		||||
 | 
			
		||||
	write_csr(mepc, retpc);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user