Thaminda Edirisooriya (thaminda(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11369
-gerrit
commit 2441ebaa8010ed0153df03da0a854cf4849c4f9a
Author: Thaminda Edirisooriya <thaminda(a)google.com>
Date: Wed Aug 26 15:28:04 2015 -0700
riscv-virtual-memory: Add virtual memory setup
Execution in supervisor level code in RISCV requires early setup of
virtual memory. Add initialization calls in
src/arch/riscv/virtual_memory.c to implement the required page table
setup, and helper functions to use when jumping to the payload correctly
in riscv.
Change-Id: I46e080e0ee8dc13277d567dcd4bf0f61a4507b76
Signed-off-by: Thaminda Edirisooriya <thaminda(a)google.com>
---
src/arch/riscv/include/vm.h | 74 +++++++++++++++++++++
src/arch/riscv/virtual_memory.c | 142 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 216 insertions(+)
diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h
new file mode 100644
index 0000000..f9ffc40
--- /dev/null
+++ b/src/arch/riscv/include/vm.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, The Regents of the University of California (Regents).
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Regents nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _VM_H
+#define _VM_H
+
+#include <string.h>
+#include <stdint.h>
+
+#define SUPERPAGE_SIZE ((uintptr_t)(RISCV_PGSIZE << RISCV_PGLEVEL_BITS))
+#define VM_CHOICE VM_SV39
+#define VA_BITS 39
+#define MEGAPAGE_SIZE (SUPERPAGE_SIZE << RISCV_PGLEVEL_BITS)
+
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+
+#define MAP_PRIVATE 0x2
+#define MAP_FIXED 0x10
+#define MAP_ANONYMOUS 0x20
+#define MAP_POPULATE 0x8000
+#define MREMAP_FIXED 0x2
+
+#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
+#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
+
+#define supervisor_paddr_valid(start, length) \
+ ((uintptr_t)(start) >= current.first_user_vaddr + current.bias \
+ && (uintptr_t)(start) + (length) < mem_size \
+ && (uintptr_t)(start) + (length) >= (uintptr_t)(start))
+
+typedef uintptr_t pte_t;
+extern pte_t* root_page_table;
+
+void enter_supervisor(void);
+void initVirtualMemory(void);
+
+size_t pte_ppn(pte_t pte);
+pte_t ptd_create(uintptr_t ppn);
+pte_t pte_create(uintptr_t ppn, int prot, int user);
+
+void walk_page_table(void);
+
+void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTableStart);
+void mstatus_init(void); // need to setup mstatus so we know we have virtual memory
+
+void flush_tlb(void);
+
+#endif
diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c
new file mode 100644
index 0000000..78405dd
--- /dev/null
+++ b/src/arch/riscv/virtual_memory.c
@@ -0,0 +1,142 @@
+/*
+ * Early initialization code for riscv virtual memory
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <vm.h>
+#include <arch/encoding.h>
+#include <atomic.h>
+#include <stdint.h>
+#include <console/console.h>
+
+pte_t* root_page_table;
+
+void walk_page_table(void) {
+ // TODO: implement a full walk to make sure memory was set up
+ //const size_t pte_per_page = RISCV_PGSIZE/sizeof(void*);
+ pte_t* t = root_page_table;
+ printk(BIOS_DEBUG, "root_page_table: %p\n", t);
+}
+
+void enter_supervisor(void) {
+ // enter supervisor mode
+ asm volatile("la t0, 1f; csrw mepc, t0; eret; 1:" ::: "t0");
+}
+
+void flush_tlb(void)
+{
+ asm volatile("sfence.vm");
+}
+
+size_t pte_ppn(pte_t pte)
+{
+ return pte >> PTE_PPN_SHIFT;
+}
+
+pte_t ptd_create(uintptr_t ppn)
+{
+ return (ppn << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
+}
+
+pte_t pte_create(uintptr_t ppn, int prot, int user)
+{
+ pte_t pte = (ppn << PTE_PPN_SHIFT) | PTE_V;
+ if (prot & PROT_WRITE) pte |= PTE_TYPE_URW_SRW;
+ if (prot & PROT_EXEC) pte |= PTE_TYPE_URX_SRX;
+ if (!user) pte |= PTE_TYPE_SR;
+ return pte;
+}
+
+void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTableStart) {
+ pte_t* sbi_pt = (pte_t*) pageTableStart;
+ memset(sbi_pt, 0, RISCV_PGSIZE);
+ // need to leave room for sbi page
+ uintptr_t memorySize = 0x7F000000; // 0xFFF... - 0xFFFFFFFF81000000 - RISCV_PGSIZE
+
+ // middle page table
+ pte_t* middle_pt = (void*)sbi_pt + RISCV_PGSIZE;
+ size_t num_middle_pts = 2; // 3 level page table, 39 bit virtual address space for now
+
+ // root page table
+ pte_t* root_pt = (void*)middle_pt + num_middle_pts * RISCV_PGSIZE;
+ memset(middle_pt, 0, (num_middle_pts + 1) * RISCV_PGSIZE); // 0's out middle_pt and root_pt
+ for (size_t i = 0; i < num_middle_pts; i++)
+ root_pt[(1<<RISCV_PGLEVEL_BITS)-num_middle_pts+i] = ptd_create(((uintptr_t)middle_pt >> RISCV_PGSHIFT) + i);
+
+ // fill the middle page table
+ for (uintptr_t vaddr = virtMemStart, paddr = physMemStart; paddr < memorySize; vaddr += SUPERPAGE_SIZE, paddr += SUPERPAGE_SIZE) {
+ int l2_shift = RISCV_PGLEVEL_BITS + RISCV_PGSHIFT;
+ size_t l2_idx = (virtMemStart >> l2_shift) & ((1 << RISCV_PGLEVEL_BITS)-1);
+ l2_idx += ((vaddr - virtMemStart) >> l2_shift);
+ middle_pt[l2_idx] = pte_create(paddr >> RISCV_PGSHIFT, PROT_READ|PROT_WRITE|PROT_EXEC, 0);
+ }
+
+ // 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 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, PROT_READ|PROT_EXEC, 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);
+
+ mb();
+ root_page_table = root_pt;
+ write_csr(sptbr, root_pt);
+}
+
+void initVirtualMemory(void) {
+ printk(BIOS_DEBUG, "Initializing virtual memory...\n");
+ uintptr_t physicalStart = 0x1000000; // TODO: Figure out how to grab this from cbfs
+ uintptr_t virtualStart = 0xffffffff81000000;
+ uintptr_t pageTableStart = 0x1f0000;
+ init_vm(virtualStart, physicalStart, pageTableStart);
+ mb();
+ printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");
+ walk_page_table();
+}
+
+void mstatus_init(void)
+{
+ // supervisor support is required
+
+ uintptr_t ms = 0;
+ ms = INSERT_FIELD(ms, MSTATUS_PRV, PRV_M);
+ ms = INSERT_FIELD(ms, MSTATUS_PRV1, PRV_S);
+ ms = INSERT_FIELD(ms, MSTATUS_PRV2, PRV_U);
+ ms = INSERT_FIELD(ms, MSTATUS_IE2, 1);
+ ms = INSERT_FIELD(ms, MSTATUS_VM, VM_CHOICE);
+ ms = INSERT_FIELD(ms, MSTATUS_FS, 3);
+ ms = INSERT_FIELD(ms, MSTATUS_XS, 3);
+ write_csr(mstatus, ms);
+ ms = read_csr(mstatus);
+
+ if (EXTRACT_FIELD(ms, MSTATUS_VM) != VM_CHOICE) {
+ printk(BIOS_DEBUG, "we don't have virtual memory...\n");
+ } else {
+ printk(BIOS_DEBUG, "-----------------------------\n");
+ printk(BIOS_DEBUG, "virtual memory status enabled\n");
+ printk(BIOS_DEBUG, "-----------------------------\n");
+ }
+
+ clear_csr(mip, MIP_MSIP);
+ set_csr(mie, MIP_MSIP);
+}
Thaminda Edirisooriya (thaminda(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11368
-gerrit
commit 2857a06ba5e7131b95b47ec81706345bbcdbfb16
Author: Thaminda Edirisooriya <thaminda(a)google.com>
Date: Wed Aug 26 14:54:31 2015 -0700
riscv-trap-handling: Add implementation for trap calls in riscv
RISCV requires the bios/bootloader to set up an interface by which it
can get information about memory, talk to host devices, etc. Put
implementation for spike in
src/mainboard/emulation/spike-riscv/spike_util.c, and
src/arch/riscv/trap_handler.c
Change-Id: Ie1d5f361595e48fa6cc1fac25485ad623ecdc717
Signed-off-by: Thaminda Edirisooriya <thaminda(a)google.com>
---
src/arch/riscv/Makefile.inc | 2 +
src/arch/riscv/include/arch/errno.h | 66 ++++++++
src/arch/riscv/include/arch/exception.h | 22 +++
src/arch/riscv/include/spike_util.h | 17 ++
src/arch/riscv/trap_handler.c | 193 +++++++++++++++++++++++
src/arch/riscv/trap_util.S | 2 +-
src/mainboard/emulation/spike-riscv/spike_util.c | 136 ++++++++++++++++
7 files changed, 437 insertions(+), 1 deletion(-)
diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc
index 0f3eb0f..c7a2c16 100644
--- a/src/arch/riscv/Makefile.inc
+++ b/src/arch/riscv/Makefile.inc
@@ -29,6 +29,8 @@ riscv_asm_flags =
ifeq ($(CONFIG_ARCH_BOOTBLOCK_RISCV),y)
bootblock-y = bootblock.S stages.c
+bootblock-y += trap_util.S
+bootblock-y += trap_handler.c
bootblock-y += boot.c
bootblock-y += rom_media.c
bootblock-y += \
diff --git a/src/arch/riscv/include/arch/errno.h b/src/arch/riscv/include/arch/errno.h
new file mode 100644
index 0000000..6f80ee5
--- /dev/null
+++ b/src/arch/riscv/include/arch/errno.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013, The Regents of the University of California (Regents).
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Regents nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _RISCV_ERRNO_BASE_H
+#define _RISCV_ERRNO_BASE_H
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+
+#endif
diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h
index befab1f..4318cba 100644
--- a/src/arch/riscv/include/arch/exception.h
+++ b/src/arch/riscv/include/arch/exception.h
@@ -32,8 +32,30 @@
#include <stdint.h>
+typedef struct
+{
+ uintptr_t gpr[32];
+ uintptr_t status;
+ uintptr_t epc;
+ uintptr_t badvaddr;
+ uintptr_t cause;
+ uintptr_t insn;
+} trapframe;
+
+typedef uint32_t insn_t;
+
+typedef struct {
+ uintptr_t error;
+ insn_t insn;
+} insn_fetch_t;
+
static inline void exception_init(void)
{
}
+void trap_handler(trapframe* tf);
+void handle_supervisor_call(trapframe* tf);
+//void handleMisalignedLoad(trapframe *tf);
+void handle_misaligned_store(trapframe *tf);
+
#endif
diff --git a/src/arch/riscv/include/spike_util.h b/src/arch/riscv/include/spike_util.h
index a9d14cc..e9c0300 100644
--- a/src/arch/riscv/include/spike_util.h
+++ b/src/arch/riscv/include/spike_util.h
@@ -40,6 +40,12 @@
#define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16)
typedef struct {
+ unsigned long base;
+ unsigned long size;
+ unsigned long node_id;
+} memory_block_info;
+
+typedef struct {
unsigned long dev;
unsigned long cmd;
unsigned long data;
@@ -63,11 +69,22 @@ typedef struct {
// hart-local storage, at top of stack
#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
+#define OTHER_HLS(id) ((hls_t*)((void*)HLS() + RISCV_PGSIZE * ((id) - HLS()->hart_id)))
#define MACHINE_STACK_SIZE RISCV_PGSIZE
+uintptr_t translate_address(uintptr_t vAddr);
+uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p);
+uintptr_t mcall_hart_id(void);
uintptr_t htif_interrupt(uintptr_t mcause, uintptr_t* regs);
uintptr_t mcall_console_putchar(uint8_t ch);
void testPrint(void);
+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
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
new file mode 100644
index 0000000..d4c9b87
--- /dev/null
+++ b/src/arch/riscv/trap_handler.c
@@ -0,0 +1,193 @@
+/*
+ * Early initialization code for riscv
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <console/console.h>
+#include <arch/exception.h>
+#include <spike_util.h>
+#include <string.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 returnValue;
+ switch(call) {
+ case HART_ID:
+ printk(BIOS_DEBUG, "Getting hart id...\n");
+ returnValue = mcall_hart_id();
+ break;
+ case CONSOLE_PUT:
+ returnValue = mcall_console_putchar(arg0);
+ break;
+ case SEND_DEVICE_REQUEST:
+ printk(BIOS_DEBUG, "Sending device request...\n");
+ returnValue = mcall_dev_req((sbi_device_message*) arg0);
+ break;
+ case RECEIVE_DEVICE_RESPONSE:
+ printk(BIOS_DEBUG, "Getting device response...\n");
+ returnValue = mcall_dev_resp();
+ break;
+ case SEND_IPI:
+ printk(BIOS_DEBUG, "Sending IPI...\n");
+ returnValue = mcall_send_ipi(arg0);
+ break;
+ case CLEAR_IPI:
+ printk(BIOS_DEBUG, "Clearing IPI...\n");
+ returnValue = mcall_clear_ipi();
+ break;
+ case SHUTDOWN:
+ printk(BIOS_DEBUG, "Shutting down...\n");
+ returnValue = mcall_shutdown();
+ break;
+ case SET_TIMER:
+ printk(BIOS_DEBUG, "Setting timer...\n");
+ returnValue = mcall_set_timer(arg0);
+ break;
+ case 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 system 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);
+ asm volatile("j supervisor_call_return");
+}
+
+void trap_handler(trapframe *tf) {
+ write_csr(mscratch, tf);
+ int cause = 0;
+ void* epc = 0;
+ void* badAddr = 0;
+
+ // extract cause
+ asm("csrr t0, mcause");
+ asm("move %0, t0" : "=r"(cause));
+
+ // extract faulting Instruction pc
+ epc = (void*) tf->epc;
+
+ // extract bad address
+ asm("csrr t0, mbadaddr");
+ asm("move %0, t0" : "=r"(badAddr));
+
+ switch(cause) {
+ case 0:
+ printk(BIOS_DEBUG, "Trap: Instruction address misaligned\n");
+ break;
+ case 1:
+ printk(BIOS_DEBUG, "Trap: Instruction access fault\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Address: %p\n", badAddr);
+ break;
+ case 2:
+ printk(BIOS_DEBUG, "Trap: Illegal instruction\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Address: %p\n", badAddr);
+ break;
+ case 3:
+ printk(BIOS_DEBUG, "Trap: Breakpoint\n");
+ break;
+ case 4:
+ printk(BIOS_DEBUG, "Trap: Load address misaligned\n");
+ //handleMisalignedLoad(tf);
+ break;
+ case 5:
+ printk(BIOS_DEBUG, "Trap: Load access fault\n");
+ break;
+ case 6:
+ printk(BIOS_DEBUG, "Trap: Store address misaligned\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Store Address: %p\n", badAddr);
+ handle_misaligned_store(tf);
+ break;
+ case 7:
+ printk(BIOS_DEBUG, "Trap: Store access fault\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Store Address: %p\n", badAddr);
+ break;
+ case 8:
+ printk(BIOS_DEBUG, "Trap: Environment call from U-mode\n");
+ break;
+ case 9:
+ // Don't print so we make console putchar calls look the way they should
+ // printk(BIOS_DEBUG, "Trap: Environment call from S-mode\n");
+ handle_supervisor_call(tf);
+ break;
+ case 10:
+ printk(BIOS_DEBUG, "Trap: Environment call from H-mode\n");
+ break;
+ case 11:
+ printk(BIOS_DEBUG, "Trap: Environment call from M-mode\n");
+ break;
+ default:
+ printk(BIOS_DEBUG, "Trap: Unknown cause\n");
+ break;
+ }
+ printk(BIOS_DEBUG, "Stored ra: %p\n", (void*) tf->gpr[1]);
+ printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
+ printk(BIOS_DEBUG, "looping...\n");
+ while(1);
+}
+
+void handle_misaligned_store(trapframe *tf) {
+ printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);
+ printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
+ insn_t faultingInstruction = 0;
+ uintptr_t faultingInstructionAddr = tf->epc;
+ asm("move t0, %0" : /* No outputs */ : "r"(faultingInstructionAddr));
+ asm("lw t0, 0(t0)");
+ asm("move %0, t0" : "=r"(faultingInstruction));
+ printk(BIOS_DEBUG, "Faulting instruction: 0x%x\n", faultingInstruction);
+ insn_t widthMask = 0x7000;
+ insn_t memWidth = (faultingInstruction & widthMask) >> 12;
+ insn_t srcMask = 0x1F00000;
+ insn_t srcRegister = (faultingInstruction & srcMask) >> 20;
+ printk(BIOS_DEBUG, "Width: 0x%x\n", memWidth);
+ if (memWidth == 3) {
+ // store double, handle the issue
+ void* badAddress = (void*) tf->badvaddr;
+ long valueToStore = tf->gpr[srcRegister];
+ memcpy(badAddress, &valueToStore, 8);
+ } else {
+ // panic, this should not have happened
+ printk(BIOS_DEBUG, "Code should not reach this path, misaligned on a non-64 bit store/load\n");
+ while(1);
+ }
+
+ // return to where we came from
+ write_csr(mepc, read_csr(mepc) + 4);
+ asm volatile("j machine_call_return");
+}
diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S
index 08061eb..9701aaf 100644
--- a/src/arch/riscv/trap_util.S
+++ b/src/arch/riscv/trap_util.S
@@ -121,7 +121,7 @@ supervisor_trap_entry:
trap_entry:
csrw mscratch, sp
1:addi sp,sp,-320
- save_tf_
+ save_tf
move a0,sp
jal trap_handler
.global supervisor_call_return
diff --git a/src/mainboard/emulation/spike-riscv/spike_util.c b/src/mainboard/emulation/spike-riscv/spike_util.c
index b34ff4a..9edc62d 100644
--- a/src/mainboard/emulation/spike-riscv/spike_util.c
+++ b/src/mainboard/emulation/spike-riscv/spike_util.c
@@ -1,4 +1,140 @@
+/*
+ * Copyright (c) 2013, The Regents of the University of California (Regents).
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Regents nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
#include <spike_util.h>
+#include <arch/errno.h>
+#include <atomic.h>
+#include <string.h>
+#include <console/console.h>
+
+uintptr_t translate_address(uintptr_t vAddr) {
+ // TODO: implement the page table translation algorithm
+ //uintptr_t pageTableRoot = read_csr(sptbr);
+ uintptr_t physAddrMask = 0xfffffff;
+ uintptr_t translationResult = vAddr & physAddrMask;
+ printk(BIOS_DEBUG, "Translated virtual address 0x%llx to physical address 0x%llx\n", vAddr, translationResult);
+ return translationResult;
+}
+
+uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p)
+{
+ 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;
+ return 0;
+ }
+
+ return -1;
+}
+
+uintptr_t mcall_send_ipi(uintptr_t recipient)
+{
+ //if (recipient >= num_harts)
+ //return -1;
+
+ if (atomic_swap(&OTHER_HLS(recipient)->ipi_pending, 1) == 0) {
+ mb();
+ write_csr(send_ipi, recipient);
+ }
+
+ 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);
+ mb();
+ }
+
+ return atomic_swap(&HLS()->ipi_pending, 0);
+}
+
+uintptr_t mcall_shutdown(void)
+{
+ while (1) write_csr(mtohost, 1);
+ return 0;
+}
+
+uintptr_t mcall_set_timer(unsigned long long when)
+{
+ write_csr(mtimecmp, when);
+ clear_csr(mip, MIP_STIP);
+ set_csr(mie, MIP_MTIP);
+ return 0;
+}
+
+uintptr_t mcall_dev_req(sbi_device_message *m)
+{
+ if ((m->dev > 0xFFU) | (m->cmd > 0xFFU) | (m->data > 0x0000FFFFFFFFFFFFU)) return -EINVAL;
+
+ while (swap_csr(mtohost, TOHOST_CMD(m->dev, m->cmd, m->data)) != 0);
+
+ m->sbi_private_data = (uintptr_t)HLS()->device_request_queue_head;
+ HLS()->device_request_queue_head = m;
+ HLS()->device_request_queue_size++;
+
+ return 0;
+}
+
+uintptr_t mcall_dev_resp(void)
+{
+ htif_interrupt(0, 0);
+
+ sbi_device_message* m = HLS()->device_response_queue_head;
+ if (m) {
+ //printm("resp %p\n", m);
+ sbi_device_message* next = (void*)atomic_read(&m->sbi_private_data);
+ HLS()->device_response_queue_head = next;
+ if (!next) {
+ HLS()->device_response_queue_tail = 0;
+
+ // only clear SSIP if no other events are pending
+ clear_csr(mip, MIP_SSIP);
+ mb();
+ if (HLS()->ipi_pending) set_csr(mip, MIP_SSIP);
+ }
+ }
+ return (uintptr_t)m;
+}
+
+uintptr_t mcall_hart_id(void)
+{
+ return HLS()->hart_id;
+}
+
+void hls_init(uint32_t hart_id)
+{
+ memset(HLS(), 0, sizeof(*HLS()));
+ HLS()->hart_id = hart_id;
+}
uintptr_t htif_interrupt(uintptr_t mcause, uintptr_t* regs) {
uintptr_t fromhost = swap_csr(mfromhost, 0);
Thaminda Edirisooriya (thaminda(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11369
-gerrit
commit 587dd02af82b3ce005086a23ee3891da3023a4eb
Author: Thaminda Edirisooriya <thaminda(a)google.com>
Date: Wed Aug 26 15:28:04 2015 -0700
riscv-virtual-memory: Add virtual memory setup
Execution in supervisor level code in RISCV requires early setup of
virtual memory. Add initialization calls in
src/arch/riscv/virtual_memory.c to implement the required page table
setup, and helper functions to use when jumping to the payload correctly
in riscv.
Change-Id: I46e080e0ee8dc13277d567dcd4bf0f61a4507b76
Signed-off-by: Thaminda Edirisooriya <thaminda(a)google.com>
---
src/arch/riscv/include/vm.h | 74 +++++++++++++++++++++
src/arch/riscv/virtual_memory.c | 142 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 216 insertions(+)
diff --git a/src/arch/riscv/include/vm.h b/src/arch/riscv/include/vm.h
new file mode 100644
index 0000000..f9ffc40
--- /dev/null
+++ b/src/arch/riscv/include/vm.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2013, The Regents of the University of California (Regents).
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Regents nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _VM_H
+#define _VM_H
+
+#include <string.h>
+#include <stdint.h>
+
+#define SUPERPAGE_SIZE ((uintptr_t)(RISCV_PGSIZE << RISCV_PGLEVEL_BITS))
+#define VM_CHOICE VM_SV39
+#define VA_BITS 39
+#define MEGAPAGE_SIZE (SUPERPAGE_SIZE << RISCV_PGLEVEL_BITS)
+
+#define PROT_READ 1
+#define PROT_WRITE 2
+#define PROT_EXEC 4
+
+#define MAP_PRIVATE 0x2
+#define MAP_FIXED 0x10
+#define MAP_ANONYMOUS 0x20
+#define MAP_POPULATE 0x8000
+#define MREMAP_FIXED 0x2
+
+#define EXTRACT_FIELD(val, which) (((val) & (which)) / ((which) & ~((which)-1)))
+#define INSERT_FIELD(val, which, fieldval) (((val) & ~(which)) | ((fieldval) * ((which) & ~((which)-1))))
+
+#define supervisor_paddr_valid(start, length) \
+ ((uintptr_t)(start) >= current.first_user_vaddr + current.bias \
+ && (uintptr_t)(start) + (length) < mem_size \
+ && (uintptr_t)(start) + (length) >= (uintptr_t)(start))
+
+typedef uintptr_t pte_t;
+extern pte_t* root_page_table;
+
+void enter_supervisor(void);
+void initVirtualMemory(void);
+
+size_t pte_ppn(pte_t pte);
+pte_t ptd_create(uintptr_t ppn);
+pte_t pte_create(uintptr_t ppn, int prot, int user);
+
+void walk_page_table(void);
+
+void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTableStart);
+void mstatus_init(void); // need to setup mstatus so we know we have virtual memory
+
+void flush_tlb(void);
+
+#endif
diff --git a/src/arch/riscv/virtual_memory.c b/src/arch/riscv/virtual_memory.c
new file mode 100644
index 0000000..78405dd
--- /dev/null
+++ b/src/arch/riscv/virtual_memory.c
@@ -0,0 +1,142 @@
+/*
+ * Early initialization code for riscv virtual memory
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <vm.h>
+#include <arch/encoding.h>
+#include <atomic.h>
+#include <stdint.h>
+#include <console/console.h>
+
+pte_t* root_page_table;
+
+void walk_page_table(void) {
+ // TODO: implement a full walk to make sure memory was set up
+ //const size_t pte_per_page = RISCV_PGSIZE/sizeof(void*);
+ pte_t* t = root_page_table;
+ printk(BIOS_DEBUG, "root_page_table: %p\n", t);
+}
+
+void enter_supervisor(void) {
+ // enter supervisor mode
+ asm volatile("la t0, 1f; csrw mepc, t0; eret; 1:" ::: "t0");
+}
+
+void flush_tlb(void)
+{
+ asm volatile("sfence.vm");
+}
+
+size_t pte_ppn(pte_t pte)
+{
+ return pte >> PTE_PPN_SHIFT;
+}
+
+pte_t ptd_create(uintptr_t ppn)
+{
+ return (ppn << PTE_PPN_SHIFT) | PTE_V | PTE_TYPE_TABLE;
+}
+
+pte_t pte_create(uintptr_t ppn, int prot, int user)
+{
+ pte_t pte = (ppn << PTE_PPN_SHIFT) | PTE_V;
+ if (prot & PROT_WRITE) pte |= PTE_TYPE_URW_SRW;
+ if (prot & PROT_EXEC) pte |= PTE_TYPE_URX_SRX;
+ if (!user) pte |= PTE_TYPE_SR;
+ return pte;
+}
+
+void init_vm(uintptr_t virtMemStart, uintptr_t physMemStart, uintptr_t pageTableStart) {
+ pte_t* sbi_pt = (pte_t*) pageTableStart;
+ memset(sbi_pt, 0, RISCV_PGSIZE);
+ // need to leave room for sbi page
+ uintptr_t memorySize = 0x7F000000; // 0xFFF... - 0xFFFFFFFF81000000 - RISCV_PGSIZE
+
+ // middle page table
+ pte_t* middle_pt = (void*)sbi_pt + RISCV_PGSIZE;
+ size_t num_middle_pts = 2; // 3 level page table, 39 bit virtual address space for now
+
+ // root page table
+ pte_t* root_pt = (void*)middle_pt + num_middle_pts * RISCV_PGSIZE;
+ memset(middle_pt, 0, (num_middle_pts + 1) * RISCV_PGSIZE); // 0's out middle_pt and root_pt
+ for (size_t i = 0; i < num_middle_pts; i++)
+ root_pt[(1<<RISCV_PGLEVEL_BITS)-num_middle_pts+i] = ptd_create(((uintptr_t)middle_pt >> RISCV_PGSHIFT) + i);
+
+ // fill the middle page table
+ for (uintptr_t vaddr = virtMemStart, paddr = physMemStart; paddr < memorySize; vaddr += SUPERPAGE_SIZE, paddr += SUPERPAGE_SIZE) {
+ int l2_shift = RISCV_PGLEVEL_BITS + RISCV_PGSHIFT;
+ size_t l2_idx = (virtMemStart >> l2_shift) & ((1 << RISCV_PGLEVEL_BITS)-1);
+ l2_idx += ((vaddr - virtMemStart) >> l2_shift);
+ middle_pt[l2_idx] = pte_create(paddr >> RISCV_PGSHIFT, PROT_READ|PROT_WRITE|PROT_EXEC, 0);
+ }
+
+ // 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 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, PROT_READ|PROT_EXEC, 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);
+
+ mb();
+ root_page_table = root_pt;
+ write_csr(sptbr, root_pt);
+}
+
+void initVirtualMemory(void) {
+ printk(BIOS_DEBUG, "Initializing virtual memory...\n");
+ uintptr_t physicalStart = 0x1000000; // TODO: Figure out how to grab this from cbfs
+ uintptr_t virtualStart = 0xffffffff81000000;
+ uintptr_t pageTableStart = 0x1f0000;
+ init_vm(virtualStart, physicalStart, pageTableStart);
+ mb();
+ printk(BIOS_DEBUG, "Finished initializing virtual memory, starting walk...\n");
+ walk_page_table();
+}
+
+void mstatus_init(void)
+{
+ // supervisor support is required
+
+ uintptr_t ms = 0;
+ ms = INSERT_FIELD(ms, MSTATUS_PRV, PRV_M);
+ ms = INSERT_FIELD(ms, MSTATUS_PRV1, PRV_S);
+ ms = INSERT_FIELD(ms, MSTATUS_PRV2, PRV_U);
+ ms = INSERT_FIELD(ms, MSTATUS_IE2, 1);
+ ms = INSERT_FIELD(ms, MSTATUS_VM, VM_CHOICE);
+ ms = INSERT_FIELD(ms, MSTATUS_FS, 3);
+ ms = INSERT_FIELD(ms, MSTATUS_XS, 3);
+ write_csr(mstatus, ms);
+ ms = read_csr(mstatus);
+
+ if (EXTRACT_FIELD(ms, MSTATUS_VM) != VM_CHOICE) {
+ printk(BIOS_DEBUG, "we don't have virtual memory...\n");
+ } else {
+ printk(BIOS_DEBUG, "-----------------------------\n");
+ printk(BIOS_DEBUG, "virtual memory status enabled\n");
+ printk(BIOS_DEBUG, "-----------------------------\n");
+ }
+
+ clear_csr(mip, MIP_MSIP);
+ set_csr(mie, MIP_MSIP);
+}
Thaminda Edirisooriya (thaminda(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11368
-gerrit
commit 4011598cd886f2ca8d840f6031b1d4f0901b34db
Author: Thaminda Edirisooriya <thaminda(a)google.com>
Date: Wed Aug 26 14:54:31 2015 -0700
riscv-trap-handling: Add implementation for trap calls in riscv
RISCV requires the bios/bootloader to set up an interface by which it
can get information about memory, talk to host devices, etc. Put
implementation for spike in
src/mainboard/emulation/spike-riscv/spike_util.c, and
src/arch/riscv/trap_handler.c
Change-Id: Ie1d5f361595e48fa6cc1fac25485ad623ecdc717
Signed-off-by: Thaminda Edirisooriya <thaminda(a)google.com>
---
src/arch/riscv/Makefile.inc | 2 +
src/arch/riscv/include/arch/errno.h | 66 ++++++++
src/arch/riscv/include/arch/exception.h | 22 +++
src/arch/riscv/include/spike_util.h | 17 ++
src/arch/riscv/trap_handler.c | 193 +++++++++++++++++++++++
src/arch/riscv/trap_util.S | 2 +-
src/mainboard/emulation/spike-riscv/spike_util.c | 139 ++++++++++++++++
7 files changed, 440 insertions(+), 1 deletion(-)
diff --git a/src/arch/riscv/Makefile.inc b/src/arch/riscv/Makefile.inc
index 0f3eb0f..c7a2c16 100644
--- a/src/arch/riscv/Makefile.inc
+++ b/src/arch/riscv/Makefile.inc
@@ -29,6 +29,8 @@ riscv_asm_flags =
ifeq ($(CONFIG_ARCH_BOOTBLOCK_RISCV),y)
bootblock-y = bootblock.S stages.c
+bootblock-y += trap_util.S
+bootblock-y += trap_handler.c
bootblock-y += boot.c
bootblock-y += rom_media.c
bootblock-y += \
diff --git a/src/arch/riscv/include/arch/errno.h b/src/arch/riscv/include/arch/errno.h
new file mode 100644
index 0000000..6f80ee5
--- /dev/null
+++ b/src/arch/riscv/include/arch/errno.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2013, The Regents of the University of California (Regents).
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Regents nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef _RISCV_ERRNO_BASE_H
+#define _RISCV_ERRNO_BASE_H
+
+#define EPERM 1 /* Operation not permitted */
+#define ENOENT 2 /* No such file or directory */
+#define ESRCH 3 /* No such process */
+#define EINTR 4 /* Interrupted system call */
+#define EIO 5 /* I/O error */
+#define ENXIO 6 /* No such device or address */
+#define E2BIG 7 /* Argument list too long */
+#define ENOEXEC 8 /* Exec format error */
+#define EBADF 9 /* Bad file number */
+#define ECHILD 10 /* No child processes */
+#define EAGAIN 11 /* Try again */
+#define ENOMEM 12 /* Out of memory */
+#define EACCES 13 /* Permission denied */
+#define EFAULT 14 /* Bad address */
+#define ENOTBLK 15 /* Block device required */
+#define EBUSY 16 /* Device or resource busy */
+#define EEXIST 17 /* File exists */
+#define EXDEV 18 /* Cross-device link */
+#define ENODEV 19 /* No such device */
+#define ENOTDIR 20 /* Not a directory */
+#define EISDIR 21 /* Is a directory */
+#define EINVAL 22 /* Invalid argument */
+#define ENFILE 23 /* File table overflow */
+#define EMFILE 24 /* Too many open files */
+#define ENOTTY 25 /* Not a typewriter */
+#define ETXTBSY 26 /* Text file busy */
+#define EFBIG 27 /* File too large */
+#define ENOSPC 28 /* No space left on device */
+#define ESPIPE 29 /* Illegal seek */
+#define EROFS 30 /* Read-only file system */
+#define EMLINK 31 /* Too many links */
+#define EPIPE 32 /* Broken pipe */
+#define EDOM 33 /* Math argument out of domain of func */
+#define ERANGE 34 /* Math result not representable */
+
+#endif
diff --git a/src/arch/riscv/include/arch/exception.h b/src/arch/riscv/include/arch/exception.h
index befab1f..4318cba 100644
--- a/src/arch/riscv/include/arch/exception.h
+++ b/src/arch/riscv/include/arch/exception.h
@@ -32,8 +32,30 @@
#include <stdint.h>
+typedef struct
+{
+ uintptr_t gpr[32];
+ uintptr_t status;
+ uintptr_t epc;
+ uintptr_t badvaddr;
+ uintptr_t cause;
+ uintptr_t insn;
+} trapframe;
+
+typedef uint32_t insn_t;
+
+typedef struct {
+ uintptr_t error;
+ insn_t insn;
+} insn_fetch_t;
+
static inline void exception_init(void)
{
}
+void trap_handler(trapframe* tf);
+void handle_supervisor_call(trapframe* tf);
+//void handleMisalignedLoad(trapframe *tf);
+void handle_misaligned_store(trapframe *tf);
+
#endif
diff --git a/src/arch/riscv/include/spike_util.h b/src/arch/riscv/include/spike_util.h
index a9d14cc..e9c0300 100644
--- a/src/arch/riscv/include/spike_util.h
+++ b/src/arch/riscv/include/spike_util.h
@@ -40,6 +40,12 @@
#define FROMHOST_DATA(fromhost_value) ((uint64_t)(fromhost_value) << 16 >> 16)
typedef struct {
+ unsigned long base;
+ unsigned long size;
+ unsigned long node_id;
+} memory_block_info;
+
+typedef struct {
unsigned long dev;
unsigned long cmd;
unsigned long data;
@@ -63,11 +69,22 @@ typedef struct {
// hart-local storage, at top of stack
#define HLS() ((hls_t*)(MACHINE_STACK_TOP() - HLS_SIZE))
+#define OTHER_HLS(id) ((hls_t*)((void*)HLS() + RISCV_PGSIZE * ((id) - HLS()->hart_id)))
#define MACHINE_STACK_SIZE RISCV_PGSIZE
+uintptr_t translate_address(uintptr_t vAddr);
+uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p);
+uintptr_t mcall_hart_id(void);
uintptr_t htif_interrupt(uintptr_t mcause, uintptr_t* regs);
uintptr_t mcall_console_putchar(uint8_t ch);
void testPrint(void);
+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
diff --git a/src/arch/riscv/trap_handler.c b/src/arch/riscv/trap_handler.c
new file mode 100644
index 0000000..d4c9b87
--- /dev/null
+++ b/src/arch/riscv/trap_handler.c
@@ -0,0 +1,193 @@
+/*
+ * Early initialization code for riscv
+ *
+ * Copyright 2015 Google Inc.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc.
+ */
+
+#include <console/console.h>
+#include <arch/exception.h>
+#include <spike_util.h>
+#include <string.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 returnValue;
+ switch(call) {
+ case HART_ID:
+ printk(BIOS_DEBUG, "Getting hart id...\n");
+ returnValue = mcall_hart_id();
+ break;
+ case CONSOLE_PUT:
+ returnValue = mcall_console_putchar(arg0);
+ break;
+ case SEND_DEVICE_REQUEST:
+ printk(BIOS_DEBUG, "Sending device request...\n");
+ returnValue = mcall_dev_req((sbi_device_message*) arg0);
+ break;
+ case RECEIVE_DEVICE_RESPONSE:
+ printk(BIOS_DEBUG, "Getting device response...\n");
+ returnValue = mcall_dev_resp();
+ break;
+ case SEND_IPI:
+ printk(BIOS_DEBUG, "Sending IPI...\n");
+ returnValue = mcall_send_ipi(arg0);
+ break;
+ case CLEAR_IPI:
+ printk(BIOS_DEBUG, "Clearing IPI...\n");
+ returnValue = mcall_clear_ipi();
+ break;
+ case SHUTDOWN:
+ printk(BIOS_DEBUG, "Shutting down...\n");
+ returnValue = mcall_shutdown();
+ break;
+ case SET_TIMER:
+ printk(BIOS_DEBUG, "Setting timer...\n");
+ returnValue = mcall_set_timer(arg0);
+ break;
+ case 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 system 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);
+ asm volatile("j supervisor_call_return");
+}
+
+void trap_handler(trapframe *tf) {
+ write_csr(mscratch, tf);
+ int cause = 0;
+ void* epc = 0;
+ void* badAddr = 0;
+
+ // extract cause
+ asm("csrr t0, mcause");
+ asm("move %0, t0" : "=r"(cause));
+
+ // extract faulting Instruction pc
+ epc = (void*) tf->epc;
+
+ // extract bad address
+ asm("csrr t0, mbadaddr");
+ asm("move %0, t0" : "=r"(badAddr));
+
+ switch(cause) {
+ case 0:
+ printk(BIOS_DEBUG, "Trap: Instruction address misaligned\n");
+ break;
+ case 1:
+ printk(BIOS_DEBUG, "Trap: Instruction access fault\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Address: %p\n", badAddr);
+ break;
+ case 2:
+ printk(BIOS_DEBUG, "Trap: Illegal instruction\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Address: %p\n", badAddr);
+ break;
+ case 3:
+ printk(BIOS_DEBUG, "Trap: Breakpoint\n");
+ break;
+ case 4:
+ printk(BIOS_DEBUG, "Trap: Load address misaligned\n");
+ //handleMisalignedLoad(tf);
+ break;
+ case 5:
+ printk(BIOS_DEBUG, "Trap: Load access fault\n");
+ break;
+ case 6:
+ printk(BIOS_DEBUG, "Trap: Store address misaligned\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Store Address: %p\n", badAddr);
+ handle_misaligned_store(tf);
+ break;
+ case 7:
+ printk(BIOS_DEBUG, "Trap: Store access fault\n");
+ printk(BIOS_DEBUG, "Bad instruction pc: %p\n", epc);
+ printk(BIOS_DEBUG, "Store Address: %p\n", badAddr);
+ break;
+ case 8:
+ printk(BIOS_DEBUG, "Trap: Environment call from U-mode\n");
+ break;
+ case 9:
+ // Don't print so we make console putchar calls look the way they should
+ // printk(BIOS_DEBUG, "Trap: Environment call from S-mode\n");
+ handle_supervisor_call(tf);
+ break;
+ case 10:
+ printk(BIOS_DEBUG, "Trap: Environment call from H-mode\n");
+ break;
+ case 11:
+ printk(BIOS_DEBUG, "Trap: Environment call from M-mode\n");
+ break;
+ default:
+ printk(BIOS_DEBUG, "Trap: Unknown cause\n");
+ break;
+ }
+ printk(BIOS_DEBUG, "Stored ra: %p\n", (void*) tf->gpr[1]);
+ printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
+ printk(BIOS_DEBUG, "looping...\n");
+ while(1);
+}
+
+void handle_misaligned_store(trapframe *tf) {
+ printk(BIOS_DEBUG, "Trapframe ptr: %p\n", tf);
+ printk(BIOS_DEBUG, "Stored sp: %p\n", (void*) tf->gpr[2]);
+ insn_t faultingInstruction = 0;
+ uintptr_t faultingInstructionAddr = tf->epc;
+ asm("move t0, %0" : /* No outputs */ : "r"(faultingInstructionAddr));
+ asm("lw t0, 0(t0)");
+ asm("move %0, t0" : "=r"(faultingInstruction));
+ printk(BIOS_DEBUG, "Faulting instruction: 0x%x\n", faultingInstruction);
+ insn_t widthMask = 0x7000;
+ insn_t memWidth = (faultingInstruction & widthMask) >> 12;
+ insn_t srcMask = 0x1F00000;
+ insn_t srcRegister = (faultingInstruction & srcMask) >> 20;
+ printk(BIOS_DEBUG, "Width: 0x%x\n", memWidth);
+ if (memWidth == 3) {
+ // store double, handle the issue
+ void* badAddress = (void*) tf->badvaddr;
+ long valueToStore = tf->gpr[srcRegister];
+ memcpy(badAddress, &valueToStore, 8);
+ } else {
+ // panic, this should not have happened
+ printk(BIOS_DEBUG, "Code should not reach this path, misaligned on a non-64 bit store/load\n");
+ while(1);
+ }
+
+ // return to where we came from
+ write_csr(mepc, read_csr(mepc) + 4);
+ asm volatile("j machine_call_return");
+}
diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S
index 08061eb..9701aaf 100644
--- a/src/arch/riscv/trap_util.S
+++ b/src/arch/riscv/trap_util.S
@@ -121,7 +121,7 @@ supervisor_trap_entry:
trap_entry:
csrw mscratch, sp
1:addi sp,sp,-320
- save_tf_
+ save_tf
move a0,sp
jal trap_handler
.global supervisor_call_return
diff --git a/src/mainboard/emulation/spike-riscv/spike_util.c b/src/mainboard/emulation/spike-riscv/spike_util.c
index b34ff4a..1ee8b77 100644
--- a/src/mainboard/emulation/spike-riscv/spike_util.c
+++ b/src/mainboard/emulation/spike-riscv/spike_util.c
@@ -1,4 +1,143 @@
+/*
+ * Copyright (c) 2013, The Regents of the University of California (Regents).
+ * All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Regents nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+ * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
+ * OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
+ * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
+ * HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
#include <spike_util.h>
+#include <arch/errno.h>
+#include <atomic.h>
+#include <string.h>
+#include <console/console.h>
+
+uintptr_t translate_address(uintptr_t vAddr) {
+ // TODO: implement the page table translation algorithm
+ //uintptr_t pageTableRoot = read_csr(sptbr);
+ uintptr_t physAddrMask = 0xfffffff;
+ uintptr_t translationResult = vAddr & physAddrMask;
+ printk(BIOS_DEBUG, "Translated virtual address 0x%llx to physical address 0x%llx\n", vAddr, translationResult);
+ return translationResult;
+}
+
+uintptr_t mcall_query_memory(uintptr_t id, memory_block_info *p)
+{
+ 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;
+ return 0;
+ }
+
+ return -1;
+}
+
+uintptr_t mcall_send_ipi(uintptr_t recipient)
+{
+ //if (recipient >= num_harts)
+ //return -1;
+
+ if (atomic_swap(&OTHER_HLS(recipient)->ipi_pending, 1) == 0) {
+ mb();
+ write_csr(send_ipi, recipient);
+ }
+
+ 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);
+ mb();
+ }
+
+ return atomic_swap(&HLS()->ipi_pending, 0);
+}
+
+uintptr_t mcall_shutdown(void)
+{
+ while (1) write_csr(mtohost, 1);
+ return 0;
+}
+
+uintptr_t mcall_set_timer(unsigned long long when)
+{
+ write_csr(mtimecmp, when);
+ #ifndef __riscv64
+ write_csr(mtimecmph, when >> 32);
+ #endif
+ clear_csr(mip, MIP_STIP);
+ set_csr(mie, MIP_MTIP);
+ return 0;
+}
+
+uintptr_t mcall_dev_req(sbi_device_message *m)
+{
+ if ((m->dev > 0xFFU) | (m->cmd > 0xFFU) | (m->data > 0x0000FFFFFFFFFFFFU)) return -EINVAL;
+
+ while (swap_csr(mtohost, TOHOST_CMD(m->dev, m->cmd, m->data)) != 0);
+
+ m->sbi_private_data = (uintptr_t)HLS()->device_request_queue_head;
+ HLS()->device_request_queue_head = m;
+ HLS()->device_request_queue_size++;
+
+ return 0;
+}
+
+uintptr_t mcall_dev_resp(void)
+{
+ htif_interrupt(0, 0);
+
+ sbi_device_message* m = HLS()->device_response_queue_head;
+ if (m) {
+ //printm("resp %p\n", m);
+ sbi_device_message* next = (void*)atomic_read(&m->sbi_private_data);
+ HLS()->device_response_queue_head = next;
+ if (!next) {
+ HLS()->device_response_queue_tail = 0;
+
+ // only clear SSIP if no other events are pending
+ clear_csr(mip, MIP_SSIP);
+ mb();
+ if (HLS()->ipi_pending) set_csr(mip, MIP_SSIP);
+ }
+ }
+ return (uintptr_t)m;
+}
+
+uintptr_t mcall_hart_id(void)
+{
+ return HLS()->hart_id;
+}
+
+void hls_init(uint32_t hart_id)
+{
+ memset(HLS(), 0, sizeof(*HLS()));
+ HLS()->hart_id = hart_id;
+}
uintptr_t htif_interrupt(uintptr_t mcause, uintptr_t* regs) {
uintptr_t fromhost = swap_csr(mfromhost, 0);
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11404
-gerrit
commit ac8b6c51132c4bf289e6ee026adeea5747c3c16b
Author: Julius Werner <jwerner(a)chromium.org>
Date: Mon Aug 17 18:47:18 2015 -0700
libpayload: usb: dwc2: Always return 'size' transferred bytes for OUT
Seems like our transferred bytes calculation for OUT transfers that span
more than one packet had been wrong, and we just got lucky that we never
noticed it before. The HCTSIZ.xfersize register field we're reading only
counts bytes transferred by the last packet we sent.
OUT endpoints cannot have short transfers -- every transfer should
either finish all bytes we wanted to send or end in a proper error
condition. Therefore, in the absence of an error we can just conclude
that all input bytes have been transferred.
BRANCH=veyron
BUG=chrome-os-partner:35525
TEST=SMSC95xx netboot on Jerry now works.
Change-Id: I57349e697c428df6b56e2f6f62e87652ef1e7a94
Signed-off-by: Patrick Georgi <patrick(a)georgi-clan.de>
Original-Commit-Id: 0abee13b6d89dec12c6fff581ece1836393c7703
Original-Change-Id: Id0a127e6919f5786ba05218277705dda1067b8c3
Original-Signed-off-by: Julius Werner <jwerner(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/293956
Original-Reviewed-by: yunzhi li <lyz(a)rock-chips.com>
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
---
payloads/libpayload/drivers/usb/dwc2.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/payloads/libpayload/drivers/usb/dwc2.c b/payloads/libpayload/drivers/usb/dwc2.c
index 9d19bc6..30e00fb 100644
--- a/payloads/libpayload/drivers/usb/dwc2.c
+++ b/payloads/libpayload/drivers/usb/dwc2.c
@@ -283,7 +283,7 @@ dwc2_do_xfer(endpoint_t *ep, int size, int pid, ep_dir_t dir,
if (ret >= 0) {
/* Calculate actual transferred length */
- transferred = (dir == EPDIR_IN) ? inpkt_length - ret : ret;
+ transferred = (dir == EPDIR_IN) ? inpkt_length - ret : size;
if (do_copy && (dir == EPDIR_IN))
memcpy(data_buf, aligned_buf, transferred);
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11400
-gerrit
commit 419b57e1c6a4ac51cb2b7c038b368cbded082e8d
Author: Alexandru M Stan <amstan(a)chromium.org>
Date: Thu Aug 20 11:45:26 2015 -0700
veyron_rialto: remove spurious GPIO assignments
GPIO(0, B, 3) and GPIO(7, C, 5) are not actually connected,
GPIO(0, B, 4) is named differently.
BUG=chrome-os-partner:43031
TEST=Rialto should still boot just fine, USB should still work
BRANCH=master
Change-Id: I11879385de6e9b57ac28bcae699333beb5a0d64c
Signed-off-by: Patrick Georgi <patrick(a)georgi-clan.de>
Original-Commit-Id: a66bf1fd73ff8d15d4ec1a8f3602465941285c32
Original-Change-Id: Ib7d2baa6ed1ab38db786eb4d5e77316ad72cbfd4
Original-Signed-off-by: Alexandru M Stan <amstan(a)chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/294713
Original-Reviewed-by: David Hendricks <dhendrix(a)chromium.org>
---
src/mainboard/google/veyron_rialto/mainboard.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/src/mainboard/google/veyron_rialto/mainboard.c b/src/mainboard/google/veyron_rialto/mainboard.c
index 4dba666..c2dde19 100644
--- a/src/mainboard/google/veyron_rialto/mainboard.c
+++ b/src/mainboard/google/veyron_rialto/mainboard.c
@@ -43,9 +43,7 @@
static void configure_usb(void)
{
- gpio_output(GPIO(0, B, 3), 1); /* HOST1_PWR_EN */
- gpio_output(GPIO(0, B, 4), 1); /* USBOTG_PWREN_H */
- gpio_output(GPIO(7, C, 5), 1); /* 5V_DRV */
+ gpio_output(GPIO(0, B, 4), 1); /* USB2_PWR_EN */
}
static void configure_emmc(void)
Patrick Georgi (pgeorgi(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/11401
-gerrit
commit cafe13fc7d358efb44249f99c203c629de304dd5
Author: Yen Lin <yelin(a)nvidia.com>
Date: Thu Aug 20 15:19:07 2015 -0700
t210: sdram_lp0: also save EmcBctSpare2 field
Need to save EmcBctSpare2 field to scratch register. Without it,
system may not resume from LP0 suspend.
BUG=chrome-os-partner:43797
BRANCH=none
TEST=able to suspend/resume >30 times on a known failed board
Signed-off-by: Patrick Georgi <patrick(a)georgi-clan.de>
Original-Commit-Id: 6d1623c4c791f79e097193dfbc4bc894ef63e230
Original-Change-Id: I53ebf8c4d4c7cd19827128a84fbd97a377d78ff7
Original-Signed-off-by: Yen Lin <yelin(a)nvidia.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/294765
Original-Reviewed-by: Furquan Shaikh <furquan(a)chromium.org>
Original-(cherry picked from commit ce38d902e889068d0068150c9352c2ecdb2f8815)
Original-Reviewed-on: https://chromium-review.googlesource.com/294864
Original-Commit-Queue: Furquan Shaikh <furquan(a)chromium.org>
Original-Trybot-Ready: Furquan Shaikh <furquan(a)chromium.org>
Original-Tested-by: Furquan Shaikh <furquan(a)chromium.org>
Change-Id: I2ff21afbe9278413033101877c2581df51913709
---
src/soc/nvidia/tegra210/sdram_lp0.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/soc/nvidia/tegra210/sdram_lp0.c b/src/soc/nvidia/tegra210/sdram_lp0.c
index f3f2af3..890c285 100644
--- a/src/soc/nvidia/tegra210/sdram_lp0.c
+++ b/src/soc/nvidia/tegra210/sdram_lp0.c
@@ -724,6 +724,7 @@ void sdram_lp0_save_params(const struct sdram_params *sdram)
s32(EmcBctSpare5, scratch42);
s32(EmcBctSpare4, scratch44);
s32(SwizzleRankByteEncode, scratch45);
+ s32(EmcBctSpare2, scratch46);
s32(EmcBctSpare1, scratch47);
s32(EmcBctSpare0, scratch48);
s32(EmcBctSpare9, scratch50);