diff --git a/qiboot/include/qi.h b/qiboot/include/qi.h index c8971e6..2592cd4 100644 --- a/qiboot/include/qi.h +++ b/qiboot/include/qi.h @@ -47,6 +47,21 @@ enum ui_actions { UI_ACTION_SKIPKERNEL = (1 << 1), }; +enum ui_indication { + UI_IND_UPDATE_ONLY, + UI_IND_MOUNT_PART, + UI_IND_MOUNT_FAIL, + UI_IND_SKIPPING, + UI_IND_KERNEL_PULL, + UI_IND_KERNEL_PULL_OK, + UI_IND_KERNEL_PULL_FAIL, + UI_IND_INITRAMFS_PULL, + UI_IND_INITRAMFS_PULL_OK, + UI_IND_INITRAMFS_PULL_FAIL, + UI_IND_KERNEL_START, + UI_IND_MEM_TEST +}; + /* describes a source for getting kernel image */ struct kernel_source { @@ -89,6 +104,7 @@ struct board_api { void (*putc)(char); void (*close)(void); u8 (*get_ui_keys)(void); + void (*set_ui_indication)(enum ui_indication); struct kernel_source kernel_source[8]; }; diff --git a/qiboot/src/cpu/s3c2442/gta02.c b/qiboot/src/cpu/s3c2442/gta02.c index 7b78b81..708e8a8 100644 --- a/qiboot/src/cpu/s3c2442/gta02.c +++ b/qiboot/src/cpu/s3c2442/gta02.c @@ -396,6 +396,40 @@ static u8 get_ui_keys_gta02(void) return ret; } + +static void set_ui_indication_gta02(enum ui_indication ui_indication) +{ + switch (ui_indication) { + case UI_IND_UPDATE_ONLY: + break; + + case UI_IND_MOUNT_PART: + case UI_IND_KERNEL_PULL_OK: + case UI_IND_INITRAMFS_PULL_OK: + rGPBDAT |= 4; + break; + + case UI_IND_KERNEL_PULL_FAIL: + case UI_IND_SKIPPING: + case UI_IND_INITRAMFS_PULL_FAIL: + case UI_IND_MOUNT_FAIL: + rGPBDAT &= ~4; + rGPBDAT |= 8; + udelay(2000000); + rGPBDAT &= ~8; + udelay(200000); + break; + + case UI_IND_KERNEL_START: + case UI_IND_MEM_TEST: + case UI_IND_KERNEL_PULL: + case UI_IND_INITRAMFS_PULL: + rGPBDAT &= ~4; + break; + } +} + + /* * our API for bootloader on this machine */ @@ -412,6 +446,7 @@ const struct board_api board_api_gta02 = { .putc = putc_gta02, .close = close_gta02, .get_ui_keys = get_ui_keys_gta02, + .set_ui_indication = set_ui_indication_gta02, .commandline_board = "mtdparts=physmap-flash:-(nor);" \ "neo1973-nand:" \ "0x00040000(qi)," \ diff --git a/qiboot/src/phase2.c b/qiboot/src/phase2.c index 2100d74..eeb81a1 100644 --- a/qiboot/src/phase2.c +++ b/qiboot/src/phase2.c @@ -37,11 +37,18 @@ struct kernel_source const * this_kernel = 0; const int INITRD_OFFSET = (8 * 1024 * 1024); + int raise(int n) { return 0; } +void indicate(enum ui_indication ui_indication) +{ + if (this_board->set_ui_indication) + (this_board->set_ui_indication)(ui_indication); +} + int read_file(const char * filepath, u8 * destination, int size) { int len = size; @@ -51,6 +58,7 @@ int read_file(const char * filepath, u8 * destination, int size) case FS_EXT2: if (!ext2fs_mount()) { puts("Unable to mount ext2 filesystem\n"); + indicate(UI_IND_MOUNT_FAIL); return -1; } puts(" EXT2 open: "); @@ -120,12 +128,15 @@ void bootloader_second_phase(void) puts(this_kernel->name); puts("\n"); + indicate(UI_IND_MOUNT_PART); + /* if this device needs initializing, try to init it */ if (this_kernel->block_init) if ((this_kernel->block_init)()) { puts("block device init failed\n"); this_kernel = &this_board-> kernel_source[kernel++]; + indicate(UI_IND_MOUNT_FAIL); continue; } @@ -140,6 +151,7 @@ void bootloader_second_phase(void) puts("Bad partition read\n"); this_kernel = &this_board-> kernel_source[kernel++]; + indicate(UI_IND_MOUNT_FAIL); continue; } @@ -147,6 +159,7 @@ void bootloader_second_phase(void) puts("partition signature missing\n"); this_kernel = &this_board-> kernel_source[kernel++]; + indicate(UI_IND_MOUNT_FAIL); continue; } @@ -181,6 +194,7 @@ void bootloader_second_phase(void) puts(this_board->noboot); puts(")\n"); this_kernel = &this_board->kernel_source[kernel++]; + indicate(UI_IND_SKIPPING); continue; } @@ -190,6 +204,8 @@ void bootloader_second_phase(void) read_file(this_board->append, (u8 *)commandline_rootfs_append, 512); + indicate(UI_IND_KERNEL_PULL); + /* pull the kernel image */ if (read_file(this_kernel->filepath, kernel_dram, 4096) < 0) { @@ -219,19 +235,26 @@ void bootloader_second_phase(void) if (read_file(this_kernel->filepath, kernel_dram, kernel_size) < 0) { this_kernel = &this_board->kernel_source[kernel++]; + indicate(UI_IND_KERNEL_PULL_FAIL); continue; } + indicate(UI_IND_KERNEL_PULL_OK); + /* initramfs if needed */ if (this_kernel->initramfs_filepath) { + indicate(UI_IND_INITRAMFS_PULL); initramfs_len = read_file(this_kernel->initramfs_filepath, - (u8 *)this_board->linux_mem_start + INITRD_OFFSET, 16 * 1024 * 1024); + (u8 *)this_board->linux_mem_start + INITRD_OFFSET, + 16 * 1024 * 1024); if (initramfs_len < 0) { puts("initramfs load failed\n"); this_kernel = &this_board->kernel_source[kernel++]; + indicate(UI_IND_INITRAMFS_PULL_FAIL); continue; } + indicate(UI_IND_INITRAMFS_PULL_OK); } /* @@ -329,6 +352,7 @@ void bootloader_second_phase(void) (this_board->close)(); puts ("Starting --->\n\n"); + indicate(UI_IND_KERNEL_START); /* * ooh that's it, we're gonna try boot this image! @@ -355,6 +379,8 @@ void bootloader_second_phase(void) * to provoke memory test. */ + indicate(UI_IND_MEM_TEST); + memory_test((void *)this_board->linux_mem_start, this_board->linux_mem_size);