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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [services/] [power/] [common/] [v2_0/] [tests/] [powertest.cxx] - Blame information for rev 591

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

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      powertest.cxx
4
//
5
//      Testcase for the power management support.
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):    bartv
44
// Contributors: bartv
45
// Date:         2001-07-29
46
//
47
// This testcase checks most of the functionality of the power management
48
// package. The main exception is the POWER_CONTROLLER_CPU macro and
49
// the power_controller_cpu variable: that controller may or may not be
50
// provided by one of the HAL packages, so attempting to manipulate that
51
// HAL could cause link-time conflicts.
52
//
53
// The testcase is likely to fail if some package supplies a policy
54
// module that is making concurrent calls, for example if that module
55
// installs its own callback. For now there is no way of detecting
56
// that scenario, but also for now policy modules are assumed to be
57
// provided by the application rather than by any eCos package.
58
//
59
//####DESCRIPTIONEND####
60
//
61
//==========================================================================
62
 
63
#include <pkgconf/system.h>
64
#include <pkgconf/power.h>
65
#include <cyg/infra/cyg_type.h>
66
#include <cyg/infra/cyg_ass.h>
67
#include <cyg/infra/testcase.h>
68
#include <cyg/hal/hal_arch.h>
69
#include <cyg/power/power.h>
70
 
71
#ifdef CYGPKG_KERNEL
72
// Additional #include's to support the use of multiple threads.
73
#include <cyg/kernel/kapi.h>
74
#include <cyg/kernel/sched.hxx>
75
#endif
76
 
77
// Additional prototypes. These are builtins, but in some configurations
78
// the relevant headers may not be present.
79
extern "C" int strcmp(const char*, const char*);
80
 
81
// ----------------------------------------------------------------------------
82
// Define the various tests in the system. This allows the power controllers
83
// and the policy callback to take appropriate action as required.
84
enum PowerTest {
85
    PowerTest_Presence,
86
    PowerTest_Order,
87
    PowerTest_InitialState,
88
    PowerTest_Ids
89
} current_test;
90
 
91
// ----------------------------------------------------------------------------
92
// Statics.
93
#ifdef CYGPKG_KERNEL
94
static unsigned char    policy_thread_stack[CYGNUM_HAL_STACK_SIZE_TYPICAL];
95
static cyg_thread       policy_thread;
96
static cyg_handle_t     policy_thread_handle;
97
#endif
98
 
99
// ----------------------------------------------------------------------------
100
// Provide three power controllers at different priorities.
101
static void xyzzy_power_controller_fn(PowerController*, PowerMode, PowerModeChange);
102
static void wumpus_power_controller_fn(PowerController*, PowerMode, PowerModeChange);
103
static void erwin_power_controller_fn(PowerController*, PowerMode, PowerModeChange);
104
 
105
POWER_CONTROLLER(xyzzy_controller,  PowerPri_Early,   "xyzzy",  &xyzzy_power_controller_fn);
106
POWER_CONTROLLER(wumpus_controller, PowerPri_Typical, "wumpus", &wumpus_power_controller_fn);
107
POWER_CONTROLLER(erwin_controller,  PowerPri_Late,    "erwin",  &erwin_power_controller_fn);
108
 
109
// ----------------------------------------------------------------------------
110
// The test cases.
111
 
112
// Check that all three power controllers are actually present in the array.
113
static void
114
test_presence(void)
115
{
116
    bool                seen_xyzzy  = false;
117
    bool                seen_wumpus = false;
118
    bool                seen_erwin  = false;
119
    PowerController*    controller;
120
 
121
    for (controller = &(__POWER__[0]); controller != &__POWER_END__; controller++) {
122
        if (controller == &xyzzy_controller) {
123
            CYG_ASSERTC(!seen_xyzzy);
124
            seen_xyzzy = true;
125
        } else if (controller == &wumpus_controller) {
126
            CYG_ASSERTC(!seen_wumpus);
127
            seen_wumpus = true;
128
        } else if (controller == &erwin_controller) {
129
            CYG_ASSERTC(!seen_erwin);
130
            seen_erwin = true;
131
        }
132
    }
133
 
134
    if (seen_xyzzy && seen_wumpus && seen_erwin) {
135
        CYG_TEST_PASS("All expected controllers found");
136
    } else {
137
        CYG_TEST_FAIL_FINISH("Failed to find all the controllers that should be present");
138
    }
139
}
140
 
