OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [testsuite/] [test-code-or1k/] [upcalls/] [upcall-misaligned.c] - Blame information for rev 93

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 93 jeremybenn
/* upcall-misaligned.c. Test of Or1ksim misaligned handling of upcalls
2
 
3
   Copyright (C) 2010 Embecosm Limited
4
 
5
   Contributors various OpenCores participants
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of OpenRISC 1000 Architectural Simulator.
9
 
10
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14
 
15
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http:  www.gnu.org/licenses/>.  */
22
 
23
/* ----------------------------------------------------------------------------
24
   This code is commented throughout for use with Doxygen.
25
   --------------------------------------------------------------------------*/
26
 
27
#include "support.h"
28
#include "spr-defs.h"
29
#include "board.h"
30
 
31
 
32
/*!Alignment exception handler defined here. */
33
unsigned long excpt_align;
34
 
35
/*!Flag set if we get a misaligned access */
36
static int  misaligned_p;
37
 
38
/* --------------------------------------------------------------------------*/
39
/*!Write a memory mapped byte register
40
 
41
   Report the result, noting if we get a misalignment exception.
42
 
43
   @param[in] addr   Memory mapped address
44
   @param[in] value  Value to set                                            */
45
/* --------------------------------------------------------------------------*/
46
static void
47
setreg8 (unsigned long int  addr,
48
         unsigned char      value)
49
{
50
  *((volatile unsigned char *) addr) = value;
51
 
52
  if (misaligned_p)
53
    {
54
      printf ("Writing byte at 0x%08lx: misalignment exception.\n", addr);
55
      misaligned_p = 0;
56
    }
57
  else
58
    {
59
      printf ("Wrote byte at 0x%08lx = 0x%02x.\n", addr, value);
60
    }
61
}       /* setreg8 () */
62
 
63
 
64
/* --------------------------------------------------------------------------*/
65
/*!Write a memory mapped half word register
66
 
67
   Report the result, noting if we get a misalignment exception.
68
 
69
   @param[in] addr   Memory mapped address
70
   @param[in] value  Value to set                                            */
71
/* --------------------------------------------------------------------------*/
72
static void
73
setreg16 (unsigned long int   addr,
74
          unsigned short int  value)
75
{
76
  *((volatile unsigned short int *) addr) = value;
77
 
78
  if (misaligned_p)
79
    {
80
      printf ("Writing half word at 0x%08lx: misalignment exception.\n", addr);
81
      misaligned_p = 0;
82
    }
83
  else
84
    {
85
      printf ("Wrote half word at 0x%08lx = 0x%04x.\n", addr, value);
86
    }
87
}       /* setreg16 () */
88
 
89
 
90
/* --------------------------------------------------------------------------*/
91
/*!Write a memory mapped full word register
92
 
93
   Report the result, noting if we get a misalignment exception.
94
 
95
   @param[in] addr   Memory mapped address
96
   @param[in] value  Value to set                                            */
97
/* --------------------------------------------------------------------------*/
98
static void
99
setreg32 (unsigned long int  addr,
100
          unsigned long int  value)
101
{
102
  *((volatile unsigned long int *) addr) = value;
103
 
104
  if (misaligned_p)
105
    {
106
      printf ("Writing full word at 0x%08lx: misalignment exception.\n", addr);
107
      misaligned_p = 0;
108
    }
109
  else
110
    {
111
      printf ("Wrote full word at 0x%08lx = 0x%08lx.\n", addr, value);
112
    }
113
}       /* setreg32 () */
114
 
115
 
116
/* --------------------------------------------------------------------------*/
117
/*!Read a memory mapped byte register
118
 
119
   Report the result, noting if we get a misalignment exception.
120
 
121
   @param[in] addr   Memory mapped address
122
 
123
   @return  Value read                                                       */
124
/* --------------------------------------------------------------------------*/
125
unsigned char
126
getreg8 (unsigned long int  addr)
127
{
128
  unsigned char  res = *((volatile unsigned char *) addr);
129
 
130
  if (misaligned_p)
131
    {
132
      printf ("Reading byte at 0x%08lx: misalignment exception.\n", addr);
133
      misaligned_p = 0;
134
    }
135
  else
136
    {
137
      printf ("Read byte at 0x%08lx = 0x%02x.\n", addr, res);
138
    }
139
 
140
  return  res;
141
 
142
}       /* getreg8 () */
143
 
144
 
145
/* --------------------------------------------------------------------------*/
146
/*!Read a memory mapped half word register
147
 
148
   Report the result, noting if we get a misalignment exception.
149
 
150
   @param[in] addr   Memory mapped address
151
 
152
   @return  Value read                                                       */
153
/* --------------------------------------------------------------------------*/
154
unsigned short int
155
getreg16 (unsigned long int  addr)
156
{
157
  unsigned short int  res = *((volatile unsigned short int *) addr);
158
 
159
  if (misaligned_p)
160
    {
161
      printf ("Reading half word at 0x%08lx: misalignment exception.\n", addr);
162
      misaligned_p = 0;
163
    }
164
  else
165
    {
166
      printf ("Read half word at 0x%08lx = 0x%04x.\n", addr, res);
167
    }
168
 
169
  return  res;
170
 
171
}       /* getreg16 () */
172
 
