source: rtems/c/src/lib/libcpu/powerpc/new-exceptions/bspsupport/ppc_exc_test.c @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

  • Property mode set to 100644
File size: 5.4 KB
Line 
1/*
2 * Test low-level exception handling code:
3 *
4 *  - hook an exception handler
5 *  - clobber (almost) all registers with a known value
6 *  - raise exception
7 *  - from exception handler, increment all saved register
8 *    contents by one (to ensure registers are not only
9 *    saved properly but also restored properly).
10 *  - resume execution
11 *  - verify registers are now 'clobber_value + 1'
12 *
13 * NOTE: cannot be used on PSIM because SYS exception is used
14 *       internally by simulator (but we could use a trap or
15 *       something else).
16 *
17 * Author: Till Straumann <strauman@slac.stanford.edu>, 2007
18 *
19 *  The license and distribution terms for this file may be
20 *  found in the file LICENSE in this distribution or at
21 *  http://www.rtems.org/license/LICENSE.
22 */
23
24
25#include <inttypes.h>
26#include <stdio.h>
27#include <stdlib.h>
28#include <string.h>
29#include "vectors.h"
30
31
32typedef struct regs_ {
33        uint32_t        cr, xer, lr, ctr;
34        uint32_t        gpr0;
35        uint32_t        gpr1;
36        uint32_t        gpr2;
37        uint32_t        gpr3;
38        uint32_t        gpr4;
39        uint32_t        gpr5;
40        uint32_t        gpr6;
41        uint32_t        gpr7;
42        uint32_t        gpr8;
43        uint32_t        gpr9;
44        uint32_t        gpr10;
45        uint32_t        gpr11;
46        uint32_t        gpr12;
47        uint32_t        gpr13;
48        uint32_t        gpr14;
49        uint32_t        gpr15;
50        uint32_t        gpr16;
51        uint32_t        gpr17;
52        uint32_t        gpr18;
53        uint32_t        gpr19;
54        uint32_t        gpr20;
55        uint32_t        gpr21;
56        uint32_t        gpr22;
57        uint32_t        gpr23;
58        uint32_t        gpr24;
59        uint32_t        gpr25;
60        uint32_t        gpr26;
61        uint32_t        gpr27;
62        uint32_t        gpr28;
63        uint32_t        gpr29;
64        uint32_t        gpr30;
65        uint32_t        gpr31;
66} ppc_exc_int_regs;
67
68#define OFF(x)  (uintptr_t)(&((ppc_exc_int_regs*)0)->x)
69
70void
71storegs(ppc_exc_int_regs *p0, ppc_exc_int_regs *p1)
72{
73        asm volatile(
74                "       stmw 0, %6(%0)   ;"
75                "       mfcr    0                ;"
76                "       stw      0, %2(%0)   ;"
77                "       mflr    0                ;"
78                "       stw      0, %3(%0)   ;"
79                "       mfxer   0                ;"
80                "       stw      0, %4(%0)   ;"
81                "       mfctr   0                ;"
82                "       stw      0, %5(%0)   ;"
83                "       lwz  0, %6(%0)   ;"
84                "       trap             ;"
85                "       stmw 0, %6(%1)   ;"
86                "       mfcr    0                ;"
87                "       stw      0, %2(%1)   ;"
88                "       mflr    0                ;"
89                "       stw      0, %3(%1)   ;"
90                "       mfxer   0                ;"
91                "       stw      0, %4(%1)   ;"
92                "       mfctr   0                ;"
93                "       stw      0, %5(%1)   ;"
94                :
95                :"b"(p0),"b"(p1),
96                "i"(OFF(cr)), "i"(OFF(lr)), "i"(OFF(xer)), "i"(OFF(ctr)),
97                "i"(OFF(gpr0))
98                :"r0");
99}
100
101/* Load up all registers from 'pre' issue system call and store
102 * registers in 'post'
103 */
104
105ppc_exc_int_regs pre;
106ppc_exc_int_regs pst;
107
108void
109clobber()
110{
111        asm volatile(
112                "       lis 2,  pre@h  ;"
113                "   ori 2, 2, pre@l  ;"
114                "       lwz     3,      %0(2) ;"
115                "       mtcr    3      ;"
116                "       lwz     3,      %1(2) ;"
117                "       mtlr    3      ;"
118                "       lwz     3,      %2(2) ;"
119                "       mtxer   3      ;"
120                /* don't know which ones stick */
121                "       mfxer   3      ;"
122                "   stw 3,  %2(2)  ;"
123                "       lwz     3,      %3(2) ;"
124                "       mtctr   3      ;"
125                "       lwz     0,      %4(2) ;"
126                /* must not clobber R13, R1, R2 */
127                "       stw 13, %6(2) ;"
128                "   lmw 3,  %5(2)  ;"
129                "   trap           ;"
130                "   stmw 0, %4(2) ;"
131                "       mfcr    0          ;"
132                "       stw      0, %0(2) ;"
133                "       mflr    0          ;"
134                "       stw      0, %1(2) ;"
135                "       mfxer   0          ;"
136                "       stw      0, %2(2) ;"
137                "       mfctr   0          ;"
138                "       stw      0, %3(2) ;"
139                :
140                :"i"(OFF(cr)), "i"(OFF(lr)), "i"(OFF(xer)), "i"(OFF(ctr)),
141                 "i"(OFF(gpr0)), "i"(OFF(gpr3)), "i"(OFF(gpr13))
142                :"r0", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
143                 "r10", "r11", "r12", "r14", "r15", "r16",
144                 "r17", "r18", "r19", "r20", "r21", "r22", "r23",
145                 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
146                 "xer","lr","ctr",
147                 "cr0","cr1","cr2","cr3","cr4","cr5","cr6","cr7",
148                 "memory");
149}
150
151typedef union { uint32_t u; uint8_t c[4]; } u32_a_t;
152
153/* exception handler; adds 1 to all register contents (except r1,r2,r13) */
154int
155handle_clobber_exc(BSP_Exception_frame *f, unsigned vector)
156{
157int i;
158u32_a_t *p = (u32_a_t*)&f->GPR0;
159        for ( i=0; i<32; i++ ) {
160                switch (i) {
161                        case 1: case 2: case 13: break;
162                        default:
163                                p[i].u++;
164                        break;
165                }
166        }
167  f->GPR2 = (uint32_t)&pst;
168  f->EXC_CR++;
169  f->EXC_CTR++;
170  f->EXC_XER++;
171  f->EXC_LR++;
172  f->EXC_SRR0 += 4;
173  return 0;
174}
175
176
177/* This routine tests the raw exception code;
178 *  - hook 'handle_clobber_exc' to SYS exception handler
179 *  - clobber all registers with 0xaffe0000 + <index>
180 *    (except: r1, r2, r13, non-sticky bits in xer)
181 *    R2 is clobbered with the address of the pre area.
182 *  - issue 'trap' -> PROG exception
183 *  - exception handler increments all reg. contents by 1,
184 *    stores address of 'pst' area in R2 and returns control
185 *    to ppc_exc_clobber().
186 *  - save all register contents to *R2 (should be &pst).
187 *  - test for mismatches (except R1, R2, R13 and parts of xer)
188 */
189void
190ppc_exc_clobber()
191{
192u32_a_t *a, *b;
193        int i;
194        a = (u32_a_t*)&pre;
195        b = (u32_a_t*)&pst;
196        for ( i=0; i< sizeof(pre)/sizeof(uint32_t); i++ ) {
197                a[i].u = 0xaffe0000 + i;
198        }
199        ppc_exc_set_handler(ASM_PROG_VECTOR, handle_clobber_exc);
200        clobber();
201        ppc_exc_set_handler(ASM_PROG_VECTOR, 0);
202        for ( i=0; i< sizeof(pre)/sizeof(uint32_t); i++ ) {
203                switch (i) {
204                        case OFF(gpr1)/sizeof(uint32_t):
205                        case OFF(gpr2)/sizeof(uint32_t):
206                        case OFF(gpr13)/sizeof(uint32_t):
207                        break;
208
209                        default:
210                                if ( a[i].u != b[i].u - 1  ) {
211                                         printf("MISMATCH at %i: 0x%08"PRIx32" -- 0x%08"PRIx32"\n",
212                                                i, a[i].u, b[i].u);
213                                }
214                }
215        }
216}
217
218#if 0
219void
220ppc_exc_test()
221{
222ppc_exc_int_regs a, b;
223int              i;
224        memset(&a, 0xaa, sizeof(a));
225        memset(&b, 0x55, sizeof(b));
226        storegs(&a, &b);
227        if ( memcmp(&a, &b, sizeof(a)) ) {
228                printf("FAILURE: context prior and after exception don't match!\n");
229        }
230        for ( i=0; i< sizeof(a)/sizeof(uint32_t); i++ ) {
231                        printf("0x%08"PRIx32" -- 0x%08"PRIx32"\n",
232                                ((uint32_t __attribute__((may_alias)) *)&a)[i],
233                                ((uint32_t __attribute__((may_alias)) *)&b)[i]);
234        }
235}
236#endif
Note: See TracBrowser for help on using the repository browser.