OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [soc/] [sw/] [orpmon/] [services/] [tftp.c] - Blame information for rev 20

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 20 xianfeng
/*
2
 *      Copyright 1994, 1995, 2000 Neil Russell.
3
 *      (See License)
4
 *      Copyright 2000, 2001 DENX Software Engineering, Wolfgang Denk, wd@denx.de
5
 */
6
 
7
#include "common.h"
8
#include "support.h"
9
#include "net.h"
10
#include "tftp.h"
11
#include "bootp.h"
12
 
13
#undef  ET_DEBUG
14
 
15
#define WELL_KNOWN_PORT 69              /* Well known TFTP port #               */
16
#define TIMEOUT         2               /* Seconds to timeout for a lost pkt    */
17
#define TIMEOUT_COUNT   10              /* # of timeouts before giving up       */
18
                                        /* (for checking the image size)        */
19
#define HASHES_PER_LINE 65              /* Number of "loading" hashes per line  */
20
 
21
/*
22
 *      TFTP operations.
23
 */
24
#define TFTP_RRQ        1
25
#define TFTP_WRQ        2
26
#define TFTP_DATA       3
27
#define TFTP_ACK        4
28
#define TFTP_ERROR      5
29
 
30
 
31
static int      TftpServerPort;         /* The UDP port at their end            */
32
static int      TftpOurPort;            /* The UDP port at our end              */
33
static int      TftpTimeoutCount;
34
static unsigned TftpBlock;
35
static unsigned TftpLastBlock;
36
static int      TftpState;
37
#define STATE_RRQ       1
38
#define STATE_DATA      2
39
#define STATE_TOO_LARGE 3
40
#define STATE_BAD_MAGIC 4
41
 
42
char *tftp_filename;
43
 
44
#ifdef CFG_DIRECT_FLASH_TFTP
45
extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
46
#endif
47
 
48
static __inline__ void
49
store_block (unsigned block, unsigned char * src, unsigned len)
50
{
51
        unsigned long offset = block * 512, newsize = offset + len;
52
#ifdef CFG_DIRECT_FLASH_TFTP
53
        int i, rc = 0;
54
 
55
        for (i=0; i<CFG_MAX_FLASH_BANKS; i++) {
56
                /* start address in flash? */
57
                if (global.src_addr + offset >= flash_info[i].start[0]) {
58
                        rc = 1;
59
                        break;
60
                }
61
        }
62
 
63
        if (rc) { /* Flash is destination for this packet */
64
                rc = flash_write ((unsigned char *)src, (unsigned long)(global.src_addr+offset), len);
65
                switch (rc) {
66
                case 0:  /* OK */
67
                        break;
68
                case 1: printf ("Timeout writing to Flash\n");
69
                        break;
70
                case 2: printf ("Flash not Erased\n");
71
                        break;
72
                case 4: printf ("Can't write to protected Flash sectors\n");
73
                        break;
74
                case 8: printf ("Outside available Flash\n");
75
                        break;
76
                case 16:printf ("Size must be aligned (multiple of 8?)\n");
77
                        break;
78
                default:
79
                        printf ("%s[%d] FIXME: rc=%d\n",__FILE__,__LINE__,rc);
80
                        break;
81
                }
82
                if (rc) {
83
                        NetState = NETLOOP_FAIL;
84
                        return;
85
                }
86
        }
87
        else
88
#endif /* CFG_DIRECT_FLASH_TFTP */
89
        (void)memcpy((void *)(global.src_addr + offset), src, len);
90
 
91
        if (NetBootFileXferSize < newsize)
92
                NetBootFileXferSize = newsize;
93
}
94
 
95
static void TftpSend (void);
96
static void TftpTimeout (void);
97
 
98
/**********************************************************************/
99
 
100
static void
101
TftpSend (void)
102
{
103
        volatile unsigned char *        pkt;
104
        volatile unsigned char *        xp;
105
        int                     len = 0;
106
 
107
        /*
108
         *      We will always be sending some sort of packet, so
109
         *      cobble together the packet headers now.
110
         */
111
        pkt = NetTxPacket + ETHER_HDR_SIZE + IP_HDR_SIZE;
112
 
113
        switch (TftpState) {
114
 
115
        case STATE_RRQ:
116
                xp = pkt;
117
                *((unsigned short *)pkt)++ = SWAP16c(TFTP_RRQ);
118
                strcpy ((char *)pkt, tftp_filename);
119
                pkt += strlen(tftp_filename) + 1;
120
                strcpy ((char *)pkt, "octet");
121
                pkt += 5 /*strlen("octet")*/ + 1;
122
                len = pkt - xp;
123
                break;
124
 
125
        case STATE_DATA:
126
                xp = pkt;
127
                *((unsigned short *)pkt)++ = SWAP16c(TFTP_ACK);
128
                *((unsigned short *)pkt)++ = SWAP16(TftpBlock);
129
                len = pkt - xp;
130
                break;
131
 
132
        case STATE_TOO_LARGE:
133
                xp = pkt;
134
                *((unsigned short *)pkt)++ = SWAP16c(TFTP_ERROR);
135
                *((unsigned short *)pkt)++ = SWAP16(3);
136
                strcpy ((char *)pkt, "File too large");
137
                pkt += 14 /*strlen("File too large")*/ + 1;
138
                len = pkt - xp;
139
                break;
140
 
141
        case STATE_BAD_MAGIC:
142
                xp = pkt;
143
                *((unsigned short *)pkt)++ = SWAP16c(TFTP_ERROR);
144
                *((unsigned short *)pkt)++ = SWAP16(2);
145
                strcpy ((char *)pkt, "File has bad magic");
146
                pkt += 18 /*strlen("File has bad magic")*/ + 1;
147
                len = pkt - xp;
148
                break;
149
        }
150
 
151
        NetSetEther (NetTxPacket, NetServerEther, PROT_IP);
152
        NetSetIP (NetTxPacket + ETHER_HDR_SIZE, NetServerIP,
153
                                        TftpServerPort, TftpOurPort, len);
154
        NetSendPacket (NetTxPacket, ETHER_HDR_SIZE + IP_HDR_SIZE + len);
155
}
156
 
