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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [sparclite/] [sleb/] [current/] [tests/] [slebintr.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
/*=================================================================
2
//
3
//        slebintr.c
4
//
5
//        SPARClite HAL interrupt manipulation test
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later
16
// version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
26
//
27
// As a special exception, if other files instantiate templates or use
28
// macros or inline functions from this file, or you compile this file
29
// and link it with other works to produce a work based on this file,
30
// this file does not by itself cause the resulting work to be covered by
31
// the GNU General Public License. However the source code for this file
32
// must still be made available in accordance with section (3) of the GNU
33
// General Public License v2.
34
//
35
// This exception does not invalidate any other reasons why a work based
36
// on this file might be covered by the GNU General Public License.
37
// -------------------------------------------
38
// ####ECOSGPLCOPYRIGHTEND####
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     dsm
43
// Contributors:    dsm, nickg
44
// Date:          1998-06-18
45
//####DESCRIPTIONEND####
46
*/
47
 
48
#include <pkgconf/system.h>
49
 
50
#include <pkgconf/hal.h>
51
 
52
#include <cyg/infra/cyg_type.h>
53
 
54
#include <cyg/infra/cyg_ass.h>
55
 
56
#include <cyg/infra/testcase.h>
57
 
58
#include <cyg/hal/hal_arch.h>
59
#include <cyg/hal/hal_intr.h>
60
#include <cyg/hal/hal_diag.h>
61
#include <cyg/hal/hal_clock.h>
62
 
63
#include <pkgconf/infra.h>
64
 
65
#include <cyg/infra/diag.h>
66
 
67
#define DELAY(x) \
68
    CYG_MACRO_START int i; for (i = 0; i < x; i++); CYG_MACRO_END
69
 
70
#define DLA 100
71
 
72
static int l, u, m, j;
73
 
74
int levels[ 16 ];
75
int    ups[ 16 ];
76
int  masks[ 16 ];
77
int   reqs[ 16 ];
78
 
79
#define XDIGIT( q ) (q + ((q < 10) ? '0' : ('A'-10) ))
80
 
81
#define SETSTR( x, y, str ) CYG_MACRO_START \
82
        str[0] = XDIGIT( x ); \
83
        str[1] = XDIGIT( y ); \
84
CYG_MACRO_END
85
 
86
static char lstr[] = "xy Bad level";
87
static char mstr[] = "xy Bad  mask";
88
static char ustr[] = "xy Bad    up";
89
 
90
 
91
static void checkallbut( int z )
92
{
93
    int i;
94
    for ( i = 1; i < 16; i++ ) {
95
        int level, up, hipri, mask, req;
96
        if ( z == i )
97
            continue;
98
 
99
        SETSTR( i, z, lstr );
100
        SETSTR( i, z, mstr );
101
        SETSTR( i, z, ustr );
102
 
103
        HAL_INTERRUPT_QUERY_INFO( i, level, up, hipri, mask, req);
104
        l = level;
105
        u = up;
106
        m = mask;
107
        j = i;
108
 
109
#if 0 // for manual testing really...
110
        if ( level != levels[i] )
111
            CYG_TEST_INFO( lstr );
112
        if (    up !=    ups[i] )
113
            CYG_TEST_INFO( ustr );
114
        if (  mask !=  masks[i] )
115
            CYG_TEST_INFO( mstr );
116
        if ( (level != levels[i] )
117
        |    (   up !=    ups[i] )
118
        |    ( mask !=  masks[i] ) ) {
119
            CYG_TEST_INFO( "Re-reading" );
120
            HAL_INTERRUPT_QUERY_INFO( i, level, up, hipri, mask, req);
121
        }
122
#endif
123
        CYG_TEST_CHECK( level == levels[i], lstr );
124
        CYG_TEST_CHECK(    up ==    ups[i], ustr );
125
        CYG_TEST_CHECK(  mask ==  masks[i], mstr );
126
    }
127
}
128
 
129
// input is the active phase of the chosen interrupt.  It is assumed that
130
// the source is normally level-sensititve rather than edge-sensitive.
131
static void interferewith( int which, int input )
132
{
133
    int level, up, hipri, mask, req;
134
 
135
    // Interfere with interrupt 'which'
136
    HAL_INTERRUPT_CONFIGURE( which, 1, input ); // should be no change
137
 
138
    checkallbut( 0 ); // so don't exclude any of them
139
 
140
    HAL_INTERRUPT_CONFIGURE( which, 1, !input ); // make it other-sensitive
141
    DELAY( DLA );
142
    HAL_INTERRUPT_ACKNOWLEDGE( which );
143
    DELAY( DLA );
144
    HAL_INTERRUPT_QUERY_INFO( which, level, up, hipri, mask, req);
145
    CYG_TEST_CHECK( 0 != level , "Int not level-sensitive (-ve level)" );
146
    if ( input )
147
        CYG_TEST_CHECK( 0 == up, "Int high level (-ve level)" );
148
    else
149
        CYG_TEST_CHECK( 0 != up, "Int low level (-ve level)" );
150
    CYG_TEST_CHECK( 0 !=  mask , "Int unmasked (-ve level)" );
151
    CYG_TEST_CHECK( 0 !=   req , "Int not requesting (-ve level)" );
152
    checkallbut( which ); // don't check #which, we're messing with it
153
 
154
    HAL_INTERRUPT_CONFIGURE( which, 0, input ); // edge, default sense
155
    DELAY( DLA );
156
    HAL_INTERRUPT_ACKNOWLEDGE( which );
157
    DELAY( DLA );
158
    HAL_INTERRUPT_QUERY_INFO( which, level, up, hipri, mask, req);
159
    CYG_TEST_CHECK( 0 == level , "Int not edge-sensitive (+ve edge)" );
160
    if ( input )
161
        CYG_TEST_CHECK( 0 != up, "Int low edge (+ve edge)" );
162
    else
163
        CYG_TEST_CHECK( 0 == up, "Int high edge (+ve edge)" );
164
    CYG_TEST_CHECK( 0 !=  mask , "Int unmasked (+ve edge)" );
165
    CYG_TEST_CHECK( 0 ==   req , "Int requesting (+ve edge)" );
166
    checkallbut( which ); // don't check #which, we're messing with it
167
 
168
    HAL_INTERRUPT_CONFIGURE( which, 0, !input ); // edge, opposite sense
169
    DELAY( DLA );
170
    HAL_INTERRUPT_ACKNOWLEDGE( which );
171
    DELAY( DLA );
172
    HAL_INTERRUPT_QUERY_INFO( which, level, up, hipri, mask, req);
173
    CYG_TEST_CHECK( 0 == level , "Int not edge-sensitive (-ve edge)" );
174
    if ( input )
175
        CYG_TEST_CHECK( 0 == up, "Int high edge (-ve edge)" );
176
    else
177
        CYG_TEST_CHECK( 0 != up, "Int low edge (-ve edge)" );
178
    CYG_TEST_CHECK( 0 !=  mask , "Int unmasked (-ve edge)" );
179
    CYG_TEST_CHECK( 0 ==   req , "Int requesting (-ve edge)" );
180
    checkallbut( which ); // don't check #which, we're messing with it
181
 
182
    HAL_INTERRUPT_CONFIGURE( which, 1, input ); // back to original value
183
    DELAY( DLA );
184
    HAL_INTERRUPT_ACKNOWLEDGE( which );
185
    DELAY( DLA );
186
    checkallbut( 0 ); // so don't exclude any of them
187
}
188
 
189
// ------------------------------------------------------------------------
190
 
191
#ifndef CYGPKG_KERNEL
192
// then the clock is not initialized!
193
#undef HAL_CLOCK_READ
194
// so provide a dumb counter, so we do the test a number of times anyway.
195
static int pseudotime = 0;
196
#define HAL_CLOCK_READ( _pval_ ) *(_pval_) = \
197
   ((pseudotime > 10) ? (pseudotime = 0) : ++pseudotime)
198
#endif
199
 
200
static int start( void )
201
{
202
    // We'll mess about with these interrupt sources:
203
    // 13   : EX_IRQ13 from expansion board, active HIGH
204
    // 12   : EX_IRQ12 from expansion board, active LOW
205
    //  4   : EX_IRQ4 from expansion board, active LOW
206
    //  3   : EX_IRQ3 from expansion board, active HIGH
207
 
208
    int i, hipri;
209
    for ( i = 1; i < 16; i++ ) {
210
        HAL_INTERRUPT_QUERY_INFO( i, levels[i], ups[i],
211
                                  hipri, masks[i], reqs[i]);
212
    }
213
    CYG_TEST_CHECK( 0 !=  masks[13], "Int 13 unmasked initially" );
214
    CYG_TEST_CHECK( 0 !=  masks[12], "Int 12 unmasked initially" );
215
    CYG_TEST_CHECK( 0 !=  masks[ 4], "Int  4 unmasked initially" );
216
    CYG_TEST_CHECK( 0 !=  masks[ 3], "Int  3 unmasked initially" );
217
    CYG_TEST_CHECK( 0 ==   reqs[13], "Int 13 requests initially" );
218
    CYG_TEST_CHECK( 0 ==   reqs[12], "Int 12 requests initially" );
219
    CYG_TEST_CHECK( 0 ==   reqs[ 4], "Int  4 requests initially" );
220
    CYG_TEST_CHECK( 0 ==   reqs[ 3], "Int  3 requests initially" );
221
    CYG_TEST_CHECK( 0 != levels[13], "Int 13 edgetrig initially" );
222
    CYG_TEST_CHECK( 0 != levels[12], "Int 12 edgetrig initially" );
223
    CYG_TEST_CHECK( 0 != levels[ 4], "Int  4 edgetrig initially" );
224
    CYG_TEST_CHECK( 0 != levels[ 3], "Int  3 edgetrig initially" );
225
    CYG_TEST_CHECK( 0 !=    ups[13], "Int 13 not up initially" );
226
    CYG_TEST_CHECK( 0 ==    ups[12], "Int 12 is up initially" );
227
    CYG_TEST_CHECK( 0 ==    ups[ 4], "Int  4 is up initially" );
228
    CYG_TEST_CHECK( 0 !=    ups[ 3], "Int  3 not up initially" );
229
 
230
    checkallbut( 0 ); // don't exclude any of them
231
 
232
    // I want to run this loop for 100 centiSeconds, so that 100 clock
233
    // interrupts have occurred whilst interfering with the other interrupt
234
    // state, to provoke possible problems with interactions there.  On a
235
    // 100MHz 86832 with default configuration, this usually gives 1200
236
    // loops in total, 12 per centiSecond.  But with config variance and
237
    // caching behaviour, it's quite possible for this loop to take much
238
    // longer, if it takes over 1/2 a centiSecond, aliasing effects could
239
    // cause the timing to fail completely, causing test timeouts.  Hence
240
    // the additional loop limit of 20 times round the inner loop, aiming
241
    // for a maximum elapsed time of 20 S maximum, plus extra chances to
242
    // break out part way through the loop if a tick has passed.
243
 
244
    hipri = 0;
245
    CYG_TEST_INFO( "About to configure interrupts" );
246
    for ( i = 0; i < 100; i++ ) {
247
        int t1, t2, j;
248
        HAL_CLOCK_READ( &t1 );
249
        // Do this while/until there is a clock tick
250
        // ie. some interrupt activity:
251
        for ( j = 0; j < 20; j++ ) {
252
            t2 = t1;
253
            hipri++;
254
            interferewith( 13, 1 );
255
            interferewith( 3, 1 );
256
            interferewith( 4, 0 );
257
            HAL_CLOCK_READ( &t1 );
258
            if ( t1 < t2 )
259
                break;                  // clock has wrapped
260
            t2 = t1;
261
            interferewith( 12, 0 );
262
            interferewith( 3, 1 );
263
            interferewith( 3, 1 );
264
            HAL_CLOCK_READ( &t1 );
265
            if ( t1 < t2 )
266
                break;                  // clock has wrapped
267
            t2 = t1;
268
            interferewith( 4, 0 );
269
            interferewith( 13, 1 );
270
            interferewith( 12, 0 );
271
            interferewith( 12, 0 );
272
            HAL_CLOCK_READ( &t1 );
273
            if ( t1 < t2 )
274
                break;                  // clock has wrapped
275
        }
276
    }
277
    CYG_TEST_PASS( "Configured interrupts 3,4,12 & 13 a great deal" );
278
    return hipri;
279
}
280
 
281
// -------------------------------------------------------------------------
282
 
283
externC void
284
#ifdef CYGPKG_KERNEL
285
cyg_user_start( void )
286
#else
287
cyg_start( void )
288
#endif
289
{
290
    int loops;
291
    CYG_TEST_INIT();
292
    CYG_TEST_INFO( "cyg_user_start()" );
293
    HAL_ENABLE_INTERRUPTS();
294
    loops = start();
295
    // Typically about 1200 loops execute on the 33MHz 86832;
296
    // I hoped to put in a check that we hadn't wasted time in
297
    // spurious interrupts, but kernel instrumentation, for example,
298
    // is more than enough to slow the world down... so keep this
299
    // very weak test in, as a placeholder.
300
    CYG_TEST_CHECK( 100 <= loops, "Not enough tests executed" );
301
    CYG_TEST_EXIT( "All done" );
302
}
303
 
304
// -------------------------------------------------------------------------
305
 
306
/* EOF slebintr.c */

powered by: WebSVN 2.1.0

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