Index: head/sys/riscv/include/frame.h
===================================================================
--- head/sys/riscv/include/frame.h (revision 342222)
+++ head/sys/riscv/include/frame.h (revision 342223)
@@ -1,80 +1,80 @@
/*-
* Copyright (c) 2015 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
*
* Portions of this software were developed by the University of Cambridge
* Computer Laboratory as part of the CTSRD Project, with support from the
* UK Higher Education Innovation Fund (HEIF).
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_FRAME_H_
#define _MACHINE_FRAME_H_
#ifndef LOCORE
#include
#include
/*
* NOTE: keep this structure in sync with struct reg and struct mcontext.
*/
struct trapframe {
uint64_t tf_ra;
uint64_t tf_sp;
uint64_t tf_gp;
uint64_t tf_tp;
uint64_t tf_t[7];
uint64_t tf_s[12];
uint64_t tf_a[8];
uint64_t tf_sepc;
uint64_t tf_sstatus;
- uint64_t tf_sbadaddr;
+ uint64_t tf_stval;
uint64_t tf_scause;
};
struct riscv_frame {
struct riscv_frame *f_frame;
u_long f_retaddr;
};
/*
* Signal frame. Pushed onto user stack before calling sigcode.
*/
struct sigframe {
siginfo_t sf_si; /* actual saved siginfo */
ucontext_t sf_uc; /* actual saved ucontext */
};
#endif /* !LOCORE */
/* Definitions for syscalls */
#define NARGREG 8 /* 8 args in regs */
#endif /* !_MACHINE_FRAME_H_ */
Index: head/sys/riscv/riscv/db_interface.c
===================================================================
--- head/sys/riscv/riscv/db_interface.c (revision 342222)
+++ head/sys/riscv/riscv/db_interface.c (revision 342223)
@@ -1,160 +1,160 @@
/*-
* Copyright (c) 2015 The FreeBSD Foundation
* All rights reserved.
*
* This software was developed by Semihalf under
* the sponsorship of the FreeBSD Foundation.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include
__FBSDID("$FreeBSD$");
#include
#include
#include
#include
#include
#ifdef KDB
#include
#endif
#include
#include
#include
#include
#include
#include
static int
db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
{
long *reg;
if (kdb_frame == NULL)
return (0);
reg = (long *)((uintptr_t)kdb_frame + (db_expr_t)vp->valuep);
if (op == DB_VAR_GET)
*valuep = *reg;
else
*reg = *valuep;
return (1);
}
#define DB_OFFSET(x) (db_expr_t *)offsetof(struct trapframe, x)
struct db_variable db_regs[] = {
{ "ra", DB_OFFSET(tf_ra), db_frame },
{ "sp", DB_OFFSET(tf_sp), db_frame },
{ "gp", DB_OFFSET(tf_gp), db_frame },
{ "tp", DB_OFFSET(tf_tp), db_frame },
{ "t0", DB_OFFSET(tf_t[0]), db_frame },
{ "t1", DB_OFFSET(tf_t[1]), db_frame },
{ "t2", DB_OFFSET(tf_t[2]), db_frame },
{ "t3", DB_OFFSET(tf_t[3]), db_frame },
{ "t4", DB_OFFSET(tf_t[4]), db_frame },
{ "t5", DB_OFFSET(tf_t[5]), db_frame },
{ "t6", DB_OFFSET(tf_t[6]), db_frame },
{ "s0", DB_OFFSET(tf_s[0]), db_frame },
{ "s1", DB_OFFSET(tf_s[1]), db_frame },
{ "s2", DB_OFFSET(tf_s[2]), db_frame },
{ "s3", DB_OFFSET(tf_s[3]), db_frame },
{ "s4", DB_OFFSET(tf_s[4]), db_frame },
{ "s5", DB_OFFSET(tf_s[5]), db_frame },
{ "s6", DB_OFFSET(tf_s[6]), db_frame },
{ "s7", DB_OFFSET(tf_s[7]), db_frame },
{ "s8", DB_OFFSET(tf_s[8]), db_frame },
{ "s9", DB_OFFSET(tf_s[9]), db_frame },
{ "s10", DB_OFFSET(tf_s[10]), db_frame },
{ "s11", DB_OFFSET(tf_s[11]), db_frame },
{ "a0", DB_OFFSET(tf_a[0]), db_frame },
{ "a1", DB_OFFSET(tf_a[1]), db_frame },
{ "a2", DB_OFFSET(tf_a[2]), db_frame },
{ "a3", DB_OFFSET(tf_a[3]), db_frame },
{ "a4", DB_OFFSET(tf_a[4]), db_frame },
{ "a5", DB_OFFSET(tf_a[5]), db_frame },
{ "a6", DB_OFFSET(tf_a[6]), db_frame },
{ "a7", DB_OFFSET(tf_a[7]), db_frame },
{ "sepc", DB_OFFSET(tf_sepc), db_frame },
{ "sstatus", DB_OFFSET(tf_sstatus), db_frame },
- { "sbadaddr", DB_OFFSET(tf_sbadaddr), db_frame },
+ { "stval", DB_OFFSET(tf_stval), db_frame },
{ "scause", DB_OFFSET(tf_scause), db_frame },
};
struct db_variable *db_eregs = db_regs + nitems(db_regs);
void
db_show_mdpcpu(struct pcpu *pc)
{
}
/*
* Read bytes from kernel address space for debugger.
*/
int
db_read_bytes(vm_offset_t addr, size_t size, char *data)
{
jmp_buf jb;
void *prev_jb;
const char *src;
int ret;
prev_jb = kdb_jmpbuf(jb);
ret = setjmp(jb);
if (ret == 0) {
src = (const char *)addr;
while (size-- > 0)
*data++ = *src++;
}
(void)kdb_jmpbuf(prev_jb);
return (ret);
}
/*
* Write bytes to kernel address space for debugger.
*/
int
db_write_bytes(vm_offset_t addr, size_t size, char *data)
{
jmp_buf jb;
void *prev_jb;
char *dst;
int ret;
prev_jb = kdb_jmpbuf(jb);
ret = setjmp(jb);
if (ret == 0) {
dst = (char *)addr;
while (size-- > 0)
*dst++ = *data++;
/* Invalidate I-cache */
fence_i();
}
(void)kdb_jmpbuf(prev_jb);
return (ret);
}
Index: head/sys/riscv/riscv/exception.S
===================================================================
--- head/sys/riscv/riscv/exception.S (revision 342222)
+++ head/sys/riscv/riscv/exception.S (revision 342223)
@@ -1,237 +1,237 @@
/*-
* Copyright (c) 2015-2018 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
*
* Portions of this software were developed by the University of Cambridge
* Computer Laboratory as part of the CTSRD Project, with support from the
* UK Higher Education Innovation Fund (HEIF).
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include
__FBSDID("$FreeBSD$");
#include "assym.inc"
#include
#include
.macro save_registers el
addi sp, sp, -(TF_SIZE)
sd ra, (TF_RA)(sp)
sd tp, (TF_TP)(sp)
.if \el == 0 /* We came from userspace. Load our pcpu */
sd gp, (TF_GP)(sp)
ld gp, (TF_SIZE)(sp)
.endif
sd t0, (TF_T + 0 * 8)(sp)
sd t1, (TF_T + 1 * 8)(sp)
sd t2, (TF_T + 2 * 8)(sp)
sd t3, (TF_T + 3 * 8)(sp)
sd t4, (TF_T + 4 * 8)(sp)
sd t5, (TF_T + 5 * 8)(sp)
sd t6, (TF_T + 6 * 8)(sp)
sd s0, (TF_S + 0 * 8)(sp)
sd s1, (TF_S + 1 * 8)(sp)
sd s2, (TF_S + 2 * 8)(sp)
sd s3, (TF_S + 3 * 8)(sp)
sd s4, (TF_S + 4 * 8)(sp)
sd s5, (TF_S + 5 * 8)(sp)
sd s6, (TF_S + 6 * 8)(sp)
sd s7, (TF_S + 7 * 8)(sp)
sd s8, (TF_S + 8 * 8)(sp)
sd s9, (TF_S + 9 * 8)(sp)
sd s10, (TF_S + 10 * 8)(sp)
sd s11, (TF_S + 11 * 8)(sp)
sd a0, (TF_A + 0 * 8)(sp)
sd a1, (TF_A + 1 * 8)(sp)
sd a2, (TF_A + 2 * 8)(sp)
sd a3, (TF_A + 3 * 8)(sp)
sd a4, (TF_A + 4 * 8)(sp)
sd a5, (TF_A + 5 * 8)(sp)
sd a6, (TF_A + 6 * 8)(sp)
sd a7, (TF_A + 7 * 8)(sp)
#if 0
/* XXX: temporary test: spin if stack is not kernel one */
.if \el == 1 /* kernel */
mv t0, sp
srli t0, t0, 63
1:
beqz t0, 1b
.endif
#endif
.if \el == 1
/* Store kernel sp */
li t1, TF_SIZE
add t0, sp, t1
sd t0, (TF_SP)(sp)
.else
/* Store user sp */
csrr t0, sscratch
sd t0, (TF_SP)(sp)
.endif
li t0, 0
csrw sscratch, t0
csrr t0, sepc
sd t0, (TF_SEPC)(sp)
csrr t0, sstatus
sd t0, (TF_SSTATUS)(sp)
- csrr t0, sbadaddr
- sd t0, (TF_SBADADDR)(sp)
+ csrr t0, stval
+ sd t0, (TF_STVAL)(sp)
csrr t0, scause
sd t0, (TF_SCAUSE)(sp)
.endm
.macro load_registers el
ld t0, (TF_SSTATUS)(sp)
.if \el == 0
/* Ensure user interrupts will be enabled on eret */
li t1, SSTATUS_SPIE
or t0, t0, t1
.else
/*
* Disable interrupts for supervisor mode exceptions.
* For user mode exceptions we have already done this
* in do_ast.
*/
li t1, ~SSTATUS_SIE
and t0, t0, t1
.endif
csrw sstatus, t0
ld t0, (TF_SEPC)(sp)
csrw sepc, t0
.if \el == 0
/* We go to userspace. Load user sp */
ld t0, (TF_SP)(sp)
csrw sscratch, t0
/* And store our pcpu */
sd gp, (TF_SIZE)(sp)
ld gp, (TF_GP)(sp)
.endif
ld ra, (TF_RA)(sp)
ld tp, (TF_TP)(sp)
ld t0, (TF_T + 0 * 8)(sp)
ld t1, (TF_T + 1 * 8)(sp)
ld t2, (TF_T + 2 * 8)(sp)
ld t3, (TF_T + 3 * 8)(sp)
ld t4, (TF_T + 4 * 8)(sp)
ld t5, (TF_T + 5 * 8)(sp)
ld t6, (TF_T + 6 * 8)(sp)
ld s0, (TF_S + 0 * 8)(sp)
ld s1, (TF_S + 1 * 8)(sp)
ld s2, (TF_S + 2 * 8)(sp)
ld s3, (TF_S + 3 * 8)(sp)
ld s4, (TF_S + 4 * 8)(sp)
ld s5, (TF_S + 5 * 8)(sp)
ld s6, (TF_S + 6 * 8)(sp)
ld s7, (TF_S + 7 * 8)(sp)
ld s8, (TF_S + 8 * 8)(sp)
ld s9, (TF_S + 9 * 8)(sp)
ld s10, (TF_S + 10 * 8)(sp)
ld s11, (TF_S + 11 * 8)(sp)
ld a0, (TF_A + 0 * 8)(sp)
ld a1, (TF_A + 1 * 8)(sp)
ld a2, (TF_A + 2 * 8)(sp)
ld a3, (TF_A + 3 * 8)(sp)
ld a4, (TF_A + 4 * 8)(sp)
ld a5, (TF_A + 5 * 8)(sp)
ld a6, (TF_A + 6 * 8)(sp)
ld a7, (TF_A + 7 * 8)(sp)
addi sp, sp, (TF_SIZE)
.endm
.macro do_ast
/* Disable interrupts */
csrr a4, sstatus
1:
csrci sstatus, (SSTATUS_SIE)
ld a1, PC_CURTHREAD(gp)
lw a2, TD_FLAGS(a1)
li a3, (TDF_ASTPENDING|TDF_NEEDRESCHED)
and a2, a2, a3
beqz a2, 2f
/* Restore interrupts */
andi a4, a4, (SSTATUS_SIE)
csrs sstatus, a4
/* Handle the ast */
mv a0, sp
call _C_LABEL(ast)
/* Re-check for new ast scheduled */
j 1b
2:
.endm
ENTRY(cpu_exception_handler)
csrrw sp, sscratch, sp
beqz sp, 1f
/* User mode detected */
csrrw sp, sscratch, sp
j cpu_exception_handler_user
1:
/* Supervisor mode detected */
csrrw sp, sscratch, sp
j cpu_exception_handler_supervisor
END(cpu_exception_handler)
ENTRY(cpu_exception_handler_supervisor)
save_registers 1
mv a0, sp
call _C_LABEL(do_trap_supervisor)
load_registers 1
sret
END(cpu_exception_handler_supervisor)
ENTRY(cpu_exception_handler_user)
csrrw sp, sscratch, sp
save_registers 0
mv a0, sp
call _C_LABEL(do_trap_user)
do_ast
load_registers 0
csrrw sp, sscratch, sp
sret
END(cpu_exception_handler_user)
Index: head/sys/riscv/riscv/genassym.c
===================================================================
--- head/sys/riscv/riscv/genassym.c (revision 342222)
+++ head/sys/riscv/riscv/genassym.c (revision 342223)
@@ -1,101 +1,101 @@
/*-
* Copyright (c) 2015-2016 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
*
* Portions of this software were developed by the University of Cambridge
* Computer Laboratory as part of the CTSRD Project, with support from the
* UK Higher Education Innovation Fund (HEIF).
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include
__FBSDID("$FreeBSD$");
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
ASSYM(KERNBASE, KERNBASE);
ASSYM(VM_MAXUSER_ADDRESS, VM_MAXUSER_ADDRESS);
ASSYM(VM_MAX_KERNEL_ADDRESS, VM_MAX_KERNEL_ADDRESS);
ASSYM(TDF_ASTPENDING, TDF_ASTPENDING);
ASSYM(TDF_NEEDRESCHED, TDF_NEEDRESCHED);
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
ASSYM(PCB_L1ADDR, offsetof(struct pcb, pcb_l1addr));
ASSYM(PCB_SIZE, sizeof(struct pcb));
ASSYM(PCB_RA, offsetof(struct pcb, pcb_ra));
ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
ASSYM(PCB_GP, offsetof(struct pcb, pcb_gp));
ASSYM(PCB_TP, offsetof(struct pcb, pcb_tp));
ASSYM(PCB_T, offsetof(struct pcb, pcb_t));
ASSYM(PCB_S, offsetof(struct pcb, pcb_s));
ASSYM(PCB_A, offsetof(struct pcb, pcb_a));
ASSYM(PCB_X, offsetof(struct pcb, pcb_x));
ASSYM(PCB_FCSR, offsetof(struct pcb, pcb_fcsr));
ASSYM(SF_UC, offsetof(struct sigframe, sf_uc));
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TD_FLAGS, offsetof(struct thread, td_flags));
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
ASSYM(TD_FRAME, offsetof(struct thread, td_frame));
ASSYM(TD_MD, offsetof(struct thread, td_md));
ASSYM(TD_LOCK, offsetof(struct thread, td_lock));
ASSYM(TF_SIZE, sizeof(struct trapframe));
ASSYM(TF_RA, offsetof(struct trapframe, tf_ra));
ASSYM(TF_SP, offsetof(struct trapframe, tf_sp));
ASSYM(TF_GP, offsetof(struct trapframe, tf_gp));
ASSYM(TF_TP, offsetof(struct trapframe, tf_tp));
ASSYM(TF_T, offsetof(struct trapframe, tf_t));
ASSYM(TF_S, offsetof(struct trapframe, tf_s));
ASSYM(TF_A, offsetof(struct trapframe, tf_a));
ASSYM(TF_SEPC, offsetof(struct trapframe, tf_sepc));
-ASSYM(TF_SBADADDR, offsetof(struct trapframe, tf_sbadaddr));
+ASSYM(TF_STVAL, offsetof(struct trapframe, tf_stval));
ASSYM(TF_SCAUSE, offsetof(struct trapframe, tf_scause));
ASSYM(TF_SSTATUS, offsetof(struct trapframe, tf_sstatus));
Index: head/sys/riscv/riscv/trap.c
===================================================================
--- head/sys/riscv/riscv/trap.c (revision 342222)
+++ head/sys/riscv/riscv/trap.c (revision 342223)
@@ -1,398 +1,398 @@
/*-
* Copyright (c) 2015-2018 Ruslan Bukin
* All rights reserved.
*
* Portions of this software were developed by SRI International and the
* University of Cambridge Computer Laboratory under DARPA/AFRL contract
* FA8750-10-C-0237 ("CTSRD"), as part of the DARPA CRASH research programme.
*
* Portions of this software were developed by the University of Cambridge
* Computer Laboratory as part of the CTSRD Project, with support from the
* UK Higher Education Innovation Fund (HEIF).
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include
__FBSDID("$FreeBSD$");
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef KDB
#include
#endif
#include
#include
#include
#include
#include
#include
#ifdef FPE
#include
#endif
#include
#include
#include
#include
#include
#ifdef KDTRACE_HOOKS
#include
#endif
int (*dtrace_invop_jump_addr)(struct trapframe *);
extern register_t fsu_intr_fault;
/* Called from exception.S */
void do_trap_supervisor(struct trapframe *);
void do_trap_user(struct trapframe *);
static __inline void
call_trapsignal(struct thread *td, int sig, int code, void *addr)
{
ksiginfo_t ksi;
ksiginfo_init_trap(&ksi);
ksi.ksi_signo = sig;
ksi.ksi_code = code;
ksi.ksi_addr = addr;
trapsignal(td, &ksi);
}
int
cpu_fetch_syscall_args(struct thread *td)
{
struct proc *p;
register_t *ap;
struct syscall_args *sa;
int nap;
nap = NARGREG;
p = td->td_proc;
sa = &td->td_sa;
ap = &td->td_frame->tf_a[0];
sa->code = td->td_frame->tf_t[0];
if (sa->code == SYS_syscall || sa->code == SYS___syscall) {
sa->code = *ap++;
nap--;
}
if (p->p_sysent->sv_mask)
sa->code &= p->p_sysent->sv_mask;
if (sa->code >= p->p_sysent->sv_size)
sa->callp = &p->p_sysent->sv_table[0];
else
sa->callp = &p->p_sysent->sv_table[sa->code];
sa->narg = sa->callp->sy_narg;
memcpy(sa->args, ap, nap * sizeof(register_t));
if (sa->narg > nap)
panic("TODO: Could we have more then %d args?", NARGREG);
td->td_retval[0] = 0;
td->td_retval[1] = 0;
return (0);
}
#include "../../kern/subr_syscall.c"
static void
dump_regs(struct trapframe *frame)
{
int n;
int i;
n = (sizeof(frame->tf_t) / sizeof(frame->tf_t[0]));
for (i = 0; i < n; i++)
printf("t[%d] == 0x%016lx\n", i, frame->tf_t[i]);
n = (sizeof(frame->tf_s) / sizeof(frame->tf_s[0]));
for (i = 0; i < n; i++)
printf("s[%d] == 0x%016lx\n", i, frame->tf_s[i]);
n = (sizeof(frame->tf_a) / sizeof(frame->tf_a[0]));
for (i = 0; i < n; i++)
printf("a[%d] == 0x%016lx\n", i, frame->tf_a[i]);
printf("sepc == 0x%016lx\n", frame->tf_sepc);
printf("sstatus == 0x%016lx\n", frame->tf_sstatus);
}
static void
svc_handler(struct trapframe *frame)
{
struct thread *td;
int error;
td = curthread;
td->td_frame = frame;
error = syscallenter(td);
syscallret(td, error);
}
static void
data_abort(struct trapframe *frame, int usermode)
{
struct vm_map *map;
- uint64_t sbadaddr;
+ uint64_t stval;
struct thread *td;
struct pcb *pcb;
vm_prot_t ftype;
vm_offset_t va;
struct proc *p;
int error, sig, ucode;
#ifdef KDB
if (kdb_active) {
kdb_reenter();
return;
}
#endif
td = curthread;
p = td->td_proc;
pcb = td->td_pcb;
- sbadaddr = frame->tf_sbadaddr;
+ stval = frame->tf_stval;
if (td->td_critnest != 0 || td->td_intr_nesting_level != 0 ||
WITNESS_CHECK(WARN_SLEEPOK | WARN_GIANTOK, NULL,
"Kernel page fault") != 0)
goto fatal;
if (usermode)
map = &td->td_proc->p_vmspace->vm_map;
- else if (sbadaddr >= VM_MAX_USER_ADDRESS)
+ else if (stval >= VM_MAX_USER_ADDRESS)
map = kernel_map;
else {
if (pcb->pcb_onfault == 0)
goto fatal;
map = &td->td_proc->p_vmspace->vm_map;
}
- va = trunc_page(sbadaddr);
+ va = trunc_page(stval);
if ((frame->tf_scause == EXCP_FAULT_STORE) ||
(frame->tf_scause == EXCP_STORE_PAGE_FAULT)) {
ftype = VM_PROT_WRITE;
} else if (frame->tf_scause == EXCP_INST_PAGE_FAULT) {
ftype = VM_PROT_EXECUTE;
} else {
ftype = VM_PROT_READ;
}
if (pmap_fault_fixup(map->pmap, va, ftype))
goto done;
if (map != kernel_map) {
/*
* Keep swapout from messing with us during this
* critical time.
*/
PROC_LOCK(p);
++p->p_lock;
PROC_UNLOCK(p);
/* Fault in the user page: */
error = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
PROC_LOCK(p);
--p->p_lock;
PROC_UNLOCK(p);
} else {
/*
* Don't have to worry about process locking or stacks in the
* kernel.
*/
error = vm_fault(map, va, ftype, VM_FAULT_NORMAL);
}
if (error != KERN_SUCCESS) {
if (usermode) {
sig = SIGSEGV;
if (error == KERN_PROTECTION_FAILURE)
ucode = SEGV_ACCERR;
else
ucode = SEGV_MAPERR;
- call_trapsignal(td, sig, ucode, (void *)sbadaddr);
+ call_trapsignal(td, sig, ucode, (void *)stval);
} else {
if (pcb->pcb_onfault != 0) {
frame->tf_a[0] = error;
frame->tf_sepc = pcb->pcb_onfault;
return;
}
goto fatal;
}
}
done:
if (usermode)
userret(td, frame);
return;
fatal:
dump_regs(frame);
- panic("Fatal page fault at %#lx: %#016lx", frame->tf_sepc, sbadaddr);
+ panic("Fatal page fault at %#lx: %#016lx", frame->tf_sepc, stval);
}
void
do_trap_supervisor(struct trapframe *frame)
{
uint64_t exception;
uint64_t sstatus;
/* Ensure we came from supervisor mode, interrupts disabled */
__asm __volatile("csrr %0, sstatus" : "=&r" (sstatus));
KASSERT((sstatus & (SSTATUS_SPP | SSTATUS_SIE)) == SSTATUS_SPP,
("We must came from S mode with interrupts disabled"));
exception = (frame->tf_scause & EXCP_MASK);
if (frame->tf_scause & EXCP_INTR) {
/* Interrupt */
riscv_cpu_intr(frame);
return;
}
#ifdef KDTRACE_HOOKS
if (dtrace_trap_func != NULL && (*dtrace_trap_func)(frame, exception))
return;
#endif
CTR3(KTR_TRAP, "do_trap_supervisor: curthread: %p, sepc: %lx, frame: %p",
curthread, frame->tf_sepc, frame);
switch(exception) {
case EXCP_FAULT_LOAD:
case EXCP_FAULT_STORE:
case EXCP_FAULT_FETCH:
case EXCP_STORE_PAGE_FAULT:
case EXCP_LOAD_PAGE_FAULT:
data_abort(frame, 0);
break;
case EXCP_BREAKPOINT:
#ifdef KDTRACE_HOOKS
if (dtrace_invop_jump_addr != 0) {
dtrace_invop_jump_addr(frame);
break;
}
#endif
#ifdef KDB
kdb_trap(exception, 0, frame);
#else
dump_regs(frame);
panic("No debugger in kernel.\n");
#endif
break;
case EXCP_ILLEGAL_INSTRUCTION:
dump_regs(frame);
panic("Illegal instruction at 0x%016lx\n", frame->tf_sepc);
break;
default:
dump_regs(frame);
- panic("Unknown kernel exception %x badaddr %lx\n",
- exception, frame->tf_sbadaddr);
+ panic("Unknown kernel exception %x trap value %lx\n",
+ exception, frame->tf_stval);
}
}
void
do_trap_user(struct trapframe *frame)
{
uint64_t exception;
struct thread *td;
uint64_t sstatus;
struct pcb *pcb;
td = curthread;
td->td_frame = frame;
pcb = td->td_pcb;
/* Ensure we came from usermode, interrupts disabled */
__asm __volatile("csrr %0, sstatus" : "=&r" (sstatus));
KASSERT((sstatus & (SSTATUS_SPP | SSTATUS_SIE)) == 0,
("We must came from U mode with interrupts disabled"));
exception = (frame->tf_scause & EXCP_MASK);
if (frame->tf_scause & EXCP_INTR) {
/* Interrupt */
riscv_cpu_intr(frame);
return;
}
CTR3(KTR_TRAP, "do_trap_user: curthread: %p, sepc: %lx, frame: %p",
curthread, frame->tf_sepc, frame);
switch(exception) {
case EXCP_FAULT_LOAD:
case EXCP_FAULT_STORE:
case EXCP_FAULT_FETCH:
case EXCP_STORE_PAGE_FAULT:
case EXCP_LOAD_PAGE_FAULT:
case EXCP_INST_PAGE_FAULT:
data_abort(frame, 1);
break;
case EXCP_USER_ECALL:
frame->tf_sepc += 4; /* Next instruction */
svc_handler(frame);
break;
case EXCP_ILLEGAL_INSTRUCTION:
#ifdef FPE
if ((pcb->pcb_fpflags & PCB_FP_STARTED) == 0) {
/*
* May be a FPE trap. Enable FPE usage
* for this thread and try again.
*/
fpe_state_clear();
frame->tf_sstatus &= ~SSTATUS_FS_MASK;
frame->tf_sstatus |= SSTATUS_FS_CLEAN;
pcb->pcb_fpflags |= PCB_FP_STARTED;
break;
}
#endif
call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)frame->tf_sepc);
userret(td, frame);
break;
case EXCP_BREAKPOINT:
call_trapsignal(td, SIGTRAP, TRAP_BRKPT, (void *)frame->tf_sepc);
userret(td, frame);
break;
default:
dump_regs(frame);
- panic("Unknown userland exception %x, badaddr %lx\n",
- exception, frame->tf_sbadaddr);
+ panic("Unknown userland exception %x, trap value %lx\n",
+ exception, frame->tf_stval);
}
}