]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/hal/arm/xscale/iq80321/v2_0/src/diag/xscale_test.c
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / xscale / iq80321 / v2_0 / src / diag / xscale_test.c
1 //=============================================================================
2 //
3 //      xscale_test.c - Cyclone Diagnostics
4 //
5 //=============================================================================
6 //####ECOSGPLCOPYRIGHTBEGIN####
7 // -------------------------------------------
8 // This file is part of eCos, the Embedded Configurable Operating System.
9 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
10 //
11 // eCos is free software; you can redistribute it and/or modify it under
12 // the terms of the GNU General Public License as published by the Free
13 // Software Foundation; either version 2 or (at your option) any later version.
14 //
15 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
16 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
18 // for more details.
19 //
20 // You should have received a copy of the GNU General Public License along
21 // with eCos; if not, write to the Free Software Foundation, Inc.,
22 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
23 //
24 // As a special exception, if other files instantiate templates or use macros
25 // or inline functions from this file, or you compile this file and link it
26 // with other works to produce a work based on this file, this file does not
27 // by itself cause the resulting work to be covered by the GNU General Public
28 // License. However the source code for this file must still be made available
29 // in accordance with section (3) of the GNU General Public License.
30 //
31 // This exception does not invalidate any other reasons why a work based on
32 // this file might be covered by the GNU General Public License.
33 //
34 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
35 // at http://sources.redhat.com/ecos/ecos-license/
36 // -------------------------------------------
37 //####ECOSGPLCOPYRIGHTEND####
38 //=============================================================================
39 //#####DESCRIPTIONBEGIN####
40 //
41 // Author(s):   Scott Coulter, Jeff Frazier, Eric Breeden
42 // Contributors: Mark Salter
43 // Date:        2001-01-25
44 // Purpose:     
45 // Description: 
46 //
47 //####DESCRIPTIONEND####
48 //
49 //===========================================================================*/
50
51 /************************************************************************/
52 /*                                                                      */
53 /* Modification History                                                 */
54 /* --------------------                                                 */
55 /* 11oct00, ejb, Created for IQ80310 StrongARM2                         */
56 /* 18dec00  jwf                                                         */
57 /* 02feb01  jwf added tests: _coy_tight_loop, cache_loop, LoopMemTest,  */
58 /*              special_mem_test written by snc                         */     
59 /* 07feb01  jwf added function calls to a variable delay time generator */
60 /* 09feb01  jwf added function version_info to show version information */
61 /*              about OS, BOARD, CPLD, 80200 ID, 80312 ID.              */
62 /************************************************************************/
63
64
65 #include <pkgconf/hal.h>
66 #include <pkgconf/system.h>
67 #include CYGBLD_HAL_PLATFORM_H
68
69 #include <cyg/infra/cyg_type.h>         // base types
70 #include <cyg/infra/cyg_trac.h>         // tracing macros
71 #include <cyg/infra/cyg_ass.h>          // assertion macros
72
73 #include <cyg/hal/hal_io.h>             // IO macros
74 #include <cyg/hal/hal_arch.h>           // Register state info
75 #include <cyg/hal/hal_diag.h>
76 #include <cyg/hal/hal_intr.h>           // Interrupt names
77 #include <cyg/hal/hal_cache.h>
78 #include <cyg/hal/hal_verde.h>          // Hardware definitions
79 #include <cyg/hal/iq80321.h>            // Platform specifics
80
81 #include <cyg/infra/diag.h>             // diag_printf
82 #include <redboot.h>
83 #include <cyg/io/pci.h>
84
85 #include "test_menu.h"
86
87 extern CYG_ADDRWORD hexIn(void);
88
89 extern int memTest (long startAddr, long endAddr);
90 extern int LoopMemTest (long startAddr, long endAddr);
91
92 void hdwr_diag (void);
93
94 extern void enet_setup (MENU_ARG arg);
95
96 static void memory_tests (MENU_ARG arg);
97 static void repeat_mem_test (MENU_ARG arg);
98 static void special_mem_test (MENU_ARG arg);
99 static void rotary_switch (MENU_ARG arg);
100 static void seven_segment_display (MENU_ARG arg);
101 static void cache_loop (MENU_ARG arg);
102 extern void pci_test (MENU_ARG arg);
103 extern void battery_status(MENU_ARG arg);
104 extern void battery_test_menu (MENU_ARG arg);
105 extern void timer_test (MENU_ARG arg);
106
107
108 /* Test Menu Table */
109 static MENU_ITEM testMenu[] =
110 {
111     {"Memory Tests", memory_tests, 0},
112     {"Repeating Memory Tests", repeat_mem_test, 0},
113     {"Repeat-On-Fail Memory Test", special_mem_test, 0},
114     {"Rotary Switch S1 Test", rotary_switch, 0},
115     {"7 Segment LED Tests", seven_segment_display, 0},
116     {"i82544 Ethernet Configuration", enet_setup, 0},
117     {"Battery Status Test", battery_status, 0},
118 #ifdef CYGSEM_HAL_ARM_IQ80321_BATTERY_TEST
119     {"Battery Backup SDRAM Memory Test", battery_test_menu, 0},
120 #endif
121     {"Timer Test", timer_test, 0},
122     {"PCI Bus test", pci_test, 0},
123     {"CPU Cache Loop (No return)", cache_loop, 0}
124 };
125
126 #define NUM_MENU_ITEMS  (sizeof (testMenu) / sizeof (testMenu[0]))
127 #define MENU_TITLE      "\n  IQ80321 Hardware Tests"
128
129 void
130 diag_wait(void)
131 {
132     char buf[1];
133     diag_printf ("Press return to continue.\n");
134     while (_rb_gets(buf, sizeof(buf), 0) != _GETS_OK)
135         ;
136 }
137
138 void
139 hdwr_diag (void)
140 {
141     diag_printf ("Entering Hardware Diagnostics - Disabling Data Cache!\n");
142
143     cyg_pci_init(); 
144
145     HAL_DCACHE_SYNC();
146     HAL_DCACHE_DISABLE();
147         
148     menu (testMenu, NUM_MENU_ITEMS, MENU_TITLE, MENU_OPT_NONE);
149
150     diag_printf ("Exiting Hardware Diagnostics!\n\n");
151     HAL_DCACHE_ENABLE();
152 }
153
154 static void
155 cache_loop (MENU_ARG arg)
156 {
157     diag_printf ("Putting Processor in a Tight Loop Forever...\n\n");
158
159     asm ( "0: mov r0,r0\n"
160           "b 0b\n");
161 }
162
163
164 // ***************************************************************************
165 // memory_tests - Basic Memory Tests                       
166 //
167 // Memory tests can be run one of two ways - with the cache turned OFF to test
168 // physical memory, or with cache turned ON to test the caching
169 //
170 static void
171 memory_tests (MENU_ARG arg)
172 {
173     CYG_ADDRWORD start_addr, end_addr;
174     long mem_size;
175
176     diag_printf("Base address of memory to test (in hex): ");
177     start_addr = hexIn();
178
179     diag_printf ("\nSize of memory to test (in hex): ");
180     mem_size = hexIn();
181
182     end_addr = start_addr + mem_size - 1;
183
184     diag_printf("\nTesting memory from %p to %p.\n", start_addr, end_addr);
185     memTest(start_addr, end_addr);
186     diag_printf ("\nMemory test done.\n");
187 }
188
189
190 // ***************************************************************************
191 // repeat_mem_test - Repeating Memory Tests                       
192 //
193 static void
194 repeat_mem_test (MENU_ARG arg)
195 {
196     CYG_ADDRWORD start_addr, mem_size, end_addr;
197     char        cache_disable[10];
198
199     diag_printf ("Turn off Data Cache? (y/n): ");
200     while (_rb_gets(cache_disable, sizeof(cache_disable), 0) != _GETS_OK)
201         ;
202     diag_printf ("\nBase address of memory to test (in hex): ");
203     start_addr = hexIn();
204     diag_printf ("\nSize of memory to test (in hex): ");
205     mem_size = hexIn();
206     end_addr = start_addr + mem_size - 1;
207     diag_printf("\nTesting memory from %p to %p", start_addr, end_addr);
208     while (memTest (start_addr, end_addr))
209         ;
210 }
211
212 // ****************************************************************************
213 // special_mem_test - Repeat-On-Fail Memory Test                     
214 //
215 // Memory tests can be run one of two ways - with the cache turned OFF to test
216 // physical memory, or with cache turned ON to test the caching
217 //
218 static void
219 special_mem_test (MENU_ARG arg)
220 {
221     long        start_addr;
222     long        mem_size;
223     long        end_addr;
224
225     diag_printf ("Base address of memory to test (in hex): ");
226     start_addr = hexIn();
227     diag_printf ("\nSize of memory to test (in hex): ");
228     mem_size = hexIn();
229
230     end_addr = start_addr + mem_size - 1;
231     diag_printf("\nTesting memory from %p to %p.\n", start_addr, end_addr);
232
233     LoopMemTest(start_addr, end_addr);
234
235     diag_printf ("\n\nMemory test done.\n");
236     diag_wait();
237 }
238
239 static unsigned char led_data[] = {
240     DISPLAY_0, DISPLAY_1, DISPLAY_2, DISPLAY_3, DISPLAY_4, DISPLAY_5, DISPLAY_6, DISPLAY_7,
241     DISPLAY_8, DISPLAY_9, DISPLAY_A, DISPLAY_B, DISPLAY_C, DISPLAY_D, DISPLAY_E, DISPLAY_F,
242     DISPLAY_PERIOD, DISPLAY_OFF
243 };
244
245 // sequential test for LSD and MSD 7 segment Leds
246 //
247 void
248 seven_segment_display (MENU_ARG arg)
249 {
250     unsigned char SevSegDecode;
251     int DisplaySequence;
252     int SelectLed;
253
254     *(volatile unsigned char *)DISPLAY_LEFT = DISPLAY_OFF;
255     *(volatile unsigned char *)DISPLAY_RIGHT = DISPLAY_OFF;
256     
257     SelectLed=0; /* initialize 7 segment LED selection */
258         
259     for (SelectLed = 0; SelectLed < 2; SelectLed++) {
260         /* run test data sequence for a 7 segment LED */
261         for (DisplaySequence = 0; DisplaySequence <= 17; ++DisplaySequence ) {
262             /* fetch 7 segment decode byte */
263             SevSegDecode = led_data[DisplaySequence];
264
265             /* display test data on selected 7 segment LED */
266             /* the test data sequence for a 7 segment led will be seen as:*/
267             /* 0 1 2 3 4 5 6 7 8 9 A b C d e F . */
268             if (SelectLed)
269                 *(volatile unsigned char *) DISPLAY_LEFT = SevSegDecode;
270             else
271                 *(volatile unsigned char *) DISPLAY_RIGHT = SevSegDecode;
272
273             CYGACC_CALL_IF_DELAY_US((cyg_int32)4*100000);
274         }
275     }
276
277     *(volatile unsigned char *)DISPLAY_LEFT = DISPLAY_S;
278     *(volatile unsigned char *)DISPLAY_RIGHT = DISPLAY_S;
279 }
280
281
282 // tests rotary switch status, S1 positions 0-3, a 2 bit output code
283 static void
284 rotary_switch (MENU_ARG arg)
285 {
286     char recv_data[1];
287     const unsigned char MAX_SWITCH_SAMPLES = 9;
288     unsigned char RotarySwitch[MAX_SWITCH_SAMPLES]; // multiple samples of a 4 bit switch code
289     unsigned char index;                // index for Rotary Switch array
290     unsigned char debounce;             // keeps tally of equal rotary switch data reads in a loop
291     unsigned char SevSegDecode;         // holds decode data for a 7 segment LED display
292
293     *(volatile unsigned char *)DISPLAY_LEFT = DISPLAY_OFF;
294     *(volatile unsigned char *)DISPLAY_RIGHT = DISPLAY_OFF;
295     diag_printf("\n\nThe 7-Segment LSD LED shows the Rotary Switch position selected, i.e., 0-F.");
296     diag_printf("\n\nSlowly dial the Rotary Switch through each position 0-F and confirm reading.");
297
298     diag_printf( "\n\nStrike <CR> to exit this test." );
299     while (_rb_gets(recv_data, sizeof(recv_data), 50) != _GETS_OK) {
300         do {
301             for(index = 0; index <= MAX_SWITCH_SAMPLES; index++) {
302                 RotarySwitch[index] = *(volatile unsigned char *) IQ80321_ROTARY_SWITCH_ADDR;
303                 RotarySwitch[index] &= 0x0f;
304             }
305             debounce = 0;
306             for(index = 1; index <= MAX_SWITCH_SAMPLES; index++) {
307                 if (RotarySwitch[0] == RotarySwitch[index])
308                     debounce++; // keep tally of equal rotary switch code samples
309             }
310         } while (debounce < (MAX_SWITCH_SAMPLES - 1));
311
312         // decipher state of rotary switch position
313         if (RotarySwitch[0] > 16)
314             RotarySwitch[0] = 16;
315         SevSegDecode = led_data[RotarySwitch[0]];
316         
317         // display the rotary switch position on the 7 segment LSD LED as: 0, 1, 2, 3, etc.
318         *(volatile unsigned char *)DISPLAY_RIGHT = SevSegDecode;
319     }
320
321 } // end rotary_switch()
322
323
324
325