157
 
158
static void
159
TftpHandler (unsigned char * pkt, unsigned dest, unsigned src, unsigned len)
160
{
161
        if (dest != TftpOurPort) {
162
                return;
163
        }
164
        if (TftpState != STATE_RRQ && src != TftpServerPort) {
165
                return;
166
        }
167
 
168
        if (len < 2) {
169
                return;
170
        }
171
        len -= 2;
172
        switch (SWAP16(*((unsigned short *)pkt)++)) {
173
 
174
        case TFTP_RRQ:
175
        case TFTP_WRQ:
176
        case TFTP_ACK:
177
                break;
178
        default:
179
                break;
180
 
181
        case TFTP_DATA:
182
                if (len < 2)
183
                        return;
184
                len -= 2;
185
                TftpBlock = SWAP16(*(unsigned short *)pkt);
186
                if (((TftpBlock - 1) % 10) == 0) {
187
                        putc ('#');
188
                        TftpTimeoutCount = 0;
189
                } else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0) {
190
                        printf ("\n\t ");
191
                }
192
 
193
                if (TftpState == STATE_RRQ) {
194
                        TftpState = STATE_DATA;
195
                        TftpServerPort = src;
196
                        TftpLastBlock = 0;
197
 
198
                        if (TftpBlock != 1) {   /* Assertion */
199
                                printf ("\nTFTP error: "
200
                                        "First block is not block 1 (%d)\n"
201
                                        "Starting again\n\n",
202
                                        TftpBlock);
203
                                NetStartAgain ();
204
                                break;
205
                        }
206
                }
207
 
208
                if (TftpBlock == TftpLastBlock) {
209
                        /*
210
                         *      Same block again; ignore it.
211
                         */
212
                        break;
213
                }
214
 
215
                TftpLastBlock = TftpBlock;
216
                NetSetTimeout (TIMEOUT * TICKS_PER_SEC, TftpTimeout);
217
 
218
                store_block (TftpBlock - 1, pkt + 2, len);
219
 
220
                /*
221
                 *      Acknoledge the block just received, which will prompt
222
                 *      the server for the next one.
223
                 */
224
                TftpSend ();
225
 
226
                if (len < 512) {
227
                        /*
228
                         *      We received the whole thing.  Try to
229
                         *      run it.
230
                         */
231
                        printf ("\ndone\n");
232
                        NetState = NETLOOP_SUCCESS;
233
                }
234
                break;
235
 
236
        case TFTP_ERROR:
237
                printf ("\nTFTP error: '%s' (%d)\n",
238
                                        pkt + 2, SWAP16(*(unsigned short *)pkt));
239
                printf ("Starting again\n\n");
240
                NetStartAgain ();
241
                break;
242
        }
243
}
244
 
245
 
246
static void
247
TftpTimeout (void)
248
{
249
        if (++TftpTimeoutCount >= TIMEOUT_COUNT) {
250
                printf ("\nRetry count exceeded; starting again\n");
251
                NetStartAgain ();
252
        } else {
253
                printf ("T ");
254
                NetSetTimeout (TIMEOUT * TICKS_PER_SEC, TftpTimeout);
255
                TftpSend ();
256
        }
257
}
258
 
259
 
260
void
261
TftpStart (void)
262
{
263
#ifdef ET_DEBUG
264
        printf ("\nServer ethernet address %02x:%02x:%02x:%02x:%02x:%02x\n",
265
                NetServerEther[0],
266
                NetServerEther[1],
267
                NetServerEther[2],
268
                NetServerEther[3],
269
                NetServerEther[4],
270
                NetServerEther[5]
271
        );
272
#endif /* DEBUG */
273
 
274
        printf ("TFTP from server ");   print_IPaddr (NetServerIP);
275
        printf ("; our IP address is ");        print_IPaddr (NetOurIP);
276
 
277
        // Check if we need to send across this subnet
278
        if (NetOurGatewayIP && NetOurSubnetMask) {
279
            IPaddr_t OurNet     = NetOurIP    & NetOurSubnetMask;
280
            IPaddr_t ServerNet  = NetServerIP & NetOurSubnetMask;
281
 
282
            if (OurNet != ServerNet) {
283
                printf ("; sending through gateway ");
284
                print_IPaddr (NetOurGatewayIP) ;
285
            }
286
        }
287
        putc ('\n');
288
 
289
        printf ("Filename '%s'.", tftp_filename);
290
 
291
        if (NetBootFileSize) {
292
            printf (" Size is %d%s kB => %x Bytes",
293
                NetBootFileSize/2,
294
                (NetBootFileSize%2) ? ".5" : "",
295
                NetBootFileSize<<9);
296
        }
297
 
298
        putc ('\n');
299
 
300
        printf ("Load address: 0x%lx\n", global.src_addr);
301
 
302
        printf ("Loading: *\b");
303
 
304
        NetSetTimeout (TIMEOUT * TICKS_PER_SEC, TftpTimeout);
305
        NetSetHandler (TftpHandler);
306
 
307
        TftpServerPort = WELL_KNOWN_PORT;
308
        TftpTimeoutCount = 0;
309
        TftpState = STATE_RRQ;
310
        TftpOurPort = 1024 + (get_timer(0) % 3072);
311
 
312
        TftpSend ();
313
}
314
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.