Merge branch 'master' of git://git.denx.de/u-boot-i2c
[oweals/u-boot.git] / post / lib_powerpc / rlwnm.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2002
4  * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5  */
6
7 #include <common.h>
8
9 /*
10  * CPU test
11  * Shift instructions:          rlwnm
12  *
13  * The test contains a pre-built table of instructions, operands and
14  * expected results. For each table entry, the test will cyclically use
15  * different sets of operand registers and result registers.
16  */
17
18 #include <post.h>
19 #include "cpu_asm.h"
20
21 #if CONFIG_POST & CONFIG_SYS_POST_CPU
22
23 extern void cpu_post_exec_22 (ulong *code, ulong *cr, ulong *res, ulong op1,
24     ulong op2);
25 extern ulong cpu_post_makecr (long v);
26
27 static struct cpu_post_rlwnm_s
28 {
29     ulong cmd;
30     ulong op1;
31     ulong op2;
32     uchar mb;
33     uchar me;
34     ulong res;
35 } cpu_post_rlwnm_table[] =
36 {
37    {
38         OP_RLWNM,
39         0xffff0000,
40         24,
41         16,
42         23,
43         0x0000ff00
44    },
45 };
46 static unsigned int cpu_post_rlwnm_size = ARRAY_SIZE(cpu_post_rlwnm_table);
47
48 int cpu_post_test_rlwnm (void)
49 {
50     int ret = 0;
51     unsigned int i, reg;
52     int flag = disable_interrupts();
53
54     for (i = 0; i < cpu_post_rlwnm_size && ret == 0; i++)
55     {
56         struct cpu_post_rlwnm_s *test = cpu_post_rlwnm_table + i;
57
58         for (reg = 0; reg < 32 && ret == 0; reg++)
59         {
60             unsigned int reg0 = (reg + 0) % 32;
61             unsigned int reg1 = (reg + 1) % 32;
62             unsigned int reg2 = (reg + 2) % 32;
63             unsigned int stk = reg < 16 ? 31 : 15;
64             unsigned long code[] =
65             {
66                 ASM_STW(stk, 1, -4),
67                 ASM_ADDI(stk, 1, -24),
68                 ASM_STW(3, stk, 12),
69                 ASM_STW(4, stk, 16),
70                 ASM_STW(reg0, stk, 8),
71                 ASM_STW(reg1, stk, 4),
72                 ASM_STW(reg2, stk, 0),
73                 ASM_LWZ(reg1, stk, 12),
74                 ASM_LWZ(reg0, stk, 16),
75                 ASM_122(test->cmd, reg2, reg1, reg0, test->mb, test->me),
76                 ASM_STW(reg2, stk, 12),
77                 ASM_LWZ(reg2, stk, 0),
78                 ASM_LWZ(reg1, stk, 4),
79                 ASM_LWZ(reg0, stk, 8),
80                 ASM_LWZ(3, stk, 12),
81                 ASM_ADDI(1, stk, 24),
82                 ASM_LWZ(stk, 1, -4),
83                 ASM_BLR,
84             };
85             unsigned long codecr[] =
86             {
87                 ASM_STW(stk, 1, -4),
88                 ASM_ADDI(stk, 1, -24),
89                 ASM_STW(3, stk, 12),
90                 ASM_STW(4, stk, 16),
91                 ASM_STW(reg0, stk, 8),
92                 ASM_STW(reg1, stk, 4),
93                 ASM_STW(reg2, stk, 0),
94                 ASM_LWZ(reg1, stk, 12),
95                 ASM_LWZ(reg0, stk, 16),
96                 ASM_122(test->cmd, reg2, reg1, reg0, test->mb, test->me) |
97                     BIT_C,
98                 ASM_STW(reg2, stk, 12),
99                 ASM_LWZ(reg2, stk, 0),
100                 ASM_LWZ(reg1, stk, 4),
101                 ASM_LWZ(reg0, stk, 8),
102                 ASM_LWZ(3, stk, 12),
103                 ASM_ADDI(1, stk, 24),
104                 ASM_LWZ(stk, 1, -4),
105                 ASM_BLR,
106             };
107             ulong res;
108             ulong cr;
109
110             if (ret == 0)
111             {
112                 cr = 0;
113                 cpu_post_exec_22 (code, & cr, & res, test->op1, test->op2);
114
115                 ret = res == test->res && cr == 0 ? 0 : -1;
116
117                 if (ret != 0)
118                 {
119                     post_log ("Error at rlwnm test %d !\n", i);
120                 }
121             }
122
123             if (ret == 0)
124             {
125                 cpu_post_exec_22 (codecr, & cr, & res, test->op1, test->op2);
126
127                 ret = res == test->res &&
128                       (cr & 0xe0000000) == cpu_post_makecr (res) ? 0 : -1;
129
130                 if (ret != 0)
131                 {
132                     post_log ("Error at rlwnm test %d !\n", i);
133                 }
134             }
135         }
136     }
137
138     if (flag)
139         enable_interrupts();
140
141     return ret;
142 }
143
144 #endif