123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- #include <common.h>
- #include <command.h>
- #include "../disk/part_amiga.h"
- #include <asm/cache.h>
- DECLARE_GLOBAL_DATA_PTR;
- #undef BOOTA_DEBUG
- #ifdef BOOTA_DEBUG
- #define PRINTF(fmt,args...) printf (fmt ,##args)
- #else
- #define PRINTF(fmt,args...)
- #endif
- struct block_header {
- u32 id;
- u32 summed_longs;
- s32 chk_sum;
- };
- extern block_dev_desc_t *ide_get_dev (int dev);
- extern struct bootcode_block *get_bootcode (block_dev_desc_t * dev_desc);
- extern int sum_block (struct block_header *header);
- struct bootcode_block bblk;
- int do_boota (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
- {
- unsigned char *load_address = (unsigned char *) CFG_LOAD_ADDR;
- unsigned char *base_address;
- unsigned long offset;
- unsigned long part_number = 0;
- block_dev_desc_t *boot_disk;
- char *s;
- struct bootcode_block *boot_code;
- /* Get parameters */
- switch (argc) {
- case 2:
- load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
- part_number = 0;
- break;
- case 3:
- load_address = (unsigned char *) simple_strtol (argv[1], NULL, 16);
- part_number = simple_strtol (argv[2], NULL, 16);
- break;
- }
- base_address = load_address;
- PRINTF ("Loading boot code from disk %d to %p\n", part_number,
- load_address);
- /* Find the appropriate disk device */
- boot_disk = ide_get_dev (part_number);
- if (!boot_disk) {
- PRINTF ("Unknown disk %d\n", part_number);
- return 1;
- }
- /* Find the bootcode block */
- boot_code = get_bootcode (boot_disk);
- if (!boot_code) {
- PRINTF ("Not a bootable disk %d\n", part_number);
- return 1;
- }
- /* Only use the offset from the first block */
- offset = boot_code->load_data[0];
- memcpy (load_address, &boot_code->load_data[1], 122 * 4);
- load_address += 122 * 4;
- /* Setup for the loop */
- bblk.next = boot_code->next;
- boot_code = &bblk;
- /* Scan the chain, and copy the loader succesively into the destination area */
- while (0xffffffff != boot_code->next) {
- PRINTF ("Loading block %d\n", boot_code->next);
- /* Load block */
- if (1 !=
- boot_disk->block_read (boot_disk->dev, boot_code->next, 1,
- (ulong *) & bblk)) {
- PRINTF ("Read error\n");
- return 1;
- }
- /* check sum */
- if (sum_block ((struct block_header *) (ulong *) & bblk) != 0) {
- PRINTF ("Checksum error\n");
- return 1;
- }
- /* Ok, concatenate it to the already loaded code */
- memcpy (load_address, boot_code->load_data, 123 * 4);
- load_address += 123 * 4;
- }
- printf ("Bootcode loaded to %p (size %d)\n", base_address,
- load_address - base_address);
- printf ("Entry point at %p\n", base_address + offset);
- flush_cache (base_address, load_address - base_address);
- s = getenv ("autostart");
- if (s && strcmp (s, "yes") == 0) {
- void (*boot) (bd_t *, char *, block_dev_desc_t *);
- char *args;
- boot = (void (*)(bd_t *, char *, block_dev_desc_t *)) (base_address + offset);
- boot (gd->bd, getenv ("amiga_bootargs"), boot_disk);
- }
- return 0;
- }
- #if defined(CONFIG_AMIGAONEG3SE) && (CONFIG_COMMANDS & CFG_CMD_BSP)
- U_BOOT_CMD(
- boota, 3, 1, do_boota,
- "boota - boot an Amiga kernel\n",
- "address disk"
- );
- #endif /* _CMD_BOOTA_H */
|