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