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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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