forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-09-20 cf4ce59b3b70238352c7f1729f0f7223214828ad
kernel/arch/mips/math-emu/cp1emu.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * cp1emu.c: a MIPS coprocessor 1 (FPU) instruction emulator
34 *
....@@ -6,19 +7,6 @@
67 *
78 * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com
89 * Copyright (C) 2000 MIPS Technologies, Inc.
9
- *
10
- * This program is free software; you can distribute it and/or modify it
11
- * under the terms of the GNU General Public License (Version 2) as
12
- * published by the Free Software Foundation.
13
- *
14
- * This program is distributed in the hope it will be useful, but WITHOUT
15
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
- * for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License along
20
- * with this program; if not, write to the Free Software Foundation, Inc.,
21
- * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2210 *
2311 * A complete emulator for MIPS coprocessor 1 instructions. This is
2412 * required for #float(switch) or #float(trap), where it catches all
....@@ -451,7 +439,7 @@
451439 regs->cp0_epc + dec_insn.pc_inc +
452440 dec_insn.next_pc_inc;
453441 }
454
- /* fall through */
442
+ fallthrough;
455443 case jr_op:
456444 /* For R6, JR already emulated in jalr_op */
457445 if (NO_R6EMU && insn.r_format.func == jr_op)
....@@ -471,11 +459,11 @@
471459 regs->regs[31] = regs->cp0_epc +
472460 dec_insn.pc_inc +
473461 dec_insn.next_pc_inc;
474
- /* fall through */
462
+ fallthrough;
475463 case bltzl_op:
476464 if (NO_R6EMU)
477465 break;
478
- /* fall through */
466
+ fallthrough;
479467 case bltz_op:
480468 if ((long)regs->regs[insn.i_format.rs] < 0)
481469 *contpc = regs->cp0_epc +
....@@ -495,11 +483,11 @@
495483 regs->regs[31] = regs->cp0_epc +
496484 dec_insn.pc_inc +
497485 dec_insn.next_pc_inc;
498
- /* fall through */
486
+ fallthrough;
499487 case bgezl_op:
500488 if (NO_R6EMU)
501489 break;
502
- /* fall through */
490
+ fallthrough;
503491 case bgez_op:
504492 if ((long)regs->regs[insn.i_format.rs] >= 0)
505493 *contpc = regs->cp0_epc +
....@@ -514,12 +502,12 @@
514502 break;
515503 case jalx_op:
516504 set_isa16_mode(bit);
517
- /* fall through */
505
+ fallthrough;
518506 case jal_op:
519507 regs->regs[31] = regs->cp0_epc +
520508 dec_insn.pc_inc +
521509 dec_insn.next_pc_inc;
522
- /* fall through */
510
+ fallthrough;
523511 case j_op:
524512 *contpc = regs->cp0_epc + dec_insn.pc_inc;
525513 *contpc >>= 28;
....@@ -531,7 +519,7 @@
531519 case beql_op:
532520 if (NO_R6EMU)
533521 break;
534
- /* fall through */
522
+ fallthrough;
535523 case beq_op:
536524 if (regs->regs[insn.i_format.rs] ==
537525 regs->regs[insn.i_format.rt])
....@@ -546,7 +534,7 @@
546534 case bnel_op:
547535 if (NO_R6EMU)
548536 break;
549
- /* fall through */
537
+ fallthrough;
550538 case bne_op:
551539 if (regs->regs[insn.i_format.rs] !=
552540 regs->regs[insn.i_format.rt])
....@@ -561,7 +549,7 @@
561549 case blezl_op:
562550 if (!insn.i_format.rt && NO_R6EMU)
563551 break;
564
- /* fall through */
552
+ fallthrough;
565553 case blez_op:
566554
567555 /*
....@@ -599,7 +587,7 @@
599587 case bgtzl_op:
600588 if (!insn.i_format.rt && NO_R6EMU)
601589 break;
602
- /* fall through */
590
+ fallthrough;
603591 case bgtz_op:
604592 /*
605593 * Compact branches for R6 for the
....@@ -737,7 +725,7 @@
737725 return 1;
738726 }
739727 /* R2/R6 compatible cop1 instruction */
740
- /* fall through */
728
+ fallthrough;
741729 case cop2_op:
742730 case cop1x_op:
743731 if (insn.i_format.rs == bc_op) {
....@@ -1063,7 +1051,7 @@
10631051 MIPSInst_SIMM(ir));
10641052 MIPS_FPU_EMU_INC_STATS(loads);
10651053
1066
- if (!access_ok(VERIFY_READ, dva, sizeof(u64))) {
1054
+ if (!access_ok(dva, sizeof(u64))) {
10671055 MIPS_FPU_EMU_INC_STATS(errors);
10681056 *fault_addr = dva;
10691057 return SIGBUS;
....@@ -1081,7 +1069,7 @@
10811069 MIPSInst_SIMM(ir));
10821070 MIPS_FPU_EMU_INC_STATS(stores);
10831071 DIFROMREG(dval, MIPSInst_RT(ir));
1084
- if (!access_ok(VERIFY_WRITE, dva, sizeof(u64))) {
1072
+ if (!access_ok(dva, sizeof(u64))) {
10851073 MIPS_FPU_EMU_INC_STATS(errors);
10861074 *fault_addr = dva;
10871075 return SIGBUS;
....@@ -1097,7 +1085,7 @@
10971085 wva = (u32 __user *) (xcp->regs[MIPSInst_RS(ir)] +
10981086 MIPSInst_SIMM(ir));
10991087 MIPS_FPU_EMU_INC_STATS(loads);
1100
- if (!access_ok(VERIFY_READ, wva, sizeof(u32))) {
1088
+ if (!access_ok(wva, sizeof(u32))) {
11011089 MIPS_FPU_EMU_INC_STATS(errors);
11021090 *fault_addr = wva;
11031091 return SIGBUS;
....@@ -1115,7 +1103,7 @@
11151103 MIPSInst_SIMM(ir));
11161104 MIPS_FPU_EMU_INC_STATS(stores);
11171105 SIFROMREG(wval, MIPSInst_RT(ir));
1118
- if (!access_ok(VERIFY_WRITE, wva, sizeof(u32))) {
1106
+ if (!access_ok(wva, sizeof(u32))) {
11191107 MIPS_FPU_EMU_INC_STATS(errors);
11201108 *fault_addr = wva;
11211109 return SIGBUS;
....@@ -1229,14 +1217,14 @@
12291217 case bcfl_op:
12301218 if (cpu_has_mips_2_3_4_5_r)
12311219 likely = 1;
1232
- /* fall through */
1220
+ fallthrough;
12331221 case bcf_op:
12341222 cond = !cond;
12351223 break;
12361224 case bctl_op:
12371225 if (cpu_has_mips_2_3_4_5_r)
12381226 likely = 1;
1239
- /* fall through */
1227
+ fallthrough;
12401228 case bct_op:
12411229 break;
12421230 }
....@@ -1493,7 +1481,7 @@
14931481 xcp->regs[MIPSInst_FT(ir)]);
14941482
14951483 MIPS_FPU_EMU_INC_STATS(loads);
1496
- if (!access_ok(VERIFY_READ, va, sizeof(u32))) {
1484
+ if (!access_ok(va, sizeof(u32))) {
14971485 MIPS_FPU_EMU_INC_STATS(errors);
14981486 *fault_addr = va;
14991487 return SIGBUS;
....@@ -1513,7 +1501,7 @@
15131501 MIPS_FPU_EMU_INC_STATS(stores);
15141502
15151503 SIFROMREG(val, MIPSInst_FS(ir));
1516
- if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) {
1504
+ if (!access_ok(va, sizeof(u32))) {
15171505 MIPS_FPU_EMU_INC_STATS(errors);
15181506 *fault_addr = va;
15191507 return SIGBUS;
....@@ -1526,16 +1514,28 @@
15261514 break;
15271515
15281516 case madd_s_op:
1529
- handler = fpemu_sp_madd;
1517
+ if (cpu_has_mac2008_only)
1518
+ handler = ieee754sp_madd;
1519
+ else
1520
+ handler = fpemu_sp_madd;
15301521 goto scoptop;
15311522 case msub_s_op:
1532
- handler = fpemu_sp_msub;
1523
+ if (cpu_has_mac2008_only)
1524
+ handler = ieee754sp_msub;
1525
+ else
1526
+ handler = fpemu_sp_msub;
15331527 goto scoptop;
15341528 case nmadd_s_op:
1535
- handler = fpemu_sp_nmadd;
1529
+ if (cpu_has_mac2008_only)
1530
+ handler = ieee754sp_nmadd;
1531
+ else
1532
+ handler = fpemu_sp_nmadd;
15361533 goto scoptop;
15371534 case nmsub_s_op:
1538
- handler = fpemu_sp_nmsub;
1535
+ if (cpu_has_mac2008_only)
1536
+ handler = ieee754sp_nmsub;
1537
+ else
1538
+ handler = fpemu_sp_nmsub;
15391539 goto scoptop;
15401540
15411541 scoptop:
....@@ -1590,7 +1590,7 @@
15901590 xcp->regs[MIPSInst_FT(ir)]);
15911591
15921592 MIPS_FPU_EMU_INC_STATS(loads);
1593
- if (!access_ok(VERIFY_READ, va, sizeof(u64))) {
1593
+ if (!access_ok(va, sizeof(u64))) {
15941594 MIPS_FPU_EMU_INC_STATS(errors);
15951595 *fault_addr = va;
15961596 return SIGBUS;
....@@ -1609,7 +1609,7 @@
16091609
16101610 MIPS_FPU_EMU_INC_STATS(stores);
16111611 DIFROMREG(val, MIPSInst_FS(ir));
1612
- if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) {
1612
+ if (!access_ok(va, sizeof(u64))) {
16131613 MIPS_FPU_EMU_INC_STATS(errors);
16141614 *fault_addr = va;
16151615 return SIGBUS;
....@@ -1622,15 +1622,27 @@
16221622 break;
16231623
16241624 case madd_d_op:
1625
- handler = fpemu_dp_madd;
1625
+ if (cpu_has_mac2008_only)
1626
+ handler = ieee754dp_madd;
1627
+ else
1628
+ handler = fpemu_dp_madd;
16261629 goto dcoptop;
16271630 case msub_d_op:
1628
- handler = fpemu_dp_msub;
1631
+ if (cpu_has_mac2008_only)
1632
+ handler = ieee754dp_msub;
1633
+ else
1634
+ handler = fpemu_dp_msub;
16291635 goto dcoptop;
16301636 case nmadd_d_op:
1631
- handler = fpemu_dp_nmadd;
1637
+ if (cpu_has_mac2008_only)
1638
+ handler = ieee754dp_nmadd;
1639
+ else
1640
+ handler = fpemu_dp_nmadd;
16321641 goto dcoptop;
16331642 case nmsub_d_op:
1643
+ if (cpu_has_mac2008_only)
1644
+ handler = ieee754dp_nmsub;
1645
+ else
16341646 handler = fpemu_dp_nmsub;
16351647 goto dcoptop;
16361648
....@@ -2831,6 +2843,13 @@
28312843 u16 *instr_ptr;
28322844 int sig = 0;
28332845
2846
+ /*
2847
+ * Initialize context if it hasn't been used already, otherwise ensure
2848
+ * it has been saved to struct thread_struct.
2849
+ */
2850
+ if (!init_fp_ctx(current))
2851
+ lose_fpu(1);
2852
+
28342853 oldepc = xcp->cp0_epc;
28352854 do {
28362855 prevepc = xcp->cp0_epc;