diff options
author | Kevin | 2014-11-15 11:48:36 +0800 |
---|---|---|
committer | Kevin | 2014-11-15 11:48:36 +0800 |
commit | d04075478d378d9e15f3e1abfd14b0bd124077d4 (patch) | |
tree | 733dd964582f388b9e3e367c249946cd32a2851f /board/MAI/AmigaOneG3SE/cmd_boota.c | |
download | FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.gz FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.tar.bz2 FOSSEE-netbook-uboot-source-d04075478d378d9e15f3e1abfd14b0bd124077d4.zip |
init commit via android 4.4 uboot
Diffstat (limited to 'board/MAI/AmigaOneG3SE/cmd_boota.c')
-rwxr-xr-x | board/MAI/AmigaOneG3SE/cmd_boota.c | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/board/MAI/AmigaOneG3SE/cmd_boota.c b/board/MAI/AmigaOneG3SE/cmd_boota.c new file mode 100755 index 0000000..3e2835a --- /dev/null +++ b/board/MAI/AmigaOneG3SE/cmd_boota.c @@ -0,0 +1,129 @@ +#include <common.h> +#include <command.h> +#include "../disk/part_amiga.h" +#include <asm/cache.h> + + +#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) { + DECLARE_GLOBAL_DATA_PTR; + + 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 */ |