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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [sparclite/] [sleb/] [v2_0/] [tests/] [slebintr.c] - Blame information for rev 27

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

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

powered by: WebSVN 2.1.0

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