-/* $OpenBSD: vfp.c,v 1.2 2017/03/28 23:47:17 jsg Exp $ */
+/* $OpenBSD: vfp.c,v 1.3 2018/01/26 16:15:26 kettenis Exp $ */
/*
* Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
*
#include <arm64/include/vfp.h>
-void vfp_store(struct fpreg *vfpsave);
-
-static inline void set_vfp_enable(int val)
+static inline void
+set_vfp_enable(int val)
{
uint64_t v;
__asm __volatile("mrs %x0, cpacr_el1" : "=r" (v));
__asm __volatile("isb");
}
-static inline int get_vfp_enable()
+static inline int
+get_vfp_enable(void)
{
uint64_t v;
int enabled = 0;
return enabled;
}
-int
-vfp_fault(vaddr_t pc, uint32_t insn, trapframe_t *tf, int fault_code);
+int vfp_fault(vaddr_t pc, uint32_t insn, trapframe_t *tf, int fault_code);
void vfp_load(struct proc *p);
-
-void
-vfp_init(void)
-{
- static int inited = 0;
-
- if (inited == 1)
- return;
- inited = 1;
-
- /* Read Coprocessor Access Control Register */
-
- /* other stuff?? */
-}
+void vfp_store(struct fpreg *vfpsave);
void
vfp_store(struct fpreg *vfpsave)
{
- uint32_t scratch;
+ uint32_t scratch;
if (get_vfp_enable()) {
__asm __volatile(
void
vfp_save(void)
{
- struct cpu_info *ci = curcpu();
- struct pcb *pcb;
- struct proc *p;
-
+ struct cpu_info *ci = curcpu();
+ struct pcb *pcb = curpcb;
+ struct proc *p = curproc;
uint32_t vfp_enabled;
if (ci->ci_fpuproc == 0)
if (!vfp_enabled)
return; /* not enabled, nothing to do */
-#if 0
- // arm32 had failures flags, verify this on aarch64
- if (vfp_enabled)
- panic("vfp exceptional data fault, time to write more code");
-#endif
-
- p = curproc;
- pcb = curpcb;
-
if (pcb->pcb_fpcpu == NULL || ci->ci_fpuproc == NULL ||
!(pcb->pcb_fpcpu == ci && ci->ci_fpuproc == p)) {
/* disable fpu before panic, otherwise recurse */
vfp_store(&p->p_addr->u_pcb.pcb_fpstate);
- /* NOTE: fpu state is saved but remains 'valid', as long as
+ /*
+ * NOTE: fpu state is saved but remains 'valid', as long as
* curpcb()->pcb_fpucpu == ci && ci->ci_fpuproc == curproc()
* is true FPU state is valid and can just be enabled without reload.
*/
}
void
-vfp_enable()
+vfp_enable(void)
{
- struct cpu_info *ci = curcpu();
+ struct cpu_info *ci = curcpu();
if (curproc->p_addr->u_pcb.pcb_fpcpu == ci &&
ci->ci_fpuproc == curproc) {
void
vfp_load(struct proc *p)
{
- struct cpu_info *ci = curcpu();
- struct pcb *pcb = &p->p_addr->u_pcb;
- uint32_t scratch = 0;
- int psw;
+ struct cpu_info *ci = curcpu();
+ struct pcb *pcb = &p->p_addr->u_pcb;
+ uint32_t scratch = 0;
+ int psw;
/* do not allow a partially synced state here */
psw = disable_interrupts();
int
vfp_fault(vaddr_t pc, uint32_t insn, trapframe_t *tf, int fault_code)
{
- struct proc *p;
- struct pcb *pcb;
- struct cpu_info *ci;
-
- p = curproc;
- pcb = &p->p_addr->u_pcb;
- ci = curcpu();
+ struct proc *p = curproc;
+ struct pcb *pcb = &p->p_addr->u_pcb;
if (get_vfp_enable()) {
/*
/* we should be able to ignore old state of pcb_fpcpu ci_fpuproc */
if ((pcb->pcb_flags & PCB_FPU) == 0) {
pcb->pcb_flags |= PCB_FPU;
-
- bzero (&pcb->pcb_fpstate, sizeof (pcb->pcb_fpstate));
-
- /* XXX - setround()? */
+ memset(&pcb->pcb_fpstate, 0, sizeof (pcb->pcb_fpstate));
}
vfp_load(p);
void
vfp_discard(struct proc *p)
{
- struct cpu_info *ci = curcpu();
+ struct cpu_info *ci = curcpu();
+
if (curpcb->pcb_fpcpu == ci && ci->ci_fpuproc == p) {
ci->ci_fpuproc = NULL;
curpcb->pcb_fpcpu = NULL;