blob: 34cbafbfcd8b85b1d90219a17b217052b46846d6 [file] [log] [blame]
Shruti Gupta38133fa2023-04-19 17:00:38 +01001/*
2 * Copyright (c) 2023, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +01006
7#include <arch_helpers.h>
Shruti Gupta38133fa2023-04-19 17:00:38 +01008#include <stdbool.h>
9#include <stdlib.h>
10#include <string.h>
11
12#include <debug.h>
13#include <lib/extensions/fpu.h>
14
15#define __STR(x) #x
16#define STR(x) __STR(x)
17
18#define fill_simd_helper(num1, num2) "ldp q"#num1", q"#num2",\
19 [%0], #"STR(2 * FPU_Q_SIZE)";"
20#define read_simd_helper(num1, num2) "stp q"#num1", q"#num2",\
21 [%0], #"STR(2 * FPU_Q_SIZE)";"
22
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010023/* Read FPU Q[0-31] and strore it in 'q_regs' */
24void fpu_q_regs_read(fpu_q_reg_t q_regs[FPU_Q_COUNT])
Shruti Gupta38133fa2023-04-19 17:00:38 +010025{
Shruti Gupta38133fa2023-04-19 17:00:38 +010026 __asm__ volatile(
27 read_simd_helper(0, 1)
28 read_simd_helper(2, 3)
29 read_simd_helper(4, 5)
30 read_simd_helper(6, 7)
31 read_simd_helper(8, 9)
32 read_simd_helper(10, 11)
33 read_simd_helper(12, 13)
34 read_simd_helper(14, 15)
35 read_simd_helper(16, 17)
36 read_simd_helper(18, 19)
37 read_simd_helper(20, 21)
38 read_simd_helper(22, 23)
39 read_simd_helper(24, 25)
40 read_simd_helper(26, 27)
41 read_simd_helper(28, 29)
42 read_simd_helper(30, 31)
43 "sub %0, %0, #" STR(FPU_Q_COUNT * FPU_Q_SIZE) ";"
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010044 : : "r" (q_regs));
Shruti Gupta38133fa2023-04-19 17:00:38 +010045}
46
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010047/* Write FPU Q[0-31] registers passed in 'q_regs' */
48static void fpu_q_regs_write(const fpu_q_reg_t q_regs[FPU_Q_COUNT])
Shruti Gupta38133fa2023-04-19 17:00:38 +010049{
Shruti Gupta38133fa2023-04-19 17:00:38 +010050 __asm__ volatile(
51 fill_simd_helper(0, 1)
52 fill_simd_helper(2, 3)
53 fill_simd_helper(4, 5)
54 fill_simd_helper(6, 7)
55 fill_simd_helper(8, 9)
56 fill_simd_helper(10, 11)
57 fill_simd_helper(12, 13)
58 fill_simd_helper(14, 15)
59 fill_simd_helper(16, 17)
60 fill_simd_helper(18, 19)
61 fill_simd_helper(20, 21)
62 fill_simd_helper(22, 23)
63 fill_simd_helper(24, 25)
64 fill_simd_helper(26, 27)
65 fill_simd_helper(28, 29)
66 fill_simd_helper(30, 31)
67 "sub %0, %0, #" STR(FPU_Q_COUNT * FPU_Q_SIZE) ";"
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010068 : : "r" (q_regs));
Shruti Gupta38133fa2023-04-19 17:00:38 +010069}
70
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010071/* Read FPCR and FPSR and store it in 'cs_regs' */
72void fpu_cs_regs_read(fpu_cs_regs_t *cs_regs)
Shruti Gupta38133fa2023-04-19 17:00:38 +010073{
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010074 cs_regs->fpcr = read_fpcr();
75 cs_regs->fpsr = read_fpsr();
76}
77
78/* Write FPCR and FPSR passed in 'cs_regs' */
79void fpu_cs_regs_write(const fpu_cs_regs_t *cs_regs)
80{
81 write_fpcr(cs_regs->fpcr);
82 write_fpsr(cs_regs->fpsr);
83}
84
85/*
86 * Generate random values and write it to 'q_regs', then write it to FPU Q
87 * registers.
88 */
89void fpu_q_regs_write_rand(fpu_q_reg_t q_regs[FPU_Q_COUNT])
90{
91 uint32_t rval;
92
93 rval = rand();
94
95 memset((void *)q_regs, 0, sizeof(fpu_q_reg_t) * FPU_Q_COUNT);
Shruti Gupta38133fa2023-04-19 17:00:38 +010096 for (unsigned int num = 0U; num < FPU_Q_COUNT; num++) {
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +010097 memset((uint8_t *)q_regs[num], rval * (num + 1),
98 sizeof(fpu_q_reg_t));
Shruti Gupta38133fa2023-04-19 17:00:38 +010099 }
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100100 fpu_q_regs_write(q_regs);
Shruti Gupta38133fa2023-04-19 17:00:38 +0100101}
102
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100103/*
104 * Generate random values and write it to 'cs_regs', then write it to FPU FPCR
105 * and FPSR.
106 */
107void fpu_cs_regs_write_rand(fpu_cs_regs_t *cs_regs)
Shruti Gupta38133fa2023-04-19 17:00:38 +0100108{
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100109 memset((void *)cs_regs, 0, sizeof(fpu_cs_regs_t));
Shruti Gupta38133fa2023-04-19 17:00:38 +0100110
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100111 cs_regs->fpcr = rand();
112 cs_regs->fpsr = rand();
113
114 /*
115 * Write random value to FPCR FPSR.
116 * Note write will be ignored for reserved bits.
117 */
118 fpu_cs_regs_write(cs_regs);
119
120 /* Read back current FPCR and FPSR */
121 fpu_cs_regs_read(cs_regs);
122}
123
124/*
125 * Generate random values and write it to 'fpu_state', then write it to FPU Q
126 * registers, FPCR and FPSR.
127 */
128void fpu_state_write_rand(fpu_state_t *fpu_state)
129{
130 fpu_q_regs_write_rand(fpu_state->q_regs);
131 fpu_cs_regs_write_rand(&fpu_state->cs_regs);
132}
133
134/* Read FPU Q registers, FPCR and FPSR write it to 'fpu_state' */
135void fpu_state_read(fpu_state_t *fpu_state)
136{
137 fpu_q_regs_read(fpu_state->q_regs);
138 fpu_cs_regs_read(&fpu_state->cs_regs);
139}
140
141/* Return zero if FPU Q registers 's1', 's2' matches else nonzero */
142int fpu_q_regs_compare(const fpu_q_reg_t s1[FPU_Q_COUNT],
143 const fpu_q_reg_t s2[FPU_Q_COUNT])
144{
145 return memcmp(s1, s2, sizeof(fpu_q_reg_t) * FPU_Q_COUNT);
146}
147
148/*
149 * Return zero if FPU control and status registers 's1', 's2' matches else
150 * nonzero
151 */
152int fpu_cs_regs_compare(const fpu_cs_regs_t *s1, const fpu_cs_regs_t *s2)
153{
154 return memcmp(s1, s2, sizeof(fpu_cs_regs_t));
155}
156
157/* Returns 0, if FPU state 's1', 's2' matches else non-zero */
158int fpu_state_compare(const fpu_state_t *s1, const fpu_state_t *s2)
159{
160 if (fpu_q_regs_compare(s1->q_regs, s2->q_regs) != 0) {
161 return 1;
Shruti Gupta38133fa2023-04-19 17:00:38 +0100162 }
Arunachalam Ganapathy7e514f62023-08-30 13:27:36 +0100163
164 if (fpu_cs_regs_compare(&s1->cs_regs, &s2->cs_regs) != 0) {
165 return 1;
166 }
167
168 return 0;
Shruti Gupta38133fa2023-04-19 17:00:38 +0100169}