]>
Commit | Line | Data |
---|---|---|
c7de829c WD |
1 | #include <common.h> |
2 | #include <command.h> | |
c7de829c WD |
3 | #include "../disk/part_amiga.h" |
4 | #include <asm/cache.h> | |
5 | ||
d87080b7 | 6 | DECLARE_GLOBAL_DATA_PTR; |
c7de829c WD |
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 | ||
16 | struct block_header { | |
17 | u32 id; | |
18 | u32 summed_longs; | |
19 | s32 chk_sum; | |
20 | }; | |
21 | ||
22 | extern block_dev_desc_t *ide_get_dev (int dev); | |
23 | extern struct bootcode_block *get_bootcode (block_dev_desc_t * dev_desc); | |
24 | extern int sum_block (struct block_header *header); | |
25 | ||
26 | struct bootcode_block bblk; | |
27 | ||
28 | int do_boota (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) | |
29 | { | |
6d0f6bcf | 30 | unsigned char *load_address = (unsigned char *) CONFIG_SYS_LOAD_ADDR; |
c7de829c WD |
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) { | |
c7de829c WD |
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 | } | |
fcec2eb9 | 122 | #if defined(CONFIG_AMIGAONEG3SE) && defined(CONFIG_CMD_BSP) |
0d498393 WD |
123 | U_BOOT_CMD( |
124 | boota, 3, 1, do_boota, | |
8bde7f77 WD |
125 | "boota - boot an Amiga kernel\n", |
126 | "address disk" | |
127 | ); | |
128 | #endif /* _CMD_BOOTA_H */ |