arch/riscv: Implement the SBI again
Not all SBI calls are implemented, but it's enough to see a couple dozen lines of Linux boot output. It should also be noted that the SBI is still in flux: https://groups.google.com/a/groups.riscv.org/forum/#!topic/sw-dev/6oNhlW0OFKM Change-Id: I80e4fe508336d6428ca7136bc388fbc3cda4f1e4 Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net> Reviewed-on: https://review.coreboot.org/16119 Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
parent
3965a522c2
commit
857e33e27f
|
@ -95,6 +95,7 @@ ramstage-y += stages.c
|
|||
ramstage-y += misc.c
|
||||
ramstage-y += boot.c
|
||||
ramstage-y += tables.c
|
||||
ramstage-y += sbi.S
|
||||
ramstage-y += \
|
||||
$(top)/src/lib/memchr.c \
|
||||
$(top)/src/lib/memcmp.c \
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Jonathan Neuschäfer <j.neuschaefer@gmx.net>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ARCH_SBI_H
|
||||
#define _ARCH_SBI_H
|
||||
|
||||
#define SBI_ECALL_HART_ID 0
|
||||
#define SBI_ECALL_CONSOLE_PUT 1
|
||||
#define SBI_ECALL_SEND_DEVICE_REQUEST 2
|
||||
#define SBI_ECALL_RECEIVE_DEVICE_RESPONSE 3
|
||||
#define SBI_ECALL_SEND_IPI 4
|
||||
#define SBI_ECALL_CLEAR_IPI 5
|
||||
#define SBI_ECALL_SHUTDOWN 6
|
||||
#define SBI_ECALL_SET_TIMER 7
|
||||
#define SBI_ECALL_QUERY_MEMORY 8
|
||||
#define SBI_ECALL_NUM_HARTS 9
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
struct opaque;
|
||||
extern struct opaque sbi_page;
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* RISC-V supervisor binary interface (SBI) trampoline page
|
||||
*
|
||||
* Copyright 2016 Jonathan Neuschäfer <j.neuschaefer@gmx.net>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#define __ASSEMBLY__
|
||||
#include <arch/encoding.h>
|
||||
#include <arch/sbi.h>
|
||||
|
||||
.section ".text.sbi", "ax", %progbits
|
||||
|
||||
/* align to a page boundary */
|
||||
.align RISCV_PGSHIFT
|
||||
|
||||
.globl sbi_page
|
||||
sbi_page:
|
||||
|
||||
/*
|
||||
* None of the SBI entry points is located in the first half of the
|
||||
* page
|
||||
*/
|
||||
.skip 0x800
|
||||
|
||||
/* -2048: size_t sbi_hart_id(void); */
|
||||
li a7, SBI_ECALL_HART_ID
|
||||
ecall
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -2032: size_t sbi_num_harts(void); */
|
||||
li a7, SBI_ECALL_NUM_HARTS
|
||||
ecall
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -2016: unsigned long sbi_query_memory(unsigned long id,
|
||||
memory_block_info *p); */
|
||||
li a7, SBI_ECALL_QUERY_MEMORY
|
||||
ecall
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -2000: int sbi_console_putchar(uint8_t ch); */
|
||||
li a7, SBI_ECALL_CONSOLE_PUT
|
||||
ecall
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -1984: int sbi_console_getchar(void); */
|
||||
li a0, -1 /* failure: Coreboot doesn't support console input */
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -1968: Not allocated */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* -1952: int sbi_send_ipi(size_t hart_id); */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* -1936: int bool sbi_clear_ipi(void); */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* -1920: unsigned long sbi_timebase(void); */
|
||||
li a0, 1000000000 /* I have no idea. */
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -1904: void sbi_shutdown(void); */
|
||||
li a7, SBI_ECALL_SHUTDOWN
|
||||
ecall
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -1888: void sbi_set_timer(unsigned long long stime_value); */
|
||||
li a7, SBI_ECALL_SET_TIMER
|
||||
ecall
|
||||
jr ra
|
||||
.align 4
|
||||
|
||||
/* -1872: int sbi_mask_interrupt(int which); */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* -1856: int sbi_unmask_interrupt(int which); */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* -1840: void sbi_remote_sfence_vm(const uintptr_t* harts,
|
||||
size_t asid); */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* -1824: void sbi_remote_sfence_vm_range(const uintptr_t* harts,
|
||||
size_t asid, uintptr_t start, uintptr_t size); */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* -1808: void sbi_remote_fence_i(const uintptr_t* harts); */
|
||||
ebreak
|
||||
.align 4
|
||||
|
||||
/* Fill the remainder of the page */
|
||||
.align RISCV_PGSHIFT
|
|
@ -15,63 +15,56 @@
|
|||
*/
|
||||
|
||||
#include <arch/exception.h>
|
||||
#include <arch/sbi.h>
|
||||
#include <console/console.h>
|
||||
#include <spike_util.h>
|
||||
#include <string.h>
|
||||
#include <vm.h>
|
||||
|
||||
#define HART_ID 0
|
||||
#define CONSOLE_PUT 1
|
||||
#define SEND_DEVICE_REQUEST 2
|
||||
#define RECEIVE_DEVICE_RESPONSE 3
|
||||
#define SEND_IPI 4
|
||||
#define CLEAR_IPI 5
|
||||
#define SHUTDOWN 6
|
||||
#define SET_TIMER 7
|
||||
#define QUERY_MEMORY 8
|
||||
|
||||
int loopBreak2 = 1;
|
||||
|
||||
void handle_supervisor_call(trapframe *tf) {
|
||||
uintptr_t call = tf->gpr[17];
|
||||
uintptr_t arg0 = tf->gpr[10];
|
||||
uintptr_t arg1 = tf->gpr[11];
|
||||
uintptr_t call = tf->gpr[17]; /* a7 */
|
||||
uintptr_t arg0 = tf->gpr[10]; /* a0 */
|
||||
uintptr_t arg1 = tf->gpr[11]; /* a1 */
|
||||
uintptr_t returnValue;
|
||||
switch(call) {
|
||||
case HART_ID:
|
||||
case SBI_ECALL_HART_ID:
|
||||
printk(BIOS_DEBUG, "Getting hart id...\n");
|
||||
returnValue = mcall_hart_id();
|
||||
returnValue = read_csr(mhartid);
|
||||
break;
|
||||
case CONSOLE_PUT:
|
||||
case SBI_ECALL_NUM_HARTS:
|
||||
/* TODO: parse the hardware-supplied config string and
|
||||
return the correct value */
|
||||
returnValue = 1;
|
||||
case SBI_ECALL_CONSOLE_PUT:
|
||||
returnValue = mcall_console_putchar(arg0);
|
||||
break;
|
||||
case SEND_DEVICE_REQUEST:
|
||||
case SBI_ECALL_SEND_DEVICE_REQUEST:
|
||||
printk(BIOS_DEBUG, "Sending device request...\n");
|
||||
returnValue = mcall_dev_req((sbi_device_message*) arg0);
|
||||
break;
|
||||
case RECEIVE_DEVICE_RESPONSE:
|
||||
case SBI_ECALL_RECEIVE_DEVICE_RESPONSE:
|
||||
printk(BIOS_DEBUG, "Getting device response...\n");
|
||||
returnValue = mcall_dev_resp();
|
||||
break;
|
||||
case SEND_IPI:
|
||||
case SBI_ECALL_SEND_IPI:
|
||||
printk(BIOS_DEBUG, "Sending IPI...\n");
|
||||
returnValue = mcall_send_ipi(arg0);
|
||||
break;
|
||||
case CLEAR_IPI:
|
||||
case SBI_ECALL_CLEAR_IPI:
|
||||
printk(BIOS_DEBUG, "Clearing IPI...\n");
|
||||
returnValue = mcall_clear_ipi();
|
||||
break;
|
||||
case SHUTDOWN:
|
||||
case SBI_ECALL_SHUTDOWN:
|
||||
printk(BIOS_DEBUG, "Shutting down...\n");
|
||||
returnValue = mcall_shutdown();
|
||||
break;
|
||||
case SET_TIMER:
|
||||
case SBI_ECALL_SET_TIMER:
|
||||
printk(BIOS_DEBUG,
|
||||
"Setting timer to %p (current time is %p)...\n",
|
||||
(void *)arg0, (void *)rdtime());
|
||||
returnValue = mcall_set_timer(arg0);
|
||||
break;
|
||||
case QUERY_MEMORY:
|
||||
case SBI_ECALL_QUERY_MEMORY:
|
||||
printk(BIOS_DEBUG, "Querying memory, CPU #%lld...\n", arg0);
|
||||
returnValue = mcall_query_memory(arg0, (memory_block_info*) arg1);
|
||||
break;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <arch/barrier.h>
|
||||
#include <arch/encoding.h>
|
||||
#include <arch/sbi.h>
|
||||
#include <atomic.h>
|
||||
#include <console/console.h>
|
||||
#include <stdint.h>
|
||||
|
@ -151,7 +152,7 @@ void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTable
|
|||
|
||||
// map SBI at top of vaddr space
|
||||
uintptr_t num_sbi_pages = 1; // only need to map a single page for sbi interface
|
||||
uintptr_t sbiStartAddress = 0x2000; // the start of the sbi mapping
|
||||
uintptr_t sbiStartAddress = (uintptr_t) &sbi_page;
|
||||
uintptr_t sbiAddr = sbiStartAddress;
|
||||
for (uintptr_t i = 0; i < num_sbi_pages; i++) {
|
||||
uintptr_t idx = (1 << RISCV_PGLEVEL_BITS) - num_sbi_pages + i;
|
||||
|
|
|
@ -25,12 +25,13 @@
|
|||
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
|
||||
#include <spike_util.h>
|
||||
#include <arch/barrier.h>
|
||||
#include <arch/errno.h>
|
||||
#include <atomic.h>
|
||||
#include <string.h>
|
||||
#include <console/console.h>
|
||||
#include <spike_util.h>
|
||||
#include <string.h>
|
||||
#include <vm.h>
|
||||
|
||||
uintptr_t translate_address(uintptr_t vAddr) {
|
||||
// TODO: implement the page table translation algorithm
|
||||
|
@ -41,13 +42,13 @@ uintptr_t translate_address(uintptr_t vAddr) {
|
|||
return translationResult;
|
||||
}
|
||||
|
||||
uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p)
|
||||
uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *info)
|
||||
{
|
||||
uintptr_t physicalAddr = translate_address((uintptr_t) p);
|
||||
memory_block_info *info = (memory_block_info*) physicalAddr;
|
||||
if (id == 0) {
|
||||
info->base = 0x1000000; // hard coded for now, but we can put these values somewhere later
|
||||
info->size = 0x7F000000 - info->base;
|
||||
mprv_write_ulong(&info->base, 2U*GiB);
|
||||
|
||||
/* TODO: Return the correct value */
|
||||
mprv_write_ulong(&info->size, 1*GiB);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -79,7 +80,7 @@ uintptr_t mcall_shutdown(void)
|
|||
|
||||
uintptr_t mcall_set_timer(unsigned long long when)
|
||||
{
|
||||
die("mcall_set_timer is currently not implemented");
|
||||
printk(BIOS_DEBUG, "mcall_set_timer is currently not implemented, ignoring\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -95,11 +96,6 @@ uintptr_t mcall_dev_resp(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uintptr_t mcall_hart_id(void)
|
||||
{
|
||||
return HLS()->hart_id;
|
||||
}
|
||||
|
||||
void hls_init(uint32_t hart_id)
|
||||
{
|
||||
memset(HLS(), 0, sizeof(*HLS()));
|
||||
|
|
Loading…
Reference in New Issue