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

Subversion Repositories openrisc

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

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

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

powered by: WebSVN 2.1.0

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