source: tt-loader/2nd/main.c @ 11

Last change on this file since 11 was 11, checked in by guillaume, 16 years ago

Publication tt-loader v0.1

File size: 5.3 KB
Line 
1/*
2 * 2nd - OMAP "second stage" tt-loader
3 *
4 * Copyright (C) 2008 Guillaume Bougard <gbougard@pkg.fr>
5 * Copyright (C) 2005 Luis Recuerda <lrec@helios.homeip.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *
21 */
22
23#include "config.h"
24#include "usb.h"
25
26#define _LSR_   ((volatile u8 *) 0xfffb0014)
27#define _THR_   ((volatile u8 *) 0xfffb0000)
28#define _RHR_   ((volatile u8 *) 0xfffb0000)
29
30#define MEM_READ_SIZE   32
31
32static char *usb_hdr = "TIS" ;
33static char usb_outbuffer[64];
34
35// limited strcpy
36static u32 strcpy ( char *dest, char *src )
37{
38        u32 count = 0 ;
39        char *tmp = dest, *s = src;
40       
41        while ( ++count < 256 && *s != '\0' )
42                *tmp++ = *s++ ;
43       
44        *tmp = '\0' ;
45       
46        return count ;
47}
48
49static u32 memcpy ( char *dest, char *src, u32 count )
50{
51        char *tmp = dest, *s = src;
52        u32 step = count ;
53
54        while (step--)
55                *tmp++ = *s++;
56       
57        return count ;
58}
59
60static void bsend (char ch)
61{
62        while (!((*_LSR_) & 0x20));
63        *_THR_= ch;
64}
65
66static inline int check_serial (void) { return (*_LSR_) & 0x01; }
67
68static char brecv (void)
69{
70        while (!((*_LSR_) & 0x01));
71        return *_RHR_;
72}
73
74char crecv (void)
75{
76        return brecv ();
77}
78
79void csend (char ch)
80{
81        if (ch == '\n')
82                bsend ('\r');
83        bsend (ch);
84}
85
86void tsend (const char *text)
87{
88        while (*text)
89                csend (*text++);
90}
91
92void xsend (unsigned value)
93{
94        if (value < 10)
95                bsend (value + '0');
96        else
97                bsend (value + ('A'-10));
98}
99
100void x8send (u8 value)
101{
102        xsend (value >> 4);
103        xsend (value & 0xf);
104}
105
106void x16send (u16 value)
107{
108        int     i;
109        for (i= 0; i < 4; ++i)
110        {
111                xsend (value >> 12);
112                value<<= 4;
113        }
114}
115
116void x32send (u32 value)
117{
118        int     i;
119        for (i= 0; i < 8; ++i)
120        {
121                xsend (value >> 28);
122                value<<= 4;
123        }
124}
125
126static void usb_msg (const char cmd, const char *msg)
127{
128        u32 len = strcpy(usb_outbuffer,usb_hdr);
129        usb_outbuffer[len-1] = cmd ;
130       
131        len += strcpy(&usb_outbuffer[len], msg ? (char *)msg : "" );
132
133        usb_send ( usb_outbuffer, len);
134        while (!usb_sent ());
135}
136
137static u32 usb_code (char cmd, u32 code)
138{
139        u32 len = strcpy(usb_outbuffer,usb_hdr);
140        usb_outbuffer[len-1] = cmd ;
141        (*(u32 *)(usb_outbuffer+len)) = code ;
142        len += sizeof(u32);
143
144        usb_send ( usb_outbuffer, len );
145        while (!usb_sent ());
146        return code ;
147}
148
149static void usb_blk (const char cmd, char *mem, u32 size)
150{
151        u32 len = strcpy(usb_outbuffer,usb_hdr);
152        usb_outbuffer[len-1] = cmd ;
153
154        len += memcpy(usb_outbuffer+len,mem,size);
155       
156        usb_send ( usb_outbuffer, len );
157        while (!usb_sent ());
158}
159
160// Code from linux-2.6.24.3/arch/arm/mach-omap1/id.c source
161static u16 omap_get_jtag_id(void)
162{
163        u32 prod_id, jtag_id;
164
165        prod_id = omap_readl(OMAP_PRODUCTION_ID_1);
166        jtag_id = omap_readl(OMAP32_ID_1);
167       
168        /* Check for unusable OMAP_PRODUCTION_ID_1 on 1611B/5912 and 730 */
169        if (((prod_id >> 20) == 0) || (prod_id == jtag_id))
170                prod_id = 0;
171        else
172                prod_id &= 0xffff;
173
174        if (prod_id)
175                return prod_id;
176
177        /* Use OMAP32_ID_1 as fallback */
178        prod_id = ((jtag_id >> 12) & 0xffff);
179
180        return prod_id;
181}
182
183u32 _main (void)
184{       
185        u32 address = CFG_LOADADDR ;
186        usb_msg ('m', "In omap plateform");
187       
188        u16 prod_id = omap_get_jtag_id();
189        switch (prod_id)
190        {
191                case 0xb55f:
192                        usb_msg ('m', "Found supported omap730");
193                        break;
194                default:
195                        usb_msg ('m', "Unsupported plateform found");
196                        usb_code ('v', (u32) prod_id);
197                        break;
198        }
199       
200        // Ready to manage requests
201        usb_msg ('r', "Waiting first request");
202       
203        for (;;)
204        {
205                u32 total, cmd, index = 0 ;
206               
207                u8 usb_inbuffer[64];
208                usb_recv (usb_inbuffer, sizeof (usb_inbuffer));
209                while (!usb_rcvd ());
210               
211                // Check we are knowing the provided header
212                while ( usb_inbuffer[index] == (u8) usb_hdr[index] && usb_hdr[index] != '\0' )
213                        index++ ;
214               
215                if ( usb_hdr[index] != '\0' )
216                        continue ;
217               
218                cmd = usb_inbuffer[index++] ;
219               
220                if ((char)cmd == 's') // Ask size to upload
221                {
222                        total= *(u32 *) &usb_inbuffer[index];
223                        u32 size = 0;
224
225                        usb_code ('n', total);
226
227                        while (size < total)
228                        {
229                                u32     r;
230                               
231                                usb_recv ((u8 *)address, sizeof (usb_inbuffer));
232                                while ((r= usb_rcvd ()) == 0);
233                                                               
234                                address += r ;
235                                size += r ;
236                        }
237                       
238                        usb_code ('o', size);
239                       
240                } else
241                if ((char)cmd == 'f') // load file ACK
242                {
243                        usb_msg ('f', (const char *)&usb_inbuffer[index]);
244                       
245                } else
246                if ((char)cmd == 'M') // dump memory command
247                {
248                        usb_blk ('M', (char *)address, MEM_READ_SIZE);
249                        address += MEM_READ_SIZE ;
250                       
251                } else
252                if ((char)cmd == 'a') // set address command
253                {
254                        address = *(u32 *) &usb_inbuffer[index];
255                        usb_code ('i', address);
256                       
257                } else
258                if ((char)cmd == 'c') // call command
259                {
260                        index = ((u32_fnc_t *)address)();
261                        usb_code ('i', index);
262                       
263                } else
264                if ((char)cmd == 'b') // boot command
265                {
266                        usb_code ('b', address );
267                        // Just return the address where is store the branch to do
268                        u32 bootaddress = (u32) &address ; // Convert/cast address just to avoid gcc warning
269                        return bootaddress ;
270                }
271        }
272}
Note: See TracBrowser for help on using the repository browser.