arch/riscv: Remove the current SBI implementation

This Supervisor Binary Interface, which is based on a page of code
that's provided to operating systems by the M-mode software, has been
superseded by a different (currently not really documented) SBI, which
is based on directly executing ECALLs instructions. Thus some of our
code becomes obsolete. Just rip it out until we implement the new SBI.

Change-Id: Iec9c20b750f39a2b8f1553e25865bbf150605a6d
Signed-off-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Reviewed-on: https://review.coreboot.org/22593
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
Jonathan Neuschäfer 2017-11-20 00:57:32 +01:00 committed by Martin Roth
parent b0de851ebb
commit 3ca8b598ed
7 changed files with 7 additions and 316 deletions

View File

@ -97,7 +97,6 @@ ramstage-y += stages.c
ramstage-y += misc.c
ramstage-y += boot.c
ramstage-y += tables.c
ramstage-y += sbi.S
ramstage-y += payload.S
ramstage-y += \
$(top)/src/lib/memchr.c \

View File

@ -1,25 +0,0 @@
/*
* 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
#ifndef __ASSEMBLY__
struct opaque;
extern struct opaque sbi_page;
#endif
#endif

View File

@ -23,32 +23,12 @@
/* We save 37 registers, currently. */
#define MENTRY_FRAME_SIZE (HLS_SIZE + 37 * 8)
#define MCALL_HART_ID 0
#define MCALL_NUM_HARTS 1
#define MCALL_QUERY_MEMORY 2
#define MCALL_CONSOLE_PUTCHAR 3
#define MCALL_CONSOLE_GETCHAR 4
#define MCALL_SEND_IPI 6
#define MCALL_CLEAR_IPI 7
#define MCALL_SHUTDOWN 8
#define MCALL_SET_TIMER 9
#define MCALL_REMOTE_SFENCE_VM 10
#define MCALL_REMOTE_FENCE_I 11
#define MCALL_CONFIG_STRING_BASE 12
#define MCALL_CONFIG_STRING_SIZE 13
#ifndef __ASSEMBLER__
#include <arch/encoding.h>
#include <atomic.h>
#include <stdint.h>
typedef struct {
unsigned long base;
unsigned long size;
unsigned long node_id;
} memory_block_info;
typedef struct {
unsigned long dev;
unsigned long cmd;
@ -80,14 +60,6 @@ typedef struct {
#define MACHINE_STACK_SIZE RISCV_PGSIZE
uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p);
uintptr_t mcall_console_putchar(uint8_t ch);
uintptr_t mcall_dev_req(sbi_device_message *m);
uintptr_t mcall_dev_resp(void);
uintptr_t mcall_set_timer(unsigned long long when);
uintptr_t mcall_clear_ipi(void);
uintptr_t mcall_send_ipi(uintptr_t recipient);
uintptr_t mcall_shutdown(void);
void hls_init(uint32_t hart_id); // need to call this before launching linux
#endif // __ASSEMBLER__

View File

@ -28,7 +28,6 @@
#include <arch/barrier.h>
#include <arch/errno.h>
#include <atomic.h>
#include <commonlib/configstring.h>
#include <console/console.h>
#include <mcall.h>
#include <string.h>
@ -36,60 +35,6 @@
int mcalldebug; // set this interactively for copious debug.
uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *info)
{
if (id == 0) {
uintptr_t base;
size_t size;
query_mem(configstring(), &base, &size);
mprv_write_ulong(&info->base, base);
mprv_write_ulong(&info->size, size);
return 0;
}
return -1;
}
uintptr_t mcall_send_ipi(uintptr_t recipient)
{
die("mcall_send_ipi is currently not implemented");
return 0;
}
uintptr_t mcall_clear_ipi(void)
{
// only clear SSIP if no other events are pending
if (HLS()->device_response_queue_head == NULL) {
clear_csr(mip, MIP_SSIP);
/* Ensure the other hart sees it. */
mb();
}
return atomic_swap(&HLS()->ipi_pending, 0);
}
uintptr_t mcall_shutdown(void)
{
die("mcall_shutdown is currently not implemented");
return 0;
}
uintptr_t mcall_set_timer(uint64_t when)
{
uint64_t *timecmp = HLS()->timecmp;
if (mcalldebug)
printk(BIOS_SPEW,
"hart %d: HLS %p: mcall timecmp@%p to 0x%llx\n",
HLS()->hart_id, HLS(), timecmp, when);
*timecmp = when;
clear_csr(mip, MIP_STIP);
set_csr(mie, MIP_MTIP);
return 0;
}
void hls_init(uint32_t hart_id)
{
printk(BIOS_SPEW, "hart %d: HLS is %p\n", hart_id, HLS());
@ -103,9 +48,3 @@ void hls_init(uint32_t hart_id)
printk(BIOS_SPEW, "Time is %p and timecmp is %p\n",
HLS()->time, HLS()->timecmp);
}
uintptr_t mcall_console_putchar(uint8_t ch)
{
do_putchar(ch);
return 0;
}