141
// Now check that the controllers appear in the expected order.
142
static void
143
test_order(void)
144
{
145
    int                 xyzzy_index  = -1;
146
    int                 wumpus_index = -1;
147
    int                 erwin_index  = -1;
148
    int                 i;
149
 
150
    for (i = 0; &(__POWER__[i]) != &__POWER_END__; i++) {
151
        if (&__POWER__[i] == &xyzzy_controller) {
152
            CYG_ASSERTC(-1 == xyzzy_index);
153
            xyzzy_index = i;
154
        } else if (&__POWER__[i] == &wumpus_controller) {
155
            CYG_ASSERTC(-1 == wumpus_index);
156
            wumpus_index = i;
157
        } else if (&__POWER__[i] == &erwin_controller) {
158
            CYG_ASSERTC(-1 == erwin_index);
159
            erwin_index = i;
160
        }
161
    }
162
    CYG_ASSERTC(-1 != xyzzy_index);
163
    CYG_ASSERTC(-1 != wumpus_index);
164
    CYG_ASSERTC(-1 != erwin_index);
165
 
166
    if ((xyzzy_index < wumpus_index) && (wumpus_index < erwin_index)) {
167
        CYG_TEST_PASS("The power controllers are in the correct order");
168
    } else {
169
        CYG_TEST_FAIL_FINISH("The power controllers are not in the correct order");
170
    }
171
}
172
 
173
// Check the initial state of the system. Power controllers other than the ones
174
// defined by this testcase are ignored, since conceivably they might well come
175
// up in a mode other than active.
176
static void
177
test_initial_state(void)
178
{
179
    bool    test_ok = true;
180
    // There have been no calls to change power mode, so the system should be active
181
    if (PowerMode_Active != power_get_mode()) {
182
        CYG_TEST_FAIL("Initial power mode not active");
183
        test_ok = false;
184
    }
185
    if (PowerMode_Active != power_get_desired_mode()) {
186
        CYG_TEST_FAIL("Initial desired power mode not active");
187
        test_ok = false;
188
    }
189
    if ((void (*)(PowerController*, PowerMode, PowerMode, PowerMode, PowerMode)) 0 != power_get_policy_callback()) {
190
        CYG_TEST_FAIL("A policy callback has already been installed");
191
        test_ok = false;
192
    }
193
 
194
    if ((PowerMode_Active != power_get_controller_mode(&xyzzy_controller))  ||
195
        (PowerMode_Active != power_get_controller_mode(&wumpus_controller)) ||
196
        (PowerMode_Active != power_get_controller_mode(&erwin_controller))) {
197
        CYG_TEST_FAIL("Not all power controllers initialized to active");
198
        test_ok = false;
199
    }
200
    if ((PowerMode_Active != power_get_controller_desired_mode(&xyzzy_controller))  ||
201
        (PowerMode_Active != power_get_controller_desired_mode(&wumpus_controller)) ||
202
        (PowerMode_Active != power_get_controller_desired_mode(&erwin_controller))) {
203
        CYG_TEST_FAIL("Not all power controllers initialized to desired active");
204
        test_ok = false;
205
    }
206
 
207
    if (!power_get_controller_attached(&xyzzy_controller)  ||
208
        !power_get_controller_attached(&wumpus_controller) ||
209
        !power_get_controller_attached(&erwin_controller)) {
210
        CYG_TEST_FAIL("Some power controllers started off detached");
211
        test_ok = false;
212
    }
213
 
214
    // The initial policy data is checked in a separate testcase
215
    if (test_ok) {
216
        CYG_TEST_PASS("Initial power management state is as expected");
217
    }
218
}
219
 
220
// If the configuration involves per-controller id's, check them.
221
#ifdef CYGIMP_POWER_PROVIDE_STRINGS
222
static int test_ids_data    = 0;    // avoid problems with over-optimising
223
 
