<p>Xiang Wang has uploaded this change for <strong>review</strong>.</p><p><a href="https://review.coreboot.org/28096">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">riscv: add support for supervisor binary interface (SBI)<br><br>SBI is runtime service for OS. For an introduction, please refer to https://github.com/riscv/riscv-sbi-doc/blob/master/riscv-sbi.md<br><br>Change-Id: Ib6c1f21d2f085f02208305dc4e3a0f970d400c27<br>Signed-off-by: Xiang Wang <wxjstz@126.com><br>---<br>M src/arch/riscv/Makefile.inc<br>A src/arch/riscv/include/sbi.h<br>A src/arch/riscv/sbi.c<br>M src/arch/riscv/trap_handler.c<br>4 files changed, 175 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://review.coreboot.org:29418/coreboot refs/changes/96/28096/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc</span><br><span>index 89feb1b..eae0f0a 100644</span><br><span>--- a/src/arch/riscv/Makefile.inc</span><br><span>+++ b/src/arch/riscv/Makefile.inc</span><br><span>@@ -45,6 +45,7 @@</span><br><span> bootblock-y += trap_handler.c</span><br><span> bootblock-y += fp_asm.S</span><br><span> bootblock-y += misaligend.c</span><br><span style="color: hsl(120, 100%, 40%);">+bootblock-y += sbi.c</span><br><span> bootblock-y += mcall.c</span><br><span> bootblock-y += virtual_memory.c</span><br><span> bootblock-y += boot.c</span><br><span>diff --git a/src/arch/riscv/include/sbi.h b/src/arch/riscv/include/sbi.h</span><br><span>new file mode 100644</span><br><span>index 0000000..2c6106d</span><br><span>--- /dev/null</span><br><span>+++ b/src/arch/riscv/include/sbi.h</span><br><span>@@ -0,0 +1,33 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2018 HardenedLinux</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_SET_TIMER 0</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_CONSOLE_PUTCHAR 1</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_CONSOLE_GETCHAR 2</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_CLEAR_IPI 3</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_SEND_IPI 4</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_REMOTE_FENCE_I 5</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_REMOTE_SFENCE_VMA 6</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_REMOTE_SFENCE_VMA_ASID 7</span><br><span style="color: hsl(120, 100%, 40%);">+#define SBI_SHUTDOWN 8</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define IPI_SOFT 1</span><br><span style="color: hsl(120, 100%, 40%);">+#define IPI_FENCE_I 2</span><br><span style="color: hsl(120, 100%, 40%);">+#define IPI_SFENCE_VMA 4</span><br><span style="color: hsl(120, 100%, 40%);">+#define IPI_SFENCE_VMA_ASID 8</span><br><span style="color: hsl(120, 100%, 40%);">+#define IPI_SHUTDOWN 16</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void handle_sbi(trapframe *tf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/src/arch/riscv/sbi.c b/src/arch/riscv/sbi.c</span><br><span>new file mode 100644</span><br><span>index 0000000..e76e152</span><br><span>--- /dev/null</span><br><span>+++ b/src/arch/riscv/sbi.c</span><br><span>@@ -0,0 +1,122 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * This file is part of the coreboot project.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2018 HardenedLinux</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; version 2 of the License.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <mcall.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <compiler.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <arch/exception.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sbi.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <vm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <console/uart.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void set_msip(int hartid, int val);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* FIXME: removed when implemented by a specific platform */</span><br><span style="color: hsl(120, 100%, 40%);">+__weak void set_msip(int hartid, int val) { }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uintptr_t send_ipi(uintptr_t *pmask, intptr_t type)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uintptr_t mask = mprv_read_ulong((unsigned long *)pmask);</span><br><span style="color: hsl(120, 100%, 40%);">+ for (int i = 0; mask; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+ if (mask & 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+ OTHER_HLS(i)->ipi_pending |= type;</span><br><span style="color: hsl(120, 100%, 40%);">+ /* send soft interrupt to target hart */</span><br><span style="color: hsl(120, 100%, 40%);">+ set_msip(i, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ mask = mask >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uintptr_t sbi_set_timer(uint64_t when)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ *(HLS()->timecmp) = when;</span><br><span style="color: hsl(120, 100%, 40%);">+ clear_csr(mip, MIP_STIP);</span><br><span style="color: hsl(120, 100%, 40%);">+ set_csr(mie, MIP_MTIP);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uintptr_t sbi_console_putchar(uint8_t ch)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+#if (IS_ENABLED(CONFIG_CONSOLE_SERIAL))</span><br><span style="color: hsl(120, 100%, 40%);">+ uart_tx_byte(CONFIG_UART_FOR_CONSOLE, ch);</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uintptr_t sbi_console_getchar(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+#if (IS_ENABLED(CONFIG_CONSOLE_SERIAL))</span><br><span style="color: hsl(120, 100%, 40%);">+ return uart_rx_byte(CONFIG_UART_FOR_CONSOLE);</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static uintptr_t sbi_clear_ipi(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return clear_csr(mip, MIP_SSIP) & MIP_SSIP;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void handle_sbi(trapframe *tf)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+#define arg0 (tf->gpr[10])</span><br><span style="color: hsl(120, 100%, 40%);">+#define arg1 (tf->gpr[11])</span><br><span style="color: hsl(120, 100%, 40%);">+#define arg2 (tf->gpr[12])</span><br><span style="color: hsl(120, 100%, 40%);">+#define which (tf->gpr[17])</span><br><span style="color: hsl(120, 100%, 40%);">+#define ret (tf->gpr[10])</span><br><span style="color: hsl(120, 100%, 40%);">+ switch (which) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_SET_TIMER:</span><br><span style="color: hsl(120, 100%, 40%);">+#if __riscv_xlen == 32</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = sbi_set_timer(arg0 + ((uint64_t)arg1 << 32));</span><br><span style="color: hsl(120, 100%, 40%);">+#else</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = sbi_set_timer(arg0);</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_CONSOLE_PUTCHAR:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = sbi_console_putchar(arg0);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_CONSOLE_GETCHAR:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = sbi_console_getchar();</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_CLEAR_IPI:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = sbi_clear_ipi();</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_SEND_IPI:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = send_ipi((uintptr_t *)arg0, IPI_SOFT);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_REMOTE_FENCE_I:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = send_ipi((uintptr_t *)arg0, IPI_FENCE_I);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_REMOTE_SFENCE_VMA:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = send_ipi((uintptr_t *)arg0, IPI_SFENCE_VMA);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_REMOTE_SFENCE_VMA_ASID:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = send_ipi((uintptr_t *)arg0, IPI_SFENCE_VMA_ASID);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case SBI_SHUTDOWN:</span><br><span style="color: hsl(120, 100%, 40%);">+ ret = send_ipi((uintptr_t *)arg0, IPI_SHUTDOWN);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c</span><br><span>index e9771af..d4c3932 100644</span><br><span>--- a/src/arch/riscv/trap_handler.c</span><br><span>+++ b/src/arch/riscv/trap_handler.c</span><br><span>@@ -19,6 +19,8 @@</span><br><span> #include <console/console.h></span><br><span> #include <string.h></span><br><span> #include <vm.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <mcall.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <sbi.h></span><br><span> </span><br><span> static uint64_t *time;</span><br><span> static uint64_t *timecmp;</span><br><span>@@ -135,6 +137,20 @@</span><br><span> msip |= SIP_STIP;</span><br><span> write_csr(mip, msip);</span><br><span> break;</span><br><span style="color: hsl(120, 100%, 40%);">+ case IRQ_M_SOFT:</span><br><span style="color: hsl(120, 100%, 40%);">+ if (HLS()->ipi_pending & IPI_SOFT) {</span><br><span style="color: hsl(120, 100%, 40%);">+ set_csr(mip, MIP_SSIP);</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (HLS()->ipi_pending & IPI_FENCE_I) {</span><br><span style="color: hsl(120, 100%, 40%);">+ asm("fence.i");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (HLS()->ipi_pending & IPI_SFENCE_VMA) {</span><br><span style="color: hsl(120, 100%, 40%);">+ asm("sfence.vma");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (HLS()->ipi_pending & IPI_SFENCE_VMA_ASID) {</span><br><span style="color: hsl(120, 100%, 40%);">+ asm("sfence.vma");</span><br><span style="color: hsl(120, 100%, 40%);">+ } else if (HLS()->ipi_pending & IPI_SHUTDOWN) {</span><br><span style="color: hsl(120, 100%, 40%);">+ while (HLS()->ipi_pending & IPI_SHUTDOWN)</span><br><span style="color: hsl(120, 100%, 40%);">+ asm("wfi");</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span> default:</span><br><span> printk(BIOS_EMERG, "======================================\n");</span><br><span> printk(BIOS_EMERG, "coreboot: Unknown machine interrupt: 0x%llx\n",</span><br><span>@@ -161,6 +177,9 @@</span><br><span> case CAUSE_STORE_ACCESS:</span><br><span> case CAUSE_USER_ECALL:</span><br><span> case CAUSE_SUPERVISOR_ECALL:</span><br><span style="color: hsl(120, 100%, 40%);">+ print_trap_information(tf);</span><br><span style="color: hsl(120, 100%, 40%);">+ handle_sbi(tf);</span><br><span style="color: hsl(120, 100%, 40%);">+ return;</span><br><span> case CAUSE_HYPERVISOR_ECALL:</span><br><span> case CAUSE_MACHINE_ECALL:</span><br><span> print_trap_information(tf);</span><br><span></span><br></pre><p>To view, visit <a href="https://review.coreboot.org/28096">change 28096</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://review.coreboot.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://review.coreboot.org/28096"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: coreboot </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: Ib6c1f21d2f085f02208305dc4e3a0f970d400c27 </div>
<div style="display:none"> Gerrit-Change-Number: 28096 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Xiang Wang <wxjstz@126.com> </div>