173
 
174
/* --------------------------------------------------------------------------*/
175
/*!Read a memory mapped full word register
176
 
177
   Report the result, noting if we get a misalignment exception.
178
 
179
   @param[in] addr   Memory mapped address
180
 
181
   @return  Value read                                                       */
182
/* --------------------------------------------------------------------------*/
183
unsigned long int
184
getreg32 (unsigned long int  addr)
185
{
186
  unsigned long int  res = *((volatile unsigned long int *) addr);
187
 
188
  if (misaligned_p)
189
    {
190
      printf ("Reading full word at 0x%08lx: misalignment exception.\n", addr);
191
      misaligned_p = 0;
192
    }
193
  else
194
    {
195
      printf ("Read full word at 0x%08lx = 0x%08lx.\n", addr, res);
196
    }
197
 
198
  return  res;
199
 
200
}       /* getreg32 () */
201
 
202
 
203
/* --------------------------------------------------------------------------*/
204
/*!Exception handler for misalignment.
205
 
206
   Set the flag to indicated we have hit an exception.
207
 
208
   We can't just return, since that will give us the instruction that caused
209
   the problem in the first place. What we do instead is patch the EPCR SPR.
210
 
211
   This is fine, so long as we didn't trap in a delay slot. The crude response
212
   to that then we just exit.                                                */
213
/* --------------------------------------------------------------------------*/
214
void align_handler (void)
215
{
216
  misaligned_p = 1;
217
 
218
  unsigned long int  iaddr = mfspr (SPR_EPCR_BASE);
219
  unsigned long int  instr = *(unsigned long int *) iaddr;
220
  unsigned char      opc   = instr >> 26;
221
 
222
  switch (opc)
223
    {
224
    case 0x00:                  /* l.j    */
225
    case 0x01:                  /* l.jal  */
226
    case 0x03:                  /* l.bnf  */
227
    case 0x04:                  /* l.bf   */
228
    case 0x11:                  /* l.jr   */
229
    case 0x12:                  /* l.jalr */
230
 
231
      printf ("Misalignment exception unable to recover from delay slot.\n");
232
      exit (1);
233
      break;
234
 
235
    default:
236
      mtspr (SPR_EPCR_BASE, iaddr + 4);         /* Step past */
237
      break;
238
    }
239
}       /* align_handler () */
240
 
241
 
242
/* --------------------------------------------------------------------------*/
243
/*!Main program to read and write memory mapped registers
244
 
245
   Some of these are misaligned and should cause the appropriate exception.
246
 
247
   @return  The return code from the program (always zero).                  */
248
/* --------------------------------------------------------------------------*/
249
int
250
main ()
251
{
252
  /* Set the exception handler, and note that no exceptions have yet
253
     happened. */
254
  printf ("Setting alignment exception handler.\n");
255
  excpt_align  = (unsigned long)align_handler;
256
  misaligned_p = 0;
257
 
258
  /* Write some registers */
259
  printf ("Writing registers.\n");
260
 
261
  setreg8 (GENERIC_BASE, 0xde);
262
 
263
  setreg16 (GENERIC_BASE +  2, 0xdead);         /* Aligned */
264
  setreg16 (GENERIC_BASE +  5, 0xbeef);         /* Unaligned */
265
 
266
  setreg32 (GENERIC_BASE +  8, 0xdeadbeef);     /* Aligned */
267
  setreg32 (GENERIC_BASE + 13, 0xcafebabe);     /* Unaligned */
268
  setreg32 (GENERIC_BASE + 18, 0xbaadf00d);     /* Unaligned */
269
  setreg32 (GENERIC_BASE + 23, 0xfee1babe);     /* Unaligned */
270
  setreg32 (GENERIC_BASE + 28, 0xbaadbabe);     /* Aligned */
271
 
272
  /* Write some registers */
273
  printf ("Reading registers.\n");
274
 
275
  (void)getreg8 (GENERIC_BASE);
276
 
277
  (void)getreg16 (GENERIC_BASE +  2);           /* Aligned */
278
  (void)getreg16 (GENERIC_BASE +  5);           /* Unaligned */
279
 
280
  (void)getreg32 (GENERIC_BASE +  8);           /* Aligned */
281
  (void)getreg32 (GENERIC_BASE + 13);           /* Unaligned */
282
  (void)getreg32 (GENERIC_BASE + 18);           /* Unaligned */
283
  (void)getreg32 (GENERIC_BASE + 23);           /* Unaligned */
284
  (void)getreg32 (GENERIC_BASE + 28);           /* Aligned */
285
 
286
  /* We don't actually ever return */
287
  report (0xdeaddead);
288
  return 0;
289
 
290
}       /* main () */

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.