add initial support for the crisarchitecture used on foxboards to openwrt
[openwrt.git] / target / linux / etrax-2.6 / image / e100boot / src / cbl / src / common_init.c
1 /*****************************************************************************
2 *!
3 *! FILE NAME  : common_init.c
4 *!
5 *! DESCRIPTION: This piece of code is loaded at bootstrap and is put in the
6 *!              cache at 0x380000F0.  Depending of how R_BUS_STATUS<2:1> is
7 *!              set different kinds of bootstrap is performed.
8 *!
9 *!              00 - Normal boot. No bootstrap is performed and this code
10 *!                   is never loaded.
11 *!              01 - Serial boot. 784 bytes is loaded and execution starts
12 *!                   at 0x380000F0.
13 *!              11 - Parallel boot. 784 bytes is loaded and execution starts
14 *!                   at 0x380000F0.
15 *!              10 - Network boot. 1484 bytes is loaded and execution start
16 *!                   at 0x380000F4.
17 *!
18 *! ---------------------------------------------------------------------------
19 *! HISTORY
20 *!
21 *! DATE         NAME               CHANGES
22 *! ----         ----               -------
23 *! 980326       Ronny Ranerup      Initial version
24 *! Sep 20 1999  Jonas Dellenvall   Added port3 debug support
25 *! 20020206     ronny              Yeah, and I removed it again...
26 *!
27 *! ---------------------------------------------------------------------------
28 *! (C) Copyright 1998-2002, Axis Communications AB, LUND, SWEDEN
29 *!***************************************************************************/
30
31 /*
32
33    Misc notes:
34
35    It is very important to keep this file short. This and the boot
36    interface specific parts must fit into the first boot packet.
37
38 */
39
40 /****************** INCLUDE FILES SECTION ***********************************/
41
42 #include "hwregs.h"
43 #include "e100boot.h"
44
45 /****************** CONSTANT AND MACRO SECTION ******************************/
46
47 /****************** TYPE DEFINITION SECTION *********************************/
48
49 /****************** LOCAL FUNCTION DECLARATION SECTION **********************/
50
51 static int timeout(void);
52
53 /****************** GLOBAL VARIABLE DECLARATION SECTION *********************/
54
55 udword  nbr_read;       /* How many bytes has been read from current file */
56 byte    interface;      /* Which I/O interface is the current one */
57 byte    set_dest;       /* Have we set the destination address in tx_header */
58 udword  last_timeout;
59
60 struct packet_header_T tx_header;
61 dma_descr_T tx_descr;   /* For packet header */
62 dma_descr_T tx_descr2;  /* packet data */
63
64 struct packet_header_T rx_header;
65 dma_descr_T rx_descr;   /* For packet header */
66 dma_descr_T rx_descr2;  /* packet data */
67
68 udword seq;             /* Sequence number of next wanted packet */
69 byte serial_up;
70
71 /****************** LOCAL VARIABLE DECLARATION SECTION **********************/
72
73 /****************** FUNCTION DEFINITION SECTION *****************************/
74
75 void 
76 crt1(void)
77 {
78   /* Do this only once so we don't reset the timers and destroy the 32
79      bit timer-register used as random number generator */
80
81   REG_SET__R_TIMER_CTRL( 
82                         timerdiv1, 0,
83                         timerdiv0, 0,
84                         presc_timer1, normal, 
85                         i1,        clr,
86                         tm1,       run,
87                         clksel1,   cascade0,
88                         presc_ext, prescale,
89                         i0,        clr,
90                         tm0,       run,
91                         clksel0,   c9600Hz);
92   
93   REG_SET__R_TIMER_CTRL(
94                         timerdiv1, 0,
95                         timerdiv0, 0,
96                         presc_timer1, normal, 
97                         i1,        nop,
98                         tm1,       run,
99                         clksel1,   cascade0,
100                         presc_ext, prescale,
101                         i0,        nop,
102                         tm0,       run,
103                         clksel0,   c9600Hz);
104   
105   start();
106 }
107
108 void
109 start(void)
110 {
111 #if USE_LEDS
112   REG_SET__R_PORT_PA_DIR( 
113                          dir7, output,
114                          dir6, output,
115                          dir5, output,
116                          dir4, output,
117                          dir3, output,
118                          dir2, output,
119                          dir1, output,
120                          dir0, input);  /* not for prodtest */
121   
122   REG_SET__R_PORT_PA_DATA(data_out, 0);
123
124   REG_SET__R_PORT_PB_DIR( 
125                          dir7, output,
126                          dir6, output,
127                          dir5, output,
128                          dir4, output,
129                          dir3, output,
130                          dir2, output,
131                          dir1, output,
132                          dir0, output);
133   
134   REG_SET__R_PORT_PB_DATA(data_out, 0xff);
135 #endif
136
137   /* We must initialize all (global) variables here, since the .data
138      and .bss area are used before they are loaded. */
139
140   //serial_up        = FALSE;
141   nbr_read         = 0;
142
143   /* Get a random value to use as id. */
144   tx_header.id     = htonl(REG_RD(R_TIMER_DATA));
145   
146   /* timer01 is used as timer. */
147   last_timeout     = REG_GET(R_TIMER01_DATA, count);
148   
149   interface        = REG_GET(R_BUS_STATUS, boot) - 1; /* 0,1,2 */
150   rx_descr2.status = 0; 
151
152   /* Initialize the boot interface */
153   init_interface();
154   send_ack();   /* Ack the first bootpacket, i.e. this code. seq 0. */
155
156   while (1) {
157     if (read_data()) {
158       if (nbr_read >= (udword)bytes_to_read) {
159         break;
160       }
161       else if (interface == NETWORK) {
162         REG_SET(R_DMA_CH1_CMD, cmd, start);
163       }
164     }
165   }
166
167 #if USE_LEDS
168   REG_SET(R_PORT_PA_DATA, data_out, 0x55);
169 #endif
170
171   level2_boot();
172 }
173
174 int
175 read_data(void)
176 {
177   if (handle_read()) {
178     return TRUE;
179   }
180
181   if (timeout()) {
182     send_ack();
183   }
184
185   return FALSE;
186 }
187
188 int
189 timeout(void)
190 {
191   volatile int now = REG_GET(R_TIMER01_DATA, count);
192   int elapsed;
193   int wait_time = 9600;
194
195   elapsed = last_timeout - now;
196
197   if (elapsed < 0) {
198     elapsed = -elapsed;
199   }
200
201   if (elapsed > wait_time) {
202     last_timeout = now;
203     return TRUE;
204   }
205
206   return FALSE;
207 }
208
209 /****************** END OF FILE common_init.c *******************************/