224
static void
225
test_ids(void)
226
{
227
    // All of the power controllers should have a valid id, i.e. it
228
    // should be possible to dereference the pointer. A SEGV here
229
    // probably indicates that a HAL or device driver package has
230
    // failed to supply a sensible string, which is a test failure
231
    // albeit one in that package rather than the power management
232
    // package.
233
    PowerController*    controller;
234
    for (controller = &(__POWER__[0]); controller != &__POWER_END__; controller++) {
235
        const char* id  = power_get_controller_id(controller);
236
        test_ids_data   += id[0];
237
    }
238
 
239
    // In addition the id strings for the three known controllers are also known.
240
    if ((0 == strcmp("xyzzy",  power_get_controller_id(&xyzzy_controller)))  &&
241
        (0 == strcmp("wumpus", power_get_controller_id(&wumpus_controller))) &&
242
        (0 == strcmp("erwin",  power_get_controller_id(&erwin_controller)))) {
243
        CYG_TEST_PASS("Controller id strings match up");
244
    } else {
245
        CYG_TEST_FAIL("Controller id strings fail to match");
246
    }
247
}
248
#else
249
static void
250
test_ids(void)
251
{
252
    CYG_TEST_NA("Unable to test controller ids - this functionaly has been configured out");
253
}
254
#endif
255
// ----------------------------------------------------------------------------
256
// The individual power controller functions. By default these just obey the
257
// requested mode change, but there are some special cases.
258
static void
259
xyzzy_power_controller_fn(PowerController* controller, PowerMode desired_mode, PowerModeChange change)
260
{
261
    switch (current_test) {
262
      default :
263
        controller->mode  = desired_mode;
264
        break;
265
    }
266
}
267
 
268
static void
269
wumpus_power_controller_fn(PowerController* controller, PowerMode desired_mode, PowerModeChange change)
270
{
271
    switch (current_test) {
272
      default :
273
        controller->mode  = desired_mode;
274
        break;
275
    }
276
}
277
 
278
static void
279
erwin_power_controller_fn(PowerController* controller, PowerMode desired_mode, PowerModeChange change)
280
{
281
    switch (current_test) {
282
      default :
283
        controller->mode  = desired_mode;
284
        break;
285
    }
286
}
287
 
288
// ----------------------------------------------------------------------------
289
// The main policy callback. Like the controller functions by default this
290
// does nothing, but for specific tests it has to take action.
291
static void
292
policy_callback(PowerController* controller, PowerMode old_mode, PowerMode current_mode, PowerMode old_desired_mode, PowerMode current_desired_mode)
293
{
294
}
295
 
296
// ----------------------------------------------------------------------------
297
// Utilities.
298
 
299
// Detach all controllers except the ones supplied by this package. It would
300
// be unfortunate if say the cpu stopped running because a test case decided
301
// to set the global mode to off.
302
static void
303
detach_all_controllers(void)
304
{
305
    PowerController*    controller;
306
    for (controller = &(__POWER__[0]); controller != &__POWER_END__; controller++) {
307
        if ((controller != &xyzzy_controller) && (controller != &wumpus_controller) && (controller != &erwin_controller)) {
308
            power_set_controller_attached(controller, false);
309
        }
310
    }
311
}
312
 
313
// ----------------------------------------------------------------------------
314
// The main routine, which acts as the policy module. This either runs as
315
// a separate thread, if the kernel is present, or else it is called
316
// directly from cyg_start().
317
static void
318
powertest_main(CYG_ADDRWORD data)
319
{
320
    CYG_ASSERT(0 == data, "No data should be supplied");
321
 
322
    CYG_TEST_INIT();
323
 
324
    current_test    = PowerTest_Presence;
325
    test_presence();
326
 
327
    current_test    = PowerTest_Order;
328
    test_order();
329
 
330
    current_test    = PowerTest_InitialState;
331
    test_initial_state();
332
 
333
    current_test    = PowerTest_Ids;
334
    test_ids();
335
 
336
    detach_all_controllers();
337
 
338
    CYG_TEST_FINISH("All tests have been run");
339
}
340
 
341
// ----------------------------------------------------------------------------
342
// Test startup.
343
externC void
344
cyg_start(void)
345
{
346
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
347
    cyg_hal_invoke_constructors();
348
#endif
349
 
350
#ifdef CYGPKG_KERNEL
351
    cyg_thread_create(CYG_SCHED_DEFAULT_INFO,
352
                      &powertest_main,
353
                      (cyg_addrword_t) 0,
354
                      "Power policy thread",
355
                      policy_thread_stack,
356
                      CYGNUM_HAL_STACK_SIZE_TYPICAL,
357
                      &policy_thread_handle,
358
                      &policy_thread);
359
    cyg_thread_resume(policy_thread_handle);
360
    Cyg_Scheduler::start();
361
    CYG_TEST_FAIL_FINISH("Not reached");
362
#else    
363
    powertest_main(0);
364
#endif
365
}
366
 
367
 
368
 
369
 

powered by: WebSVN 2.1.0

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