add initial support for the crisarchitecture used on foxboards to openwrt
[openwrt/staging/dedeckeh.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 *******************************/