diff options
author | Thaminda Edirisooriya <thaminda@google.com> | 2015-08-26 12:22:29 -0700 |
---|---|---|
committer | Ronald G. Minnich <rminnich@gmail.com> | 2015-08-26 23:50:45 +0000 |
commit | 31f0521a996791f842af94f0c561c18fd2aec2ba (patch) | |
tree | ee6e821d477aa2ae43a6c9106c088c35c190f71b /src/arch | |
parent | 5cd34e2f15e1bf562fa80f013995d77429ea784f (diff) | |
download | coreboot-31f0521a996791f842af94f0c561c18fd2aec2ba.tar.xz |
riscv-trap-handling: Add preliminary trap handling for riscv
RISCV requires a trap handler at the machine stage to deal with
misaligned loads/stores, as well as to deal with calls that a linux
payload will make in its setup. Put required assembly for jumping
into and out of a trap here to be set up by the bootblock in a later
commit.
Change-Id: Ibf6b18e477aaa1c415a31dbeffa50a2470a7ab2e
Signed-off-by: Thaminda Edirisooriya <thaminda@google.com>
Reviewed-on: http://review.coreboot.org/11367
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
Tested-by: build bot (Jenkins)
Diffstat (limited to 'src/arch')
-rw-r--r-- | src/arch/riscv/include/bits.h | 57 | ||||
-rw-r--r-- | src/arch/riscv/trap_util.S | 136 |
2 files changed, 193 insertions, 0 deletions
diff --git a/src/arch/riscv/include/bits.h b/src/arch/riscv/include/bits.h new file mode 100644 index 0000000000..f69c7ec0da --- /dev/null +++ b/src/arch/riscv/include/bits.h @@ -0,0 +1,57 @@ +/* + * 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 _BITS_H +#define _BITS_H + +#define CONST_POPCOUNT2(x) ((((x) >> 0) & 1) + (((x) >> 1) & 1)) +#define CONST_POPCOUNT4(x) (CONST_POPCOUNT2(x) + CONST_POPCOUNT2((x)>>2)) +#define CONST_POPCOUNT8(x) (CONST_POPCOUNT4(x) + CONST_POPCOUNT4((x)>>4)) +#define CONST_POPCOUNT16(x) (CONST_POPCOUNT8(x) + CONST_POPCOUNT8((x)>>8)) +#define CONST_POPCOUNT32(x) (CONST_POPCOUNT16(x) + CONST_POPCOUNT16((x)>>16)) +#define CONST_POPCOUNT64(x) (CONST_POPCOUNT32(x) + CONST_POPCOUNT32((x)>>32)) +#define CONST_POPCOUNT(x) CONST_POPCOUNT64(x) + +#define CONST_CTZ2(x) CONST_POPCOUNT2(((x) & -(x))-1) +#define CONST_CTZ4(x) CONST_POPCOUNT4(((x) & -(x))-1) +#define CONST_CTZ8(x) CONST_POPCOUNT8(((x) & -(x))-1) +#define CONST_CTZ16(x) CONST_POPCOUNT16(((x) & -(x))-1) +#define CONST_CTZ32(x) CONST_POPCOUNT32(((x) & -(x))-1) +#define CONST_CTZ64(x) CONST_POPCOUNT64(((x) & -(x))-1) +#define CONST_CTZ(x) CONST_CTZ64(x) + +#define STR(x) XSTR(x) +#define XSTR(x) #x + +# define SLL32 sllw +# define STORE sd +# define LOAD ld +# define LOG_REGBYTES 3 + +#define REGBYTES (1 << LOG_REGBYTES) + +#endif diff --git a/src/arch/riscv/trap_util.S b/src/arch/riscv/trap_util.S new file mode 100644 index 0000000000..08061eb537 --- /dev/null +++ b/src/arch/riscv/trap_util.S @@ -0,0 +1,136 @@ +/* + * 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 <bits.h> +.macro restore_regs + # restore x registers + LOAD x1,1*REGBYTES(a0) + LOAD x2,2*REGBYTES(a0) + LOAD x3,3*REGBYTES(a0) + LOAD x4,4*REGBYTES(a0) + LOAD x5,5*REGBYTES(a0) + LOAD x6,6*REGBYTES(a0) + LOAD x7,7*REGBYTES(a0) + LOAD x8,8*REGBYTES(a0) + LOAD x9,9*REGBYTES(a0) + LOAD x11,11*REGBYTES(a0) + LOAD x12,12*REGBYTES(a0) + LOAD x13,13*REGBYTES(a0) + LOAD x14,14*REGBYTES(a0) + LOAD x15,15*REGBYTES(a0) + LOAD x16,16*REGBYTES(a0) + LOAD x17,17*REGBYTES(a0) + LOAD x18,18*REGBYTES(a0) + LOAD x19,19*REGBYTES(a0) + LOAD x20,20*REGBYTES(a0) + LOAD x21,21*REGBYTES(a0) + LOAD x22,22*REGBYTES(a0) + LOAD x23,23*REGBYTES(a0) + LOAD x24,24*REGBYTES(a0) + LOAD x25,25*REGBYTES(a0) + LOAD x26,26*REGBYTES(a0) + LOAD x27,27*REGBYTES(a0) + LOAD x28,28*REGBYTES(a0) + LOAD x29,29*REGBYTES(a0) + LOAD x30,30*REGBYTES(a0) + LOAD x31,31*REGBYTES(a0) + # restore a0 last + LOAD x10,10*REGBYTES(a0) + + + .endm +.macro save_tf + # save gprs + STORE x1,1*REGBYTES(x2) + STORE x3,3*REGBYTES(x2) + STORE x4,4*REGBYTES(x2) + STORE x5,5*REGBYTES(x2) + STORE x6,6*REGBYTES(x2) + STORE x7,7*REGBYTES(x2) + STORE x8,8*REGBYTES(x2) + STORE x9,9*REGBYTES(x2) + STORE x10,10*REGBYTES(x2) + STORE x11,11*REGBYTES(x2) + STORE x12,12*REGBYTES(x2) + STORE x13,13*REGBYTES(x2) + STORE x14,14*REGBYTES(x2) + STORE x15,15*REGBYTES(x2) + STORE x16,16*REGBYTES(x2) + STORE x17,17*REGBYTES(x2) + STORE x18,18*REGBYTES(x2) + STORE x19,19*REGBYTES(x2) + STORE x20,20*REGBYTES(x2) + STORE x21,21*REGBYTES(x2) + STORE x22,22*REGBYTES(x2) + STORE x23,23*REGBYTES(x2) + STORE x24,24*REGBYTES(x2) + STORE x25,25*REGBYTES(x2) + STORE x26,26*REGBYTES(x2) + STORE x27,27*REGBYTES(x2) + STORE x28,28*REGBYTES(x2) + STORE x29,29*REGBYTES(x2) + STORE x30,30*REGBYTES(x2) + STORE x31,31*REGBYTES(x2) + + # get sr, epc, badvaddr, cause + csrrw t0,mscratch,x0 + csrr s0,mstatus + csrr t1,mepc + csrr t2,mbadaddr + csrr t3,mcause + STORE t0,2*REGBYTES(x2) + STORE s0,32*REGBYTES(x2) + STORE t1,33*REGBYTES(x2) + STORE t2,34*REGBYTES(x2) + STORE t3,35*REGBYTES(x2) + + # get faulting insn, if it wasn't a fetch-related trap + li x5,-1 + STORE x5,36*REGBYTES(x2) +1: + .endm + + .text + .global supervisor_trap_entry +supervisor_trap_entry: + csrw mscratch, sp + # load in the top of the machine stack + la sp, 0x80FFF0 + 1:addi sp,sp,-320 + save_tf + move a0,sp + jal trap_handler + .global trap_entry +trap_entry: + csrw mscratch, sp + 1:addi sp,sp,-320 + save_tf_ + move a0,sp + jal trap_handler + .global supervisor_call_return +supervisor_call_return: + csrr a0, mscratch + restore_regs + eret # go back into supervisor call + .global machine_call_return +machine_call_return: + csrr a0, mscratch + restore_regs + eret # go back into machine call |