]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/cygmon/v2_0/misc/ecos_bsp.c
Initial revision
[karo-tx-redboot.git] / packages / cygmon / v2_0 / misc / ecos_bsp.c
1 //==========================================================================
2 //
3 //        ecos_bsp.c
4 //
5 //        eCos BSP (for building Cygmon)
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):     gthomas
44 // Contributors:  gthomas, dmoseley
45 // Date:          1999-10-11
46 // Description:   Wrapper functions which provide BSP environment for Cygmon
47 //####DESCRIPTIONEND####
48
49 #ifdef CYGPKG_KERNEL
50 #include <pkgconf/kernel.h>   // Configuration headers
51 #endif
52 #include <pkgconf/hal.h>
53 #include <pkgconf/cygmon.h>
54
55 #include <cyg/hal/hal_arch.h>
56 #include <cyg/hal/hal_cache.h>
57 #ifdef CYGPKG_KERNEL
58 #include <cyg/kernel/kapi.h>
59 #else
60 #include <cyg/hal/drv_api.h>
61 #include <cyg/hal/hal_intr.h>
62 #endif
63 #include <cyg/infra/diag.h>
64 #include "bsp/common/bsp_if.h"
65 #include <cyg/hal/hal_if.h>
66 #include <signal.h>
67 #include CYGHWR_MEMORY_LAYOUT_H
68  
69 #include <pkgconf/system.h>
70 #ifdef CYGPKG_IO
71 #include <cyg/io/io.h>
72 #include <cyg/io/serialio.h>
73 #endif
74
75 #define STACK_SIZE CYGNUM_HAL_STACK_SIZE_MINIMUM
76 static char stack[STACK_SIZE];
77 #ifdef CYGPKG_KERNEL
78 static cyg_thread thread_data;
79 static cyg_handle_t thread_handle;
80 #endif
81
82 char *build_date = __DATE__;
83
84 extern void monitor_main(int, char *);
85 extern int  stub_is_active;
86
87 void ecos_bsp_set_memsize(unsigned long size);
88
89 void
90 cygmon_main(void)
91 {
92     _bsp_init();
93     monitor_main(0, 0);  // Null argument list
94 }
95
96 extern unsigned long cygmon_memsize;
97
98 externC void
99 cyg_start( void )
100 {
101     // Fill in the BSP memory info
102     if (cygmon_memsize != 0)
103         ecos_bsp_set_memsize(cygmon_memsize);
104
105 #ifdef CYGPKG_KERNEL
106     // Create a main thread, so we can run the scheduler and have time 'pass'
107     cyg_thread_create(10,                // Priority - just a number
108                       (cyg_thread_entry_t*)cygmon_main,       // entry
109                       0,                 // entry parameter
110                       "Cygmon",          // Name
111                       &stack[0],         // Stack
112                       STACK_SIZE,        // Size
113                       &thread_handle,    // Handle
114                       &thread_data       // Thread data structure
115             );
116     cyg_thread_resume(thread_handle);  // Start it
117     cyg_scheduler_start();
118 #else
119 #ifdef HAL_ARCH_FUNCALL_NEW_STACK
120     HAL_ARCH_FUNCALL_NEW_STACK(cygmon_main, &stack[0], STACK_SIZE);
121 #else
122     #error Need to define HAL_ARCH_FUNCALL_NEW_STACK
123 #endif
124 #endif
125 } // cyg_package_start()
126
127 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
128 extern void *_hal_registers;  // Used by eCos GDB stubs
129 extern void (*__init_vec)(void);
130 extern void (*__cleanup_vec)(void);
131 extern void __install_traps(void);
132 #endif
133
134 extern int machine_syscall(HAL_SavedRegisters *regs);
135 void
136 _bsp_handle_exception(cyg_addrword_t data, cyg_code_t num, cyg_addrword_t info)
137 {
138     if (num == CYGNUM_HAL_EXCEPTION_INTERRUPT) {
139         if (machine_syscall((HAL_SavedRegisters*)info)) {
140             return;
141         }
142         // Fall through to "normal" exception handling if system call failed
143     }
144 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
145     _hal_registers = (void *)info;  // Used by eCos GDB stubs
146     __cleanup_vec();
147 #endif
148     bsp_invoke_dbg_handler(num, (void *)info);
149 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
150     __init_vec();
151 #endif
152 }
153
154 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
155 extern void __handle_exception(void);
156 #else
157
158 int
159 unhandled_exception(int num, void *args)
160 {
161     diag_printf("Unhandled exception: %d/%x\n", num, args);
162     while (1) ;
163 }
164 #endif
165
166 void
167 _bsp_cpu_init(void)
168 {
169 #ifdef CYGPKG_KERNEL
170     int d0;
171     cyg_exception_set_handler(CYGNUM_HAL_EXCEPTION_ILLEGAL_INSTRUCTION,
172                               _bsp_handle_exception,
173                               (cyg_addrword_t)&d0,
174                               0,
175                               0);
176 #endif
177 #ifdef CYGDBG_HAL_DEBUG_GDB_INCLUDE_STUBS
178     bsp_install_dbg_handler((bsp_handler_t)__handle_exception);
179     __install_traps();
180 #else
181     bsp_install_dbg_handler(unhandled_exception);
182 #endif
183 }
184
185 #define FAIL() diag_printf("fail: %s\n", __FUNCTION__);  while (1) ;
186
187 #ifndef CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
188
189 struct BSP_IO {
190     char            *name;
191     cyg_io_handle_t  chan;
192 };
193
194 static void 
195 uart_putchar(void *base, char c)
196 {
197     char buf;
198     int len;
199     struct BSP_IO *io = (struct BSP_IO *)base;
200     if (io->chan) {
201         len = 1;
202         buf = c;
203         cyg_io_write(io->chan, &buf, &len);
204     }
205 }
206
207 extern int __output_gdb_string (const char *str, int string_len);
208
209 // This function is mostly used by the 'write()' system call
210 static void
211 uart_write(void *base, const char *buf, int len)
212 {
213     struct BSP_IO *io = (struct BSP_IO *)base;
214     if (io->chan) {
215         if (stub_is_active) {
216             // We are running in 'GDB' mode
217             __output_gdb_string(buf, len);
218         } else {
219             cyg_io_write(io->chan, buf, &len);
220         }
221     }
222 }
223
224 static int
225 uart_read(void *base, char *buf, int len)
226 {
227     struct BSP_IO *io = (struct BSP_IO *)base;
228     if (io->chan) {
229         cyg_io_read(io->chan, buf, &len);
230         return len;
231     }
232     return 0;
233 }
234
235 static int
236 uart_getchar(void *base)
237 {
238     char buf = '\0';
239     int len;
240     struct BSP_IO *io = (struct BSP_IO *)base;
241     if (io->chan) {
242         len = 1;
243         cyg_io_read(io->chan, &buf, &len);
244     }
245     return buf;
246 }
247
248 static int
249 uart_control(void *base, int func, ...)
250 {
251     int rc = 0;
252     va_list ap;
253     int arg;
254     struct BSP_IO *io = (struct BSP_IO *)base;
255
256     va_start(ap, func);
257
258     if (func == COMMCTL_SETBAUD)
259     {
260         cyg_serial_info_t buffer = {
261             CYG_SERIAL_BAUD_DEFAULT, 
262             CYG_SERIAL_STOP_DEFAULT, 
263             CYG_SERIAL_PARITY_DEFAULT,
264             CYG_SERIAL_WORD_LENGTH_DEFAULT,
265             CYG_SERIAL_FLAGS_DEFAULT
266         };
267         int len = sizeof(buffer);
268         arg = va_arg(ap, int);
269
270         switch (arg)
271         {
272         case 50:         buffer.baud = CYG_SERIAL_BAUD_RATE(50);       break;
273         case 75:         buffer.baud = CYG_SERIAL_BAUD_RATE(75);       break;
274         case 110:        buffer.baud = CYG_SERIAL_BAUD_RATE(110);      break;
275         case 134:        buffer.baud = CYG_SERIAL_BAUD_RATE(134_5);    break;
276         case 135:        buffer.baud = CYG_SERIAL_BAUD_RATE(134_5);    break;
277         case 150:        buffer.baud = CYG_SERIAL_BAUD_RATE(150);      break;
278         case 200:        buffer.baud = CYG_SERIAL_BAUD_RATE(200);      break;
279         case 300:        buffer.baud = CYG_SERIAL_BAUD_RATE(300);      break;
280         case 600:        buffer.baud = CYG_SERIAL_BAUD_RATE(600);      break;
281         case 1200:       buffer.baud = CYG_SERIAL_BAUD_RATE(1200);     break;
282         case 1800:       buffer.baud = CYG_SERIAL_BAUD_RATE(1800);     break;
283         case 2400:       buffer.baud = CYG_SERIAL_BAUD_RATE(2400);     break;
284         case 3600:       buffer.baud = CYG_SERIAL_BAUD_RATE(3600);     break;
285         case 4800:       buffer.baud = CYG_SERIAL_BAUD_RATE(4800);     break;
286         case 7200:       buffer.baud = CYG_SERIAL_BAUD_RATE(7200);     break;
287         case 9600:       buffer.baud = CYG_SERIAL_BAUD_RATE(9600);     break;
288         case 14400:      buffer.baud = CYG_SERIAL_BAUD_RATE(14400);    break;
289         case 19200:      buffer.baud = CYG_SERIAL_BAUD_RATE(19200);    break;
290         case 38400:      buffer.baud = CYG_SERIAL_BAUD_RATE(38400);    break;
291         case 57600:      buffer.baud = CYG_SERIAL_BAUD_RATE(57600);    break;
292         case 115200:     buffer.baud = CYG_SERIAL_BAUD_RATE(115200);   break;
293         case 230400:     buffer.baud = CYG_SERIAL_BAUD_RATE(230400);   break;
294         default:         buffer.baud = -1; rc = -1;                    break;
295         }
296
297         if ((io->chan) && (buffer.baud != -1)) {
298             rc = cyg_io_set_config(io->chan, CYG_IO_SET_CONFIG_SERIAL_INFO, &buffer, &len);
299         }
300     }
301
302     va_end(ap);
303     return rc;
304 }
305
306 /*
307  * Setup the bsp_comm_channel data structure
308  */
309 struct BSP_IO bsp_comm_io[] = { 
310     {CYGDAT_CYGMON_CONSOLE_DEV, 0},  // Console device
311 };
312
313 struct bsp_comm_channel _bsp_comm_list[] = 
314 {
315     {
316         { "UART 0", 
317           BSP_COMM_SERIAL, 
318           BSP_PROTO_NONE },
319         { (void*)&bsp_comm_io[0], 
320           uart_write, 
321           uart_read,
322           uart_putchar, 
323           uart_getchar, 
324           uart_control }
325     },
326 };
327 int _bsp_num_comms = sizeof(_bsp_comm_list)/sizeof(_bsp_comm_list[0]);
328
329 void
330 _bsp_init_board_comm(void)
331 {
332     int i;
333     for (i = 0;  i < _bsp_num_comms;  i++) {
334         Cyg_ErrNo err;
335         struct BSP_IO *io;
336         io = (struct BSP_IO *)_bsp_comm_list[i].procs.ch_data;
337         if ((err = cyg_io_lookup(io->name, &io->chan)) != ENOERR) {
338             diag_printf("Can't open '%s'\n", io->name);
339         }
340     }
341 }
342
343 #else // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
344
345 struct bsp_comm_channel _bsp_comm_list[1];
346 int _bsp_num_comms = 1;
347
348 // Yuck! Two things need doing:
349
350 // FIXME: Make bsp code use pointers in the bsp_comm_channel instead
351 //        of sub-structures.
352
353 // FIXME: Make HAL provide the bsp_comm_info structure - I missed that
354 //        initially because it cannot be accessed via the virtual table API.
355 void
356 _bsp_init_board_comm(void)
357 {
358     struct bsp_comm_channel* channel;
359     hal_virtual_comm_table_t* comm;
360
361     channel = &_bsp_comm_list[0];
362     channel->info.name = "fixme";
363     channel->info.kind = BSP_COMM_SERIAL;
364     channel->info.protocol = BSP_PROTO_NONE;
365
366     comm = CYGACC_CALL_IF_DEBUG_PROCS();
367     channel->procs = *(struct bsp_comm_procs*)comm;
368 }
369 #endif // CYGSEM_HAL_VIRTUAL_VECTOR_SUPPORT
370
371 /*
372  * Array of memory region descriptors. We just list RAM.
373  */
374 #ifdef CYGMEM_REGION_ram
375 #define RAM_VIRTUAL_BASE CYGMEM_REGION_ram
376 #define RAM_TOTAL_SIZE   CYGMEM_REGION_ram_SIZE
377 #else
378 #define RAM_VIRTUAL_BASE 0x00008000
379 #define RAM_TOTAL_SIZE   0x00FF8000
380 #endif
381
382 struct bsp_mem_info _bsp_memory_list[] = 
383 {
384     { (void *)RAM_VIRTUAL_BASE,   
385       (void *)RAM_VIRTUAL_BASE,   
386       0, 
387       RAM_TOTAL_SIZE,   
388       BSP_MEM_RAM 
389     },
390 };
391
392 /*
393  * Number of memory region descriptors.
394  */
395 int _bsp_num_mem_regions = sizeof(_bsp_memory_list)/sizeof(_bsp_memory_list[0]);
396
397 void
398 _bsp_install_cpu_irq_controllers(void)
399 {
400 }
401
402 void
403 _bsp_install_board_irq_controllers(void)
404 {
405 }
406
407 void
408 __init_irq_controllers(void)
409 {
410 }
411
412 void
413 _bsp_board_init(void)
414 {
415     /*
416      * Define platform info.
417      */
418 #ifdef HAL_PLATFORM_CPU
419     _bsp_platform_info.cpu = HAL_PLATFORM_CPU;
420 #else
421     _bsp_platform_info.cpu = "Unknown CPU";
422 #endif
423 #ifdef HAL_PLATFORM_BOARD
424     _bsp_platform_info.board = HAL_PLATFORM_BOARD;
425 #else
426     _bsp_platform_info.board = "Unknown board";
427 #endif
428 #ifdef HAL_PLATFORM_EXTRA
429     _bsp_platform_info.extra = HAL_PLATFORM_EXTRA;
430 #else
431     _bsp_platform_info.extra = "";
432 #endif
433 }
434
435 extern char *strchr(char *, char);
436 char *
437 index(char *string, char key)
438 {
439     return strchr(string, key);
440 }
441
442 void
443 flush_i_cache(void)
444 {
445     HAL_ICACHE_SYNC();
446 }
447
448 void
449 ecos_bsp_console_putc(char c)
450 {
451     if (bsp_shared_data) {
452         bsp_console_putc(c);
453     }
454 }
455
456 char
457 ecos_bsp_console_getc(void)
458 {
459     if (bsp_shared_data) {
460         return bsp_console_getc();
461     } else {
462         return '?';
463     }
464 }
465
466 void
467 ecos_bsp_set_memsize(unsigned long size)
468 {
469     _bsp_memory_list[0].nbytes = size;
470 }