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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [bootloaders/] [orpmon/] [cmds/] [load.c] - Blame information for rev 607

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 406 julius
#include "common.h"
2 2 marcus.erl
#include "support.h"
3
#include "flash.h"
4
#include "net.h"
5 464 julius
#include "eth.h"
6 2 marcus.erl
#include "uart.h"
7 389 tac2
#include "dosfs.h"
8 246 julius
#include "spr-defs.h"
9 2 marcus.erl
 
10
#ifndef MAX_IMAGES
11
#define MAX_IMAGES 20
12
#endif
13
 
14 464 julius
// Put the copyboot program at just before end of memory
15
#define COPYBOOT_LOCATION (SDRAM_SIZE - (32*4))
16
 
17
 
18 2 marcus.erl
extern unsigned long fprog_addr;
19
extern char *tftp_filename;
20
 
21 406 julius
static flash_cfg_struct gcfg =
22
    { BOARD_DEF_IP, BOARD_DEF_MASK, BOARD_DEF_GW, BOARD_DEF_TBOOT_SRVR };
23 2 marcus.erl
 
24 140 julius
// Not booting from flash, so just set these from board.h -- jb
25
//static flash_cfg_struct __attribute__ ((section(".config"))) gcfg = { BOARD_DEF_IP, BOARD_DEF_MASK, BOARD_DEF_GW,  BOARD_DEF_TBOOT_SRVR };
26
//static flash_cfg_struct __attribute__ ((section(".config"))) gcfg = { 0, 0, 0, 0 };
27
 
28 2 marcus.erl
#define FLASH_IMAGES_BASE 0xf0300000
29
 
30
#define ALIGN(addr,size) ((addr + (size-1))&(~(size-1)))
31 140 julius
// If the image buffer is word aligned, then uncomment this, but it was set up 
32
// so that the tftp images would download quicker
33
#define COPY_AND_BOOT_WORD_ALIGNED
34
#ifdef COPY_AND_BOOT_WORD_ALIGNED
35 406 julius
void copy_and_boot(unsigned long src,
36
                   unsigned long dst, unsigned long len, int tx_next)
