source: SVN/rincon/u-boot/board/MAI/AmigaOneG3SE/cmd_boota.c @ 55

Last change on this file since 55 was 55, checked in by Tim Harvey, 22 months ago

rincon: added latest u-boot source

restored form server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 3.0 KB
Line 
1#include <common.h>
2#include <command.h>
3#include "../disk/part_amiga.h"
4#include <asm/cache.h>
5
6DECLARE_GLOBAL_DATA_PTR;
7
8#undef BOOTA_DEBUG
9
10#ifdef BOOTA_DEBUG
11#define PRINTF(fmt,args...)     printf (fmt ,##args)
12#else
13#define PRINTF(fmt,args...)
14#endif
15
16struct block_header {
17        u32 id;
18        u32 summed_longs;
19        s32 chk_sum;
20};
21
22extern block_dev_desc_t *ide_get_dev (int dev);
23extern struct bootcode_block *get_bootcode (block_dev_desc_t * dev_desc);
24extern int sum_block (struct block_header *header);
25
26struct bootcode_block bblk;
27
28int do_boota (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
29{
30        unsigned char *load_address = (unsigned char *) CFG_LOAD_ADDR;
31        unsigned char *base_address;
32        unsigned long offset;
33
34        unsigned long part_number = 0;
35        block_dev_desc_t *boot_disk;
36        char *s;
37        struct bootcode_block *boot_code;
38
39        /* Get parameters */
40
41        switch (argc) {
42        case 2:
43                load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
44                part_number = 0;
45                break;
46        case 3:
47                load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
48                part_number = simple_strtol (argv[2], NULL, 16);
49                break;
50        }
51
52        base_address = load_address;
53
54        PRINTF ("Loading boot code from disk %d to %p\n", part_number,
55                        load_address);
56
57        /* Find the appropriate disk device */
58        boot_disk = ide_get_dev (part_number);
59        if (!boot_disk) {
60                PRINTF ("Unknown disk %d\n", part_number);
61                return 1;
62        }
63
64        /* Find the bootcode block */
65        boot_code = get_bootcode (boot_disk);
66        if (!boot_code) {
67                PRINTF ("Not a bootable disk %d\n", part_number);
68                return 1;
69        }
70
71        /* Only use the offset from the first block */
72        offset = boot_code->load_data[0];
73        memcpy (load_address, &boot_code->load_data[1], 122 * 4);
74        load_address += 122 * 4;
75
76        /* Setup for the loop */
77        bblk.next = boot_code->next;
78        boot_code = &bblk;
79
80        /* Scan the chain, and copy the loader succesively into the destination area */
81        while (0xffffffff != boot_code->next) {
82                PRINTF ("Loading block %d\n", boot_code->next);
83
84                /* Load block */
85                if (1 !=
86                        boot_disk->block_read (boot_disk->dev, boot_code->next, 1,
87                                                                   (ulong *) & bblk)) {
88                        PRINTF ("Read error\n");
89                        return 1;
90                }
91
92                /* check sum */
93                if (sum_block ((struct block_header *) (ulong *) & bblk) != 0) {
94                        PRINTF ("Checksum error\n");
95                        return 1;
96                }
97
98                /* Ok, concatenate it to the already loaded code */
99                memcpy (load_address, boot_code->load_data, 123 * 4);
100                load_address += 123 * 4;
101        }
102
103        printf ("Bootcode loaded to %p (size %d)\n", base_address,
104                        load_address - base_address);
105        printf ("Entry point at %p\n", base_address + offset);
106
107        flush_cache (base_address, load_address - base_address);
108
109
110        s = getenv ("autostart");
111        if (s && strcmp (s, "yes") == 0) {
112                void (*boot) (bd_t *, char *, block_dev_desc_t *);
113                char *args;
114
115                boot = (void (*)(bd_t *, char *, block_dev_desc_t *)) (base_address + offset);
116                boot (gd->bd, getenv ("amiga_bootargs"), boot_disk);
117        }
118
119
120        return 0;
121}
122#if defined(CONFIG_AMIGAONEG3SE) && defined(CONFIG_CMD_BSP)
123U_BOOT_CMD(
124        boota,   3,      1,      do_boota,
125        "boota   - boot an Amiga kernel\n",
126        "address disk"
127);
128#endif /* _CMD_BOOTA_H */
Note: See TracBrowser for help on using the repository browser.