View File

@ -1,119 +0,0 @@
/*
* 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 <mcall.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, MCALL_HART_ID
ecall
jr ra
.align 4
/* -2032: size_t sbi_num_harts(void); */
li a7, MCALL_NUM_HARTS
ecall
jr ra
.align 4
/* -2016: unsigned long sbi_query_memory(unsigned long id,
memory_block_info *p); */
li a7, MCALL_QUERY_MEMORY
ecall
jr ra
.align 4
/* -2000: int sbi_console_putchar(uint8_t ch); */
li a7, MCALL_CONSOLE_PUTCHAR
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, MCALL_SHUTDOWN
ecall
jr ra
.align 4
/* -1888: void sbi_set_timer(unsigned long long stime_value); */
li a7, MCALL_SET_TIMER
ecall
jr ra
.align 4
/* -1872: int sbi_mask_interrupt(int which); */
li a0, 0 # dummy
jr ra
.align 4
/* -1856: int sbi_unmask_interrupt(int which); */
li a0, 0 # dummy
jr ra
.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

View File

@ -15,9 +15,7 @@
*/
#include <arch/exception.h>
#include <arch/sbi.h>
#include <console/console.h>
#include <mcall.h>
#include <string.h>
#include <vm.h>
#include <commonlib/configstring.h>
@ -25,52 +23,6 @@
static uint64_t *time;
static uint64_t *timecmp;
void handle_supervisor_call(trapframe *tf) {
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 MCALL_HART_ID:
printk(BIOS_DEBUG, "Getting hart id...\n");
returnValue = read_csr(0xf14);//mhartid);
break;
case MCALL_NUM_HARTS:
/* TODO: parse the hardware-supplied config string and
return the correct value */
returnValue = 1;
break;
case MCALL_CONSOLE_PUTCHAR:
returnValue = mcall_console_putchar(arg0);
break;
case MCALL_SEND_IPI:
printk(BIOS_DEBUG, "Sending IPI...\n");
returnValue = mcall_send_ipi(arg0);
break;
case MCALL_CLEAR_IPI:
printk(BIOS_DEBUG, "Clearing IPI...\n");
returnValue = mcall_clear_ipi();
break;
case MCALL_SHUTDOWN:
printk(BIOS_DEBUG, "Shutting down...\n");
returnValue = mcall_shutdown();
break;
case MCALL_SET_TIMER:
returnValue = mcall_set_timer(arg0);
break;
case MCALL_QUERY_MEMORY:
printk(BIOS_DEBUG, "Querying memory, CPU #%lld...\n", arg0);
returnValue = mcall_query_memory(arg0, (memory_block_info*) arg1);
break;
default:
printk(BIOS_DEBUG, "ERROR! Unrecognized SBI call\n");
returnValue = 0;
break; // note: system call we do not know how to handle
}
tf->gpr[10] = returnValue;
write_csr(mepc, read_csr(mepc) + 4);
}
static const char *const exception_names[] = {
"Instruction address misaligned",
"Instruction access fault",
@ -204,6 +156,7 @@ void trap_handler(trapframe *tf)
case CAUSE_FAULT_LOAD:
case CAUSE_FAULT_STORE:
case CAUSE_USER_ECALL:
case CAUSE_SUPERVISOR_ECALL:
case CAUSE_HYPERVISOR_ECALL:
case CAUSE_MACHINE_ECALL:
print_trap_information(tf);
@ -216,11 +169,6 @@ void trap_handler(trapframe *tf)
print_trap_information(tf);
handle_misaligned_store(tf);
return;
case CAUSE_SUPERVISOR_ECALL:
/* Don't print so we make console putchar calls look
the way they should */
handle_supervisor_call(tf);
return;
default:
printk(BIOS_EMERG, "================================\n");
printk(BIOS_EMERG, "coreboot: can not handle a trap:\n");

View File

@ -16,7 +16,6 @@
#include <arch/barrier.h>
#include <arch/encoding.h>
#include <arch/sbi.h>
#include <atomic.h>
#include <console/console.h>
#include <stdint.h>
@ -144,7 +143,6 @@ pte_t pte_create(uintptr_t ppn, int prot, int user)
// The current RISCV *physical* address space is this:
// * 0 - 2 GiB: miscellaneous IO devices
// * 2 GiB - 4 GiB DRAM
// * top 2048 bytes of memory: SBI (which we round out to a 4K page)
// We have determined, also, that if code references a physical address
// not backed by a device, we'll take a fault. In other words, we don't
// need to finely map the memory-mapped devices as we would on an x86.
@ -166,16 +164,11 @@ pte_t pte_create(uintptr_t ppn, int prot, int user)
// I.e. we use 1 GiB PTEs for 4 GiB.
// Linux/BSD uses this mapping just enough to replace it.
//
// The SBI page is the last page in the 64 bit address space.
// map that using the middle_pts shown below.
// Top 2G map: map the 2 Gib - 4 GiB of physical address space to
// 0xffffffff_80000000. This will be needed until the GNU toolchain can compile
// code to run at 0xffffffc000000000, i.e. the start of Sv39.
//
// Top 2G map, including SBI page: map the 2 Gib - 4 GiB of physical
// address space to 0xffffffff_80000000. This will be needed until the
// GNU toolchain can compile code to run at 0xffffffc000000000,
// i.e. the start of Sv39.
//
// Only Harvey/Plan 9 uses this Mapping, and temporarily. It can
// never be full removed as we need the 4KiB mapping for the SBI page.
// Only Harvey/Plan 9 uses this Mapping, and temporarily.
//
// standard RISCV map long term: Map IO space, and all of DRAM, to the *lowest*
// possible negative address for this implementation,
@ -187,15 +180,13 @@ pte_t pte_create(uintptr_t ppn, int prot, int user)
// It is our intent on Harvey (and eventually Akaros) that we use
// this map, once the toolchain can correctly support it.
// We have tested this arrangement and it lets us boot harvey to user mode.
void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, pte_t *sbi_pt)
void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, pte_t *pt)
{
memset(sbi_pt, 0, RISCV_PGSIZE);
// need to leave room for sbi page
// 0xFFF... - 0xFFFFFFFF81000000 - RISCV_PGSIZE
intptr_t memorySize = 0x7F000000;
// middle page table
pte_t* middle_pt = (void*)sbi_pt + RISCV_PGSIZE;
pte_t* middle_pt = (void*)pt;
size_t num_middle_pts = 2; // 3 level page table, 39 bit virtual address space for now
// root page table
@ -215,20 +206,6 @@ void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, pte_t *sbi_pt)
PTE_U|PTE_R|PTE_W|PTE_X, 0);
}
// map SBI at top of vaddr space
// only need to map a single page for sbi interface
uintptr_t num_sbi_pages = 1;
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;
sbi_pt[idx] = pte_create(sbiAddr >> RISCV_PGSHIFT,
PTE_R|PTE_X, 0);
sbiAddr += RISCV_PGSIZE;
}
pte_t* sbi_pte = middle_pt + ((num_middle_pts << RISCV_PGLEVEL_BITS)-1);
*sbi_pte = ptd_create((uintptr_t)sbi_pt >> RISCV_PGSHIFT);
// IO space. Identity mapped.
root_pt[0x000] = pte_create(0x00000000 >> RISCV_PGSHIFT,
PTE_R | PTE_W, 0);