37 2 marcus.erl
{
38 406 julius
        __asm__ __volatile__("   ;\
39 2 marcus.erl
        l.addi  r8,r0,0x1  ;\
40
        l.mtspr r0,r8,0x11  ;\
41
        l.nop               ;\
42
        l.nop               ;\
43
        l.nop               ;\
44
        l.nop               ;\
45
        l.nop               ;\
46
2:                          ;\
47
        l.sfgeu r4,r5       ;\
48
        l.bf    1f          ;\
49
        l.nop               ;\
50
        l.lwz   r8,0(r3)    ;\
51
        l.sw    0(r4),r8    ;\
52
        l.addi  r3,r3,4     ;\
53
        l.j     2b          ;\
54
        l.addi  r4,r4,4     ;\
55
1:      l.sw    0x0(r0),r6  ;\
56
        l.ori   r8,r0,0x100 ;\
57
        l.jr    r8          ;\
58
        l.nop");
59
}
60 140 julius
#else
61 406 julius
void copy_and_boot(unsigned long src,
62
                   unsigned long dst, unsigned long len, int tx_next)
63 140 julius
{
64 406 julius
        __asm__ __volatile__("   ;\
65 140 julius
        l.addi  r8,r0,0x1  ;\
66
        l.mtspr r0,r8,0x11  ;\
67
        l.nop               ;\
68
        l.nop               ;\
69
        l.nop               ;\
70
        l.nop               ;\
71
        l.nop               ;\
72
2:                          ;\
73
        l.sfgeu r4,r5       ;\
74
        l.bf    1f          ;\
75
        l.nop               ;\
76
        l.lbz   r8,0(r3)    ;\
77
        l.sb    0(r4),r8    ;\
78
        l.addi  r3,r3,1     ;\
79
        l.j     2b          ;\
80
        l.addi  r4,r4,1     ;\
81
1:      l.sw    0x0(r0),r6  ;\
82
        l.ori   r8,r0,0x100 ;\
83
        l.jr    r8          ;\
84
        l.nop");
85
}
86
#endif
87
/* WARNING: stack and non-const globals should not be used in this function
88
   -- it may corrupt what have we loaded;
89 2 marcus.erl
   start_addr should be 0xffffffff if only copying should be made
90
   no return, when start_addr != 0xffffffff, if successful */
91 406 julius
int copy_memory_run(register unsigned long src_addr,
92
                    register unsigned long dst_addr,
93
                    register unsigned long length,
94
                    register int erase, register unsigned long start_addr)
95 2 marcus.erl
{
96 464 julius
#ifdef FLASH_BASE_ADDR
97 406 julius
        unsigned long i, flags;
98 2 marcus.erl
 
99 406 julius
        register char *dst = (char *)dst_addr;
100
        register const char *src = (const char *)src_addr;
101 2 marcus.erl
 
102 406 julius
        if (dst_addr >= FLASH_BASE_ADDR) {
103
                if (dst_addr + length >= FLASH_BASE_ADDR + FLASH_SIZE) {
104
                        printf("error: region does not fit into flash.\n");
105
                        return 1;
106
                }
107 2 marcus.erl
#ifndef CFG_IN_FLASH
108 406 julius
                fl_program(src_addr, dst_addr, length, erase,
109
                           1 /* do verify */ );
110 2 marcus.erl
#else
111 406 julius
                /* we must disable interrupts! */
112
                flags = mfspr(SPR_SR);
113
                mtspr(SPR_SR, flags & ~(SPR_SR_TEE | SPR_SR_IEE));
114
 
115
                printf("Unlocking flash... ");
116
                for (i = 0; i < length; i += FLASH_BLOCK_SIZE)
117
                        fl_ext_unlock(dst_addr + i);
118
                printf("done\n");
119
 
120
                printf("Erasing flash... ");
121
                for (i = 0; i < length; i += FLASH_BLOCK_SIZE)
122
                        fl_ext_erase(dst_addr + i);
123
                printf("done\n");
124
 
125
                printf("Programing flash:\n\t");
126
                for (i = 0; i < length; i += INC_ADDR) {
127
                        if (((i + INC_ADDR) % 1000) == 0)
128
                                printf("#");
129
                        if ((i % (65 * 1000)) == 0)
130
                                printf("\n\t");
131
                        if (fl_ext_program
132
                            (dst_addr + i, reg_read(src_addr + i))) {
133
                                printf("error programing at 0x%08lx!\n",
134
                                       dst_addr + i);
135
                                return 1;
136
                        }
137
                }
138
                printf("Verifying flash... ");
139
                for (i = 0; i < length; i += INC_ADDR) {
140
                        if (reg_read(dst_addr + i) != reg_read(src_addr + i)) {
141
                                printf("error at %08lx: %08lx != %08lx\n",
142
                                       src_addr + i, reg_read(src_addr + i),
143
                                       reg_read(dst_addr + i));
144
                                return 1;
145
                        }
146
                }
147
                printf("OK!\n");
148
                mtspr(SPR_SR, flags);
149 2 marcus.erl
#endif
150 406 julius
                if (start_addr == 0xffffffff)
151
                        return 0;
152
        } else {
153
                while (length--)
154
                        *dst++ = *src++;
155
                if (start_addr == 0xffffffff)
156
                        return 0;
157
        }
158
        /* Run the program */
159
        ((void (*)(void))start_addr) ();
160
        return 0;                /* just to satisfy the cc */
161 464 julius
#else
162
        return -1;
163
#endif
164 2 marcus.erl
}
165
 
166
void bf_jump(unsigned long addr)
167
{
168 406 julius
        asm("l.jr   r3");
169
        asm("l.nop  0x0");
170 2 marcus.erl
}
171
 
172
int boot_flash_cmd(int argc, char *argv[])
173
{
174 464 julius
#ifdef FLASH_BASE_ADDR
175 406 julius
        unsigned long addr, val, jaddr;
176
        addr = 17;
177
        val = 0;
178
        /* clear SR */
179 2 marcus.erl
 
180 406 julius
asm("l.mtspr %0,%1,0": :"r"(addr), "r"(val));
181
        /* jump */
182
        if (argc == 0)
183
                bf_jump(FLASH_BASE_ADDR + 0x100);
184
        else {
185
                jaddr = strtoul(argv[0], 0, 0);
186
                bf_jump(jaddr);
187
        }
188 464 julius
#endif
189 406 julius
        return 0;
190 2 marcus.erl
}
191
 
192 406 julius
void init_load(void)
193 2 marcus.erl
{
194 406 julius
        global.ip = BOARD_DEF_IP;
195
        global.gw_ip = BOARD_DEF_GW;
196
        global.mask = BOARD_DEF_MASK;
197
        global.srv_ip = BOARD_DEF_TBOOT_SRVR;
198 464 julius
        global.src_addr = ((ETH_BUF_SPACE + ETH_DATA_BASE) + 8) & ~0x3;
199 406 julius
        tftp_filename = BOARD_DEF_IMAGE_NAME;
200 140 julius
 
201 2 marcus.erl
}
202
 
203 406 julius
int tftp_cmd(int argc, char *argv[])
204 2 marcus.erl
{
205 406 julius
        switch (argc) {
206
        case 0:
207
                tftp_filename = "boot.img";
208
                break;
209
        case 3:
210
                global.src_addr = strtoul(argv[2], 0, 0);
211
        case 2:
212
                global.srv_ip = parse_ip(argv[1]);
213
        case 1:
214
                tftp_filename = &argv[0][0];
215
                break;
216
        }
217
 
218
        NetLoop(TFTP);          // TFTP is enumerated value in net.h
219
 
220
        return 0;
221 2 marcus.erl
}
222
 
223
int tftp_conf_cmd(int argc, char *argv[])
224
{
225 406 julius
        switch (argc) {
226
        case 0:
227
                printf("Image filename: %s", tftp_filename);
228
                printf("\nSrc addr: 0x%lx", global.src_addr);
229
                printf("\nServer IP: %s", inet_ntoa(global.srv_ip));
230
                return 0;
231
        case 3:
232
                global.src_addr = strtoul(argv[2], 0, 0);
233
                global.srv_ip = inet_aton(argv[1]);
234
                tftp_filename = argv[0];
235
                tftp_filename[strlen(argv[0])] = '\0';
236
                break;
237
        case 2:
238
                global.srv_ip = inet_aton(argv[1]);
239
                tftp_filename = argv[0];
240
                break;
241
        case 1:
242
                tftp_filename = argv[0];
243
                break;
244
        }
245
        return 0;
246 2 marcus.erl
}
247
 
248
void save_global_cfg(flash_cfg_struct cfg)
249
{
250 464 julius
#ifdef FLASH_BASE_ADDR
251 406 julius
        unsigned long dst = (unsigned long)&gcfg, src = (unsigned long)&cfg;
252
        unsigned long i, end, flags;
253 2 marcus.erl
 
254 406 julius
        end = (unsigned long)&cfg + sizeof(flash_cfg_struct);
255 2 marcus.erl
 
256 406 julius
        printf("Saving global cfg from 0x%lx (end: 0x%lx) to 0x%lx...", src,
257
               end, dst);
258 2 marcus.erl
 
259 406 julius
        /* we must disable interrupts! */
260
        flags = mfspr(SPR_SR);
261
        mtspr(SPR_SR, flags & ~(SPR_SR_TEE | SPR_SR_IEE));
262
        /*  printf("Unlocking... "); */
263
        for (i = 0; (src + i <= end); i += FLASH_BLOCK_SIZE) {
264
                fl_ext_unlock(dst + i);
265
        }
266
        /*  printf("done\n"); */
267
        /*  printf("Erasing... "); */
268
        for (i = 0; (src + i <= end); i += FLASH_BLOCK_SIZE)
269
                fl_ext_erase(dst);
270
        /*  printf("done\n"); */
271
        /*  printf("Programing... "); */
272
        for (i = 0; (src + i <= end); i += INC_ADDR) {
273
                if (fl_ext_program(dst + i, reg_read(src + i))) {
274
                        printf("Error ocurred while saving.\n");
275
                        return;
276
                }
277
        }
278
        printf("done\n");
279 2 marcus.erl
 
280 406 julius
        /* and than enable it back */
281
        mtspr(SPR_SR, flags);
282 464 julius
#endif
283 406 julius
        return;
284 2 marcus.erl
}
285
 
286
int save_conf_cmd(int argc, char *argv[])
287
{
288 406 julius
        flash_cfg_struct newCfg;
289 2 marcus.erl
 
290 406 julius
        newCfg = gcfg;
291 2 marcus.erl
 
292 406 julius
        newCfg.eth_ip = global.ip;
293
        newCfg.eth_mask = global.mask;
294
        newCfg.eth_gw = global.gw_ip;
295
        newCfg.tftp_srv_ip = global.srv_ip;
296
        /*  memcpy(newCfg.tftp_filename, tftp_filename, strlen(tftp_filename)); */
297 2 marcus.erl
 
298 406 julius
        save_global_cfg(newCfg);
299
        return 0;
300 2 marcus.erl
}
301 406 julius
 
302
int copy_cmd(int argc, char *argv[])
303 2 marcus.erl
{
304 406 julius
        switch (argc) {
305
        case 3:
306
                global.src_addr = strtoul(argv[2], 0, 0);
307
        case 2:
308
                global.length = strtoul(argv[2], 0, 0);
309
        case 1:
310
                global.src_addr = strtoul(argv[2], 0, 0);
311
        case 0:
312
                return copy_memory_run(global.src_addr, global.dst_addr,
313
                                       global.length, global.erase_method,
314
                                       0xffffffff);
315
        }
316
        return -1;
317 2 marcus.erl
}
318
 
319 406 julius
void images_info(void)
320 2 marcus.erl
{
321 406 julius
        int i;
322
        printf("Number of images: 0x%lx\n", gcfg.img_number);
323
        for (i = 0; i < gcfg.img_number; i++)
324
                printf("%d. image size: 0x%lx (at 0x%08lx)\n", i + 1,
325
                       gcfg.img_length[i], gcfg.img_start_addr[i]);
326 2 marcus.erl
}
327
 
328
/*
329
 * get_good_addr()
330
 *
331
 * Here we try to find the most suitable place for our image. We search for
332
 * a hole between images, that is big enough (but as small as possible).
333
 *
334
 */
335 406 julius
unsigned long get_good_addr(unsigned int size)
336 2 marcus.erl
{
337 464 julius
#ifdef FLASH_BASE_ADDR
338 406 julius
        unsigned long start_addr[MAX_IMAGES], end_addr[MAX_IMAGES];
339
        unsigned long free[MAX_IMAGES], st_addr[MAX_IMAGES];
340
        unsigned long tmpval;
341
        unsigned int i = 0, j;
342 2 marcus.erl
 
343 406 julius
        flash_cfg_struct myCfg;
344
        myCfg = gcfg;
345 2 marcus.erl
 
346 406 julius
        /* we are full */
347
        if (gcfg.img_number == MAX_IMAGES)
348
                return 0xffffffff;
349 2 marcus.erl
 
350 406 julius
        if (gcfg.img_number == 0)
351
                return FLASH_IMAGES_BASE;
352 2 marcus.erl
 
353 406 julius
        for (i = 0; i < MAX_IMAGES; i++) {
354
                start_addr[i] = 0;
355
                end_addr[i] = 0;
356
                free[i] = 0;
357
                st_addr[i] = 0;
358
        }
359 2 marcus.erl
 
360 406 julius
        for (i = 0; i < myCfg.img_number; i++) {
361
                start_addr[i] = myCfg.img_start_addr[i];
362
                end_addr[i] =
363
                    ALIGN((myCfg.img_start_addr[i] + myCfg.img_length[i]),
364
                          FLASH_BLOCK_SIZE);
365
        }
366
        /*  printf("\n");
367
           for(i = 0; i < myCfg.img_number; i++)
368
           printf("start: 0x%08x, end: 0x%08x\n", start_addr[i], end_addr[i]);
369
           printf("\n"); */
370
        /* bubble sorting by start_addr */
371 2 marcus.erl
 
372 406 julius
        for (j = myCfg.img_number - 1; j > 0; j--)
373
                for (i = 0; i < j; i++)
374
                        if (start_addr[i] > start_addr[i + 1]) {
375
                                tmpval = start_addr[i];
376
                                start_addr[i] = start_addr[i + 1];
377
                                start_addr[i + 1] = tmpval;
378
                                tmpval = end_addr[i];
379
                                end_addr[i] = end_addr[i + 1];
380
                                end_addr[i + 1] = tmpval;
381
                        }
382 2 marcus.erl
 
383 406 julius
        /*  for(i = 0; i < myCfg.img_number; i++)
384
           printf("start: 0x%08x, end: 0x%08x\n", start_addr[i], end_addr[i]);
385
           printf("\n"); */
386 2 marcus.erl
 
387 406 julius
        /* now we calculate free space betwens segments */
388
        for (i = 1; i < myCfg.img_number; i++) {
389
                st_addr[i] = end_addr[i - 1];
390
                free[i] = start_addr[i] - end_addr[i - 1];
391
        }
392 2 marcus.erl
 
393 406 julius
        /* here we calcuta first position (starting with FLASH_IMAGES_BASE)... */
394
        st_addr[0] = FLASH_IMAGES_BASE + 0;
395
        free[0] = start_addr[0] - FLASH_IMAGES_BASE;
396
        /* ... and last one (ending with FLASH_IMAGES_BASE + FLASH_SIZE). */
397
        st_addr[myCfg.img_number] = end_addr[myCfg.img_number - 1];
398
        free[myCfg.img_number] = (FLASH_IMAGES_BASE + FLASH_SIZE) -
399
            end_addr[myCfg.img_number - 1];
400 2 marcus.erl
 
401 406 julius
        /* yet another bubble sort by free (space) */
402
        for (j = myCfg.img_number; j > 0; j--)
403
                for (i = 0; i < j; i++)
404
                        if (free[i] > free[i + 1]) {
405
                                tmpval = free[i];
406
                                free[i] = free[i + 1];
407
                                free[i + 1] = tmpval;
408
                                tmpval = st_addr[i];
409
                                st_addr[i] = st_addr[i + 1];
410
                                st_addr[i + 1] = tmpval;
411
                        }
412 2 marcus.erl
 
413 406 julius
        /* now we pick the smallest but just big enough for our size */
414
        for (i = 0; i <= myCfg.img_number; i++)
415
                if (free[i] >= size)
416
                        return st_addr[i];
417 2 marcus.erl
 
418 406 julius
        /* there is not enough space (in one segment) left */
419
        return 0;
420 464 julius
#else
421
        return -1;
422
#endif
423 2 marcus.erl
}
424
 
425 406 julius
unsigned long prepare_img_data(unsigned int num, unsigned int size)
426 2 marcus.erl
{
427 406 julius
        int i;
428
        unsigned long addr = 0;
429
        flash_cfg_struct newCfg;
430 2 marcus.erl
 
431 406 julius
        newCfg = gcfg;
432 2 marcus.erl
 
433 406 julius
        if (newCfg.img_number >= MAX_IMAGES) {
434
                printf("Maximum images exceeded: %d\n", MAX_IMAGES);
435
                return 0xffffffff;
436
        }
437 2 marcus.erl
 
438 406 julius
        newCfg.img_number++;
439 2 marcus.erl
 
440 406 julius
        if ((num > newCfg.img_number) || (num == 0))
441
                num = newCfg.img_number;
442 2 marcus.erl
 
443 406 julius
        addr = get_good_addr(size);
444
        if (addr == 0x00) {
445
                printf
446
                    ("Can not find suitable place in flash. (None of free segments are big enough)\n");
447
                return 0xffffffff;
448
        }
449 2 marcus.erl
 
450 406 julius
        if (num < newCfg.img_number)
451
                for (i = newCfg.img_number - 1; i >= num; i--) {
452
                        newCfg.img_length[i] = newCfg.img_length[i - 1];
453
                        newCfg.img_start_addr[i] = newCfg.img_start_addr[i - 1];
454
                }
455 2 marcus.erl
 
456 406 julius
        newCfg.img_length[num - 1] = size;
457
        newCfg.img_start_addr[num - 1] = addr;
458 2 marcus.erl
 
459 406 julius
        save_global_cfg(newCfg);
460
        return addr;
461 2 marcus.erl
}
462
 
463 406 julius
int del_image_cmd(int argc, char *argv[])
464 2 marcus.erl
{
465 406 julius
        unsigned num, i;
466
        flash_cfg_struct newCfg = gcfg;
467 2 marcus.erl
 
468 406 julius
        newCfg.img_number = gcfg.img_number;
469
        for (i = 0; i < MAX_IMAGES; i++)
470
                newCfg.img_length[i] = gcfg.img_length[i];
471 2 marcus.erl
 
472 406 julius
        printf("Number of images available: 0x%lx\n", newCfg.img_number);
473 2 marcus.erl
 
474 406 julius
        if (argc == 0) {
475
                newCfg.img_number = 0;
476
                for (i = 0; i < MAX_IMAGES; i++) {
477
                        newCfg.img_length[i] = 0;
478
                        newCfg.img_start_addr[i] = 0;
479
                }
480
                save_global_cfg(newCfg);
481
                return 0;
482
        } else {
483
                num = strtoul(argv[0], 0, 0);
484
        }
485 2 marcus.erl
 
486 406 julius
        if (newCfg.img_number == 0) {
487
                printf("Nothing to delete!\n");
488
                return 0;
489
        }
490
        if ((num == 0) || (num > newCfg.img_number))
491
                num = newCfg.img_number;
492 2 marcus.erl
 
493 406 julius
        for (i = num - 1; i < newCfg.img_number; i++) {
494
                newCfg.img_length[i] = newCfg.img_length[i + 1];
495
                newCfg.img_start_addr[i] = newCfg.img_start_addr[i + 1];
496
        }
497
 
498
        newCfg.img_number--;
499
        save_global_cfg(newCfg);
500
        return 0;
501 2 marcus.erl
}
502
 
503 406 julius
int boot_cmd(int argc, char *argv[])
504 2 marcus.erl
{
505 406 julius
        int num;
506
        extern int tx_next;
507 2 marcus.erl
 
508 406 julius
        if (argc == 0) {
509
                images_info();
510
                return 0;
511
        }
512 2 marcus.erl
 
513 406 julius
        num = strtoul(argv[0], 0, 0);
514
        if (gcfg.img_number < num) {
515
                printf("There are only %lu images, you requested %d!\n",
516
                       gcfg.img_number, num);
517
                return -1;
518
        }
519 2 marcus.erl
 
520 406 julius
        printf("Copying image number %d from 0x%lx, size: 0x%lx...",
521
               num, gcfg.img_start_addr[num - 1], gcfg.img_length[num - 1]);
522 2 marcus.erl
 
523 406 julius
        printf("booting...\n");
524
        copy_and_boot(gcfg.img_start_addr[num - 1], 0x0,
525
                      gcfg.img_length[num - 1], tx_next);
526
        return 0;
527 2 marcus.erl
}
528
 
529
int mGetData(unsigned long);
530
 
531 406 julius
#if 0                           // Disable sboot - JB
532
int sboot_cmd(int argc, char *argv[])
533 2 marcus.erl
{
534 406 julius
        int copied;
535
        unsigned int num = 0xffffffff, addr = 0x0;
536 2 marcus.erl
 
537 406 julius
        switch (argc) {
538
        case 0:
539
                num = 0xffffffff;
540
                break;
541
        case 1:
542
                num = strtoul(argv[0], 0, 0);
543
                break;
544
        }
545 2 marcus.erl
 
546 406 julius
        copied = mGetData(global.src_addr);
547
        if (copied <= 0) {
548
                printf("sboot: error while getting the image!");
549
                return -1;
550
        }
551
        printf("image size: 0x%x\n", copied);
552 2 marcus.erl
 
553 406 julius
        if (num != 0xffffffff) {
554
                addr = prepare_img_data(num, copied);
555
                if (addr == 0xffffffff)
556
                        printf("Image not written to flash!\n");
557
                else {
558
                        printf
559
                            ("Copying image to flash, image number: %d, dst_addr: 0x%x\n",
560
                             num, addr);
561
                        copy_memory_run(global.src_addr,
562
                                        gcfg.img_start_addr[num - 1], copied, 2,
563
                                        0xffffffff);
564
                }
565
        }
566 2 marcus.erl
 
567 406 julius
        return 0;
568 2 marcus.erl
}
569 140 julius
#endif
570 2 marcus.erl
 
571 406 julius
void relocate_code(void *destination, void *function, int length_words)
572 140 julius
{
573 406 julius
        // Just copy the function word at a time from one place to another
574
        int i;
575
        unsigned long *p1 = (unsigned long *)destination;
576
        unsigned long *p2 = (unsigned long *)function;
577
        for (i = 0; i < length_words; i++)
578
                p1[i] = p2[i];
579 140 julius
}
580
 
581 246 julius
// DC disable command in cpu.c
582
extern int dc_disable_cmd(int argc, char *argv[]);
583
 
584 406 julius
int tboot_cmd(int argc, char *argv[])
585 2 marcus.erl
{
586 406 julius
        int copied;
587
        unsigned int num = 0xffffffff, addr = 0x0;
588
        extern int tx_next;
589
        // NetTxPacket wasn't getting cleared before we used it...
590
        NetTxPacket = 0;
591
        NetBootFileSize = 0;
592 2 marcus.erl
 
593 406 julius
        switch (argc) {
594
        case 0:
595
                num = 0xffffffff;
596
                break;
597
        case 1:
598
                printf("argv[0] %p\n", argv[0]);
599
                num = strtoul(argv[0], 0, 0);
600
                printf("num %d\n", num);
601
                break;
602
        }
603 2 marcus.erl
 
604 406 julius
        // Disable data cache if present
605
        if (mfspr(SPR_SR) & SPR_SR_DCE) {
606
                printf("Disabling data cache\n");
607
                dc_disable_cmd(0, 0);
608
        }
609
        // Kick off copy
610
        copied = NetLoop(TFTP);
611
        if (copied <= 0) {
612
                printf("tboot: error while getting the image '%s'",
613
                       tftp_filename);
614
                return -1;
615
        }
616 2 marcus.erl
 
617 406 julius
        if (global.src_addr > 0) {
618
                /* the point of no return */
619
                printf("tboot: copying 0x%lx -> 0x0, image size 0x%x...\n",
620
                       global.src_addr, copied);
621
        }
622
        // Disable timer: clear it all!
623
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
624
        mtspr(SPR_TTMR, 0);
625 2 marcus.erl
 
626 406 julius
        printf("tboot: relocating copy loop to 0x%x ...\n",
627
               (unsigned long)COPYBOOT_LOCATION);
628
        // Setup where we'll copy the relocation function to
629
        void (*relocated_function) (unsigned long, unsigned long, unsigned long,
630
                                    int)
631
            = (void *)COPYBOOT_LOCATION;
632
        // Now copy the function there, 32 words worth, increase this if needed...
633
        relocate_code((void *)COPYBOOT_LOCATION, copy_and_boot, 32);
634
        // Indicate we'll jump there...
635
        printf
636
            ("tboot: Relocate (%d bytes from 0x%x to 0) and boot image, ...\n",
637
             copied, (unsigned long)global.src_addr);
638
        // Now do the copy and boot
639
        (*relocated_function) (global.src_addr, 0x0, 0x0 + copied, tx_next);
640 140 julius
 
641 406 julius
        return 0;
642 2 marcus.erl
}
643
 
644 406 julius
int sdboot_cmd(int argc, char *argv[])
645 389 tac2
{
646 406 julius
        VOLINFO vi;
647 389 tac2
        unsigned char *buf_ptr;
648 406 julius
 
649 389 tac2
        unsigned char sector[SECTOR_SIZE], sector2[SECTOR_SIZE];
650
        FILEINFO fi;
651 406 julius
        unsigned long int pstart, psize, i, fisz;
652
        unsigned char pactive, ptype;
653 389 tac2
        DIRINFO di;
654
        DIRENT de;
655
        unsigned long int cache;
656 140 julius
 
657 406 julius
        // Obtain pointer to first partition on first (only) unit
658
        // Disable data cache if present
659
        if (mfspr(SPR_SR) & SPR_SR_DCE) {
660
                printf("Disabling data cache\n");
661
                dc_disable_cmd(0, 0);
662
        }
663
 
664
        buf_ptr = global.src_addr;
665
 
666 389 tac2
        printf("SD-BOOT start \n");
667 406 julius
        i = init_fat(&vi);
668
 
669 389 tac2
        printf("Volume label '%-11.11s'\n", vi.label);
670 406 julius
        printf
671
            ("%d sector/s per cluster, %d reserved sector/s, volume total %d sectors.\n",
672
             vi.secperclus, vi.reservedsecs, vi.numsecs);
673
        printf
674
            ("%d sectors per FAT, first FAT at sector #%d, root dir at #%d.\n",
675
             vi.secperfat, vi.fat1, vi.rootdir);
676
        printf
677
            ("(For FAT32, the root dir is a CLUSTER number, FAT12/16 it is a SECTOR number)\n");
678
        printf("%d root dir entries, data area commences at sector #%d.\n",
679
               vi.rootentries, vi.dataarea);
680
        printf("%d clusters (%d bytes) in data area, filesystem IDd as ",
681
               vi.numclusters, vi.numclusters * vi.secperclus * SECTOR_SIZE);
682 389 tac2
        if (vi.filesystem == FAT12)
683
                printf("FAT12.\n");
684
        else if (vi.filesystem == FAT16)
685
                printf("FAT16.\n");
686
        else if (vi.filesystem == FAT32)
687
                printf("FAT32.\n");
688
        else
689
                printf("[unknown]\n");
690 406 julius
 
691 389 tac2
        if (DFS_OpenDir(&vi, "", &di)) {
692 406 julius
                printf("Error opening root directory\n");
693 389 tac2
                return -1;
694
        }
695 140 julius
 
696 389 tac2
        printf("Readback test\n");
697 406 julius
        if (DFS_OpenFile(&vi, "vmlinux.bin", DFS_READ, sector, &fi)) {
698
                printf("error opening file\n");
699
 
700 389 tac2
                return -1;
701
        }
702 406 julius
 
703
        printf("fi.filen %d, pointer adress:%d, data:%d \n", fi.filelen,
704
               buf_ptr, *buf_ptr);
705
 
706 389 tac2
        DFS_ReadFile(&fi, sector, buf_ptr, &i, fi.filelen);
707 406 julius
        printf("\n read complete %d bytes (expected %d) pointer %d\n", i,
708
               fi.filelen, fi.pointer);
709 140 julius
 
710 406 julius
        if (global.src_addr > 0) {
711
                /* the point of no return */
712
                printf("tboot: copying 0x%lx -> 0x0, image size 0x%x...\n",
713
                       global.src_addr, i);
714
        }
715 389 tac2
 
716 406 julius
        // Disable timer: clear it all!
717
        mtspr(SPR_SR, mfspr(SPR_SR) & ~SPR_SR_TEE);
718
        mtspr(SPR_TTMR, 0);
719
 
720
        printf("tboot: relocating copy loop to 0x%x ...\n",
721
               (unsigned long)COPYBOOT_LOCATION);
722
        // Setup where we'll copy the relocation function to
723
        void (*relocated_function) (unsigned long, unsigned long, unsigned long,
724
                                    int)
725
            = (void *)COPYBOOT_LOCATION;
726
        // Now copy the function there, 32 words worth, increase this if needed...
727
        relocate_code((void *)COPYBOOT_LOCATION, copy_and_boot, 32);
728
        // Indicate we'll jump there...
729
        printf
730
            ("tboot: Relocate (%d bytes from 0x%x to 0) and boot image, ...\n",
731
             i, (unsigned long)global.src_addr);
732
        // Now do the copy and boot
733
        (*relocated_function) (global.src_addr, 0x0, 0x0 + i, 0);
734
 
735
        return 0;
736
 
737 389 tac2
}
738
 
739 406 julius
void module_load_init(void)
740 2 marcus.erl
{
741 140 julius
 
742 406 julius
        register_command("tftp_conf", "[ <file> [ <srv_ip> [ <src_addr>]]]",
743
                         "TFTP configuration", tftp_conf_cmd);
744
        register_command("tboot", "[<image number>]",
745
                         "Bootstrap image downloaded via tftp", tboot_cmd);
746
        register_command("sdboot", "[<image number>]",
747
                         "Read image from SD-CARD", sdboot_cmd);
748 140 julius
#if 0
749 406 julius
        register_command("tftp", "[<file> [<srv_ip> [<src_addr>]]]",
750
                         "TFTP download", tftp_cmd);
751
        register_command("copy", "[<dst_addr> [<src_addr [<length>]]]",
752
                         "Copy memory", copy_cmd);
753
        register_command("sboot", "[<image number>]",
754
                         "Bootstrap image downloaded via serial (Y/X modem)",
755
                         sboot_cmd);
756
        register_command("boot", "[<image number>]",
757
                         "Bootstrap image copied from flash.", boot_cmd);
758
        register_command("del_image", "[<image number>]", "Delete image",
759
                         del_image_cmd);
760
        register_command("save_conf", "",
761
                         "Save current configuration into flash",
762
                         save_conf_cmd);
763
        register_command("boot_flash", "[<start_addr>]",
764
                         "Boot image from <start_addr> (default from flash)",
765
                         boot_flash_cmd);
766 140 julius
#endif
767 406 julius
        init_load();
768 389 tac2
 
769 2 marcus.erl
}

powered by: WebSVN 2.1.0

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