summaryrefslogtreecommitdiff
path: root/sys/src/9/imx8/fpu.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2022-05-08 16:50:29 +0000
committercinap_lenrek <cinap_lenrek@felloff.net>2022-05-08 16:50:29 +0000
commitfff070f2cbb01b7c0879e9dcb13ee4e3ed2497f0 (patch)
tree44899a9ae6e8143740a4b02e7d50a3b6db768008 /sys/src/9/imx8/fpu.c
parent9126ee3eea90d639f4e877c01400248581d10f65 (diff)
imx8: add work in progress i.MX8MQ kernel for the mntreform2 laptop
This is a work in progress port to the mntreform2 laptop. Working so far: - mmu (same as raspberry pi 3b+) - arm generic timer - gicv3 - uart1 - enet With access to the uart, one can netboot this kernel in u-boot using the following commands: > dhcp > bootm
Diffstat (limited to 'sys/src/9/imx8/fpu.c')
-rw-r--r--sys/src/9/imx8/fpu.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/sys/src/9/imx8/fpu.c b/sys/src/9/imx8/fpu.c
new file mode 100644
index 000000000..163678294
--- /dev/null
+++ b/sys/src/9/imx8/fpu.c
@@ -0,0 +1,92 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+
+#include "ureg.h"
+#include "sysreg.h"
+
+/* libc */
+extern ulong getfcr(void);
+extern void setfcr(ulong fcr);
+extern ulong getfsr(void);
+extern void setfsr(ulong fsr);
+
+void
+fpuinit(void)
+{
+ fpoff();
+}
+
+void
+fpon(void)
+{
+ syswr(CPACR_EL1, 3<<20);
+}
+
+void
+fpoff(void)
+{
+ syswr(CPACR_EL1, 0<<20);
+}
+
+void
+fpinit(void)
+{
+ fpon();
+ setfcr(0);
+ setfsr(0);
+}
+
+void
+fpclear(void)
+{
+ fpoff();
+}
+
+void
+fpsave(FPsave *p)
+{
+ p->control = getfcr();
+ p->status = getfsr();
+ fpsaveregs(p->regs);
+ fpoff();
+}
+
+void
+fprestore(FPsave *p)
+{
+ fpon();
+ setfcr(p->control);
+ setfsr(p->status);
+ fploadregs(p->regs);
+}
+
+void
+mathtrap(Ureg*)
+{
+ int s;
+
+ if((up->fpstate & FPillegal) != 0){
+ postnote(up, 1, "sys: floating point in note handler", NDebug);
+ return;
+ }
+ switch(up->fpstate){
+ case FPinit:
+ s = splhi();
+ fpinit();
+ up->fpstate = FPactive;
+ splx(s);
+ break;
+ case FPinactive:
+ s = splhi();
+ fprestore(up->fpsave);
+ up->fpstate = FPactive;
+ splx(s);
+ break;
+ case FPactive:
+ postnote(up, 1, "sys: floating point error", NDebug);
+ break;
+ }
+}