<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>