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

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [or1ksim/] [testbench/] [tick.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1540 nogj
/* tick.c -- Tests all aspects of the tick timer
2
   Copyright (C) 2005 György `nog' Jeney, nog@sdf.lonestar.org
3
 
4
This file is part of OpenRISC 1000 Architectural Simulator.
5
 
6
This program is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2 of the License, or
9
(at your option) any later version.
10
 
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
GNU General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with this program; if not, write to the Free Software
18
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
19
 
20
#include "spr_defs.h"
21
#include "support.h"
22
 
23
#define ASSERT(x) ((x)? printf(" Test succeeded %s:%i\n", __FILE__, __LINE__) : fail (__FILE__, __LINE__))
24
 
25
void fail (char *func, int line)
26
{
27
#ifndef __FUNCTION__
28
#define __FUNCTION__ "?"
29
#endif
30
  printf ("Test failed in %s:%i\n", func, line);
31
  report(0xeeeeeeee);
32
  exit (1);
33
}
34
 
35
static volatile int tick_cnt = 0;
36
static int clear_ip = 1;
37
 
38
void tick_int(void)
39
{
40
  int ttcr = mfspr(SPR_TTCR);
41
  int ttmr = mfspr(SPR_TTMR);
42
 
43
  /* Make sure that the tick timer interrupt pending bit is set */
44
  ASSERT(mfspr(SPR_TTMR) & SPR_TTMR_IP);
45
 
46
  tick_cnt++;
47
 
48
  /* Clear interrupt (Write a 0 to SPR_TTMR_IP) */
49
  /* If we programmed a one-shot timer, make sure to disable the interrupts,
50
   * else we'd get a spurious interrupt */
51
  if((ttmr & SPR_TTMR_M) != 0x80000000)
52
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~SPR_TTMR_IP);
53
  else
54
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~(SPR_TTMR_IP | SPR_TTMR_IE));
55
}
56
 
57
void tick_int_spurious(void)
58
{
59
  /* Make sure that the tick timer interrupt pending bit is set */
60
  ASSERT(mfspr(SPR_TTMR) & SPR_TTMR_IP);
61
 
62
  /* Clear interrupt (Write a 0 to SPR_TTMR_IP) */
63
  if(clear_ip)
64
    mtspr(SPR_TTMR, mfspr(SPR_TTMR) & ~SPR_TTMR_IP);
65
 
66
  /* Make sure we actually get a spurious interrupt */
67
  if(++tick_cnt == 5)
68
    /* We should get spurious tick interrupts so disable it */
69
    mtspr(SPR_TTMR, 0);
70
}
71
 
72
/* Does nothing for a small amount of time (waiting for TTCR to increment) */
73
void waste_time(void)
74
{
75
  int i;
76
  volatile int x;
77
 
78
  for(i = 0; i < 50; i++)
79
    x = i;
80
}
81
 
82
/* Waits for a tick timer exception */
83
void wait_match(void)
84
{
85
  while(!tick_cnt);
86
  tick_cnt = 0;
87
}
88
 
89
int main()
90
{
91
  int ttcr;
92
 
93
  excpt_tick = (unsigned long)tick_int;
94
 
95
  /* Enable tick interrupt */
96
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
97
 
98
  /* Disable timer */
99
  mtspr(SPR_TTMR, 0);
100
 
101
  mtspr(SPR_TTCR, 0);
102
 
103
  /* Waste some time to check if the timer is really disabled */
104
  waste_time();
105
 
106
  /* Timer is disabled and shouldn't count, TTCR should still be 0 */
107
  ASSERT(mfspr(SPR_TTCR) == 0);
108
 
109
  /* Start timer in continous timeing mode.  Enable timer interrupt and set the
110
   * value to match */
111
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x100);
112
 
113
  /* Wait for the timer to count up to the match value */
114
  wait_match();
115
 
116
  ttcr = mfspr(SPR_TTCR);
117
 
118
  waste_time();
119
 
120
  /* The timer should have kept counting and our saved ttcr should not be the
121
   * same as SPR_TTCR */
122
  ASSERT(ttcr < mfspr(SPR_TTCR));
123
 
124
  mtspr(SPR_TTMR, 0);
125
  ttcr = mfspr(SPR_TTCR);
126
  /* Restart the timer */
127
  mtspr(SPR_TTMR, (3 << 30));
128
  waste_time();
129
  /* The timer should have carried on from what was SPR_TTCR when we started it.
130
   */
131
  ASSERT(ttcr < mfspr(SPR_TTCR));
132
 
133
  mtspr(SPR_TTMR, 0);
134
  ttcr = mfspr(SPR_TTCR);
135
  waste_time();
136
  /* Timer should be disabled and should not have counted */
137
  ASSERT(ttcr == mfspr(SPR_TTCR));
138
 
139
  /* Stop the timer when a match occured */
140
  mtspr(SPR_TTCR, 0);
141
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
142
 
143
  wait_match();
144
  ttcr = mfspr(SPR_TTCR);
145
  waste_time();
146
  /* The timer should have stoped and thus SPR_TTCR sould = ttcr */
147
  ASSERT(ttcr == mfspr(SPR_TTCR));
148
 
149
  /* The counter should still indicate one-shot mode */
150
  ASSERT((mfspr(SPR_TTMR) >> 30) == 2);
151
 
152
  /* Set auto-restarting timer */
153
  mtspr(SPR_TTMR, 0);
154
  mtspr(SPR_TTCR, 0);
155
  mtspr(SPR_TTMR, (1 << 30) | SPR_TTMR_IE | 0x1000);
156
  wait_match();
157
  ttcr = mfspr(SPR_TTCR);
158
  wait_match();
159
 
160
  /* Disable timer */
161
  mtspr(SPR_TTMR, 0);
162
 
163
  /* Start a one-shot counter but keep interrupts disabled */
164
  mtspr(SPR_TTCR, 0);
165
  mtspr(SPR_TTMR, (2 << 30) | 0x100);
166
 
167
  /* Wait for the counter to stop */
168
  while(mfspr(SPR_TTCR) != 0x100);
169
  /* Make sure the counter has actually stopped */
170
  waste_time();
171
  ASSERT(mfspr(SPR_TTCR) == 0x100);
172
  ASSERT(tick_cnt == 0);
173
 
174
  /* SPR_TTMR_IP should not be set */
175
  ASSERT(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
176
 
177
  /* Start a perpetual counter (makeing sure that no interrupts occur while it's
178
   * counting) */
179
  mtspr(SPR_TTMR, 0);
180
  mtspr(SPR_TTCR, 0);
181
  mtspr(SPR_TTMR, (3 << 30) | 0x100);
182
  while(mfspr(SPR_TTCR) < 0x100);
183
  waste_time();
184
  ASSERT(mfspr(SPR_TTCR) > 0x100);
185
  ASSERT(tick_cnt == 0);
186
  ASSERT(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
187
 
188
  /* Disable the timer interrupt */
189
  mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
190
 
191
  /* Set one-shot timer */
192
  mtspr(SPR_TTCR, 0);
193
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
194
  while(!(mfspr(SPR_TTMR) & SPR_TTMR_IP));
195
  /* Give some time for a potential interrupt to occur */
196
  waste_time();
197
  /* No interrupt should have occured */
198
  ASSERT(tick_cnt == 0);
199
 
200
  /* Enable tick interrupt */
201
  mtspr(SPR_SR, mfspr(SPR_SR) | SPR_SR_TEE);
202
 
203
  /* Test Setting TTCR while counting */
204
  mtspr(SPR_TTMR, 0);
205
  mtspr(SPR_TTCR, 0);
206
  mtspr(SPR_TTMR, (3 << 30) | 0x3000);
207
  while(mfspr(SPR_TTCR) < 0x30000);
208
  waste_time();
209
  mtspr(SPR_TTCR, 0x50);
210
  waste_time();
211
  ttcr = mfspr(SPR_TTCR);
212
  ASSERT(ttcr > 0x50 && ttcr < 0x30000);
213
  mtspr(SPR_TTMR, 0);
214
 
215
  /* Set ttcr to a high value */
216
  mtspr(SPR_TTCR, 0x20000);
217
  /* Now, start timer in one-shot mode */
218
  mtspr(SPR_TTMR, (2 << 30) | SPR_TTMR_IE | 0x100);
219
 
220
  /* The counter should start counting from 0x20000 and wrap around to 0x100
221
   * causeing an interrupt */
222
  waste_time();
223
  ASSERT(mfspr(SPR_TTCR) > 0x20000);
224
  wait_match();
225
 
226
  ASSERT(1);
227
 
228
  /* If TTCR is greater than TTMR_PERIOD then the interrupt gets delivered after
229
   * TTCR wraps around to 0 and counts to SPR_TTMR_PERIOD */
230
  mtspr(SPR_TTMR, 0);
231
  mtspr(SPR_TTCR, 0xffffc00);
232
  mtspr(SPR_TTMR, (1 << 30) | SPR_TTMR_IE | 0x10000);
233
  wait_match();
234
 
235
  ASSERT(1);
236
 
237
  /* test continuous mode */
238
  mtspr(SPR_TTMR, 0);
239
  mtspr(SPR_TTCR, 0xffffc00);
240
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x10000);
241
  wait_match();
242
  mtspr(SPR_TTMR, 0);
243
 
244
  ASSERT(1);
245
 
246
  excpt_tick = (unsigned long)tick_int_spurious;
247
 
248
  /* Make sure sure that TTMR_PERIOD is not 0!! */
249
  mtspr(SPR_TTMR, 1);
250
  /* Set SPR_TTMR_PERIOD to some value, while keeping the timer disabled */
251
  mtspr(SPR_TTCR, 0);
252
  mtspr(SPR_TTMR, SPR_TTMR_IE | 0x100);
253
 
254
  /* Set SPR_TTCR with the same value */
255
  mtspr(SPR_TTCR, 0x100);
256
 
257
  while(tick_cnt != 5);
258
  tick_cnt = 0;
259
  ASSERT(mfspr(SPR_TTCR) == 0x100);
260
 
261
  /* Test setting TTCR first then TTMR */
262
  mtspr(SPR_TTCR, 0x101);
263
  mtspr(SPR_TTMR, SPR_TTMR_IE | 0x101);
264
 
265
  while(tick_cnt != 5);
266
  tick_cnt = 0;
267
  ASSERT(mfspr(SPR_TTCR) == 0x101);
268
 
269
  /* Set countinous counter, but make sure we never clear the TTMR_IP bit */
270
  clear_ip = 0;
271
  mtspr(SPR_TTCR, 0);
272
  mtspr(SPR_TTMR, (3 << 30) | SPR_TTMR_IE | 0x100);
273
 
274
  while(tick_cnt != 5);
275
 
276 1566 nogj
  report(0xdeaddead);
277 1540 nogj
  return 0;
278
}
279
 

powered by: WebSVN 2.1.0

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