diff options
Diffstat (limited to 'bootloader/x1000')
-rw-r--r-- | bootloader/x1000/boot.c | 18 | ||||
-rw-r--r-- | bootloader/x1000/gui.c | 69 | ||||
-rw-r--r-- | bootloader/x1000/install.c | 6 | ||||
-rw-r--r-- | bootloader/x1000/main.c | 2 | ||||
-rw-r--r-- | bootloader/x1000/utils.c | 22 | ||||
-rw-r--r-- | bootloader/x1000/x1000bootloader.h | 4 |
6 files changed, 82 insertions, 39 deletions
diff --git a/bootloader/x1000/boot.c b/bootloader/x1000/boot.c index d6dfd4a193..60fb864d19 100644 --- a/bootloader/x1000/boot.c +++ b/bootloader/x1000/boot.c | |||
@@ -43,14 +43,14 @@ void boot_rockbox(void) | |||
43 | 43 | ||
44 | void shutdown(void) | 44 | void shutdown(void) |
45 | { | 45 | { |
46 | splash(HZ, "Shutting down"); | 46 | splashf(HZ, "Shutting down"); |
47 | power_off(); | 47 | power_off(); |
48 | while(1); | 48 | while(1); |
49 | } | 49 | } |
50 | 50 | ||
51 | void reboot(void) | 51 | void reboot(void) |
52 | { | 52 | { |
53 | splash(HZ, "Rebooting"); | 53 | splashf(HZ, "Rebooting"); |
54 | system_reboot(); | 54 | system_reboot(); |
55 | while(1); | 55 | while(1); |
56 | } | 56 | } |
@@ -70,13 +70,13 @@ static int read_linux_args(const char* filename) | |||
70 | size_t max_size; | 70 | size_t max_size; |
71 | int handle = core_alloc_maximum("args", &max_size, &buflib_ops_locked); | 71 | int handle = core_alloc_maximum("args", &max_size, &buflib_ops_locked); |
72 | if(handle <= 0) { | 72 | if(handle <= 0) { |
73 | splash(5*HZ, "Out of memory"); | 73 | splashf(5*HZ, "Out of memory"); |
74 | return -2; | 74 | return -2; |
75 | } | 75 | } |
76 | 76 | ||
77 | int fd = open(filename, O_RDONLY); | 77 | int fd = open(filename, O_RDONLY); |
78 | if(fd < 0) { | 78 | if(fd < 0) { |
79 | splash2(5*HZ, "Can't open args file", filename); | 79 | splashf(5*HZ, "Can't open args file\n%s", filename); |
80 | ret = -3; | 80 | ret = -3; |
81 | goto err_free; | 81 | goto err_free; |
82 | } | 82 | } |
@@ -84,7 +84,7 @@ static int read_linux_args(const char* filename) | |||
84 | /* this isn't 100% correct but will be good enough */ | 84 | /* this isn't 100% correct but will be good enough */ |
85 | off_t fsize = filesize(fd); | 85 | off_t fsize = filesize(fd); |
86 | if(fsize < 0 || fsize+1 > (off_t)max_size) { | 86 | if(fsize < 0 || fsize+1 > (off_t)max_size) { |
87 | splash(5*HZ, "Arguments too long"); | 87 | splashf(5*HZ, "Arguments too long"); |
88 | ret = -4; | 88 | ret = -4; |
89 | goto err_close; | 89 | goto err_close; |
90 | } | 90 | } |
@@ -96,7 +96,7 @@ static int read_linux_args(const char* filename) | |||
96 | close(fd); | 96 | close(fd); |
97 | 97 | ||
98 | if(rdres != (ssize_t)fsize) { | 98 | if(rdres != (ssize_t)fsize) { |
99 | splash(5*HZ, "Can't read args file"); | 99 | splashf(5*HZ, "Can't read args file"); |
100 | ret = -5; | 100 | ret = -5; |
101 | goto err_free; | 101 | goto err_free; |
102 | } | 102 | } |
@@ -191,7 +191,7 @@ void boot_of_helper(uint32_t addr, uint32_t flash_size, const char* args) | |||
191 | void* jump_addr = core_get_data(handle); | 191 | void* jump_addr = core_get_data(handle); |
192 | uint32_t entry_addr = mips_linux_stub_get_entry(&jump_addr, img_length); | 192 | uint32_t entry_addr = mips_linux_stub_get_entry(&jump_addr, img_length); |
193 | if(entry_addr >= 0xa0000000 || entry_addr < 0x80000000) { | 193 | if(entry_addr >= 0xa0000000 || entry_addr < 0x80000000) { |
194 | splash2(5*HZ, "Kernel patch failed", "Please send bugreport"); | 194 | splashf(5*HZ, "Kernel patch failed\nPlease send bugreport"); |
195 | return; | 195 | return; |
196 | } | 196 | } |
197 | 197 | ||
@@ -216,7 +216,7 @@ void boot_of_player(void) | |||
216 | #if defined(OF_PLAYER_ADDR) | 216 | #if defined(OF_PLAYER_ADDR) |
217 | boot_of_helper(OF_PLAYER_ADDR, OF_PLAYER_LENGTH, OF_PLAYER_ARGS); | 217 | boot_of_helper(OF_PLAYER_ADDR, OF_PLAYER_LENGTH, OF_PLAYER_ARGS); |
218 | #else | 218 | #else |
219 | splash(HZ, "Not supported"); | 219 | splashf(HZ, "Not supported"); |
220 | #endif | 220 | #endif |
221 | } | 221 | } |
222 | 222 | ||
@@ -225,6 +225,6 @@ void boot_of_recovery(void) | |||
225 | #if defined(OF_RECOVERY_ADDR) | 225 | #if defined(OF_RECOVERY_ADDR) |
226 | boot_of_helper(OF_RECOVERY_ADDR, OF_RECOVERY_LENGTH, OF_RECOVERY_ARGS); | 226 | boot_of_helper(OF_RECOVERY_ADDR, OF_RECOVERY_LENGTH, OF_RECOVERY_ARGS); |
227 | #else | 227 | #else |
228 | splash(HZ, "Not supported"); | 228 | splashf(HZ, "Not supported"); |
229 | #endif | 229 | #endif |
230 | } | 230 | } |
diff --git a/bootloader/x1000/gui.c b/bootloader/x1000/gui.c index a672c30380..513a3cb9cb 100644 --- a/bootloader/x1000/gui.c +++ b/bootloader/x1000/gui.c | |||
@@ -29,6 +29,8 @@ | |||
29 | #include "button.h" | 29 | #include "button.h" |
30 | #include "version.h" | 30 | #include "version.h" |
31 | #include <string.h> | 31 | #include <string.h> |
32 | #include <stdarg.h> | ||
33 | #include <stdio.h> | ||
32 | 34 | ||
33 | static bool lcd_inited = false; | 35 | static bool lcd_inited = false; |
34 | extern bool is_usb_connected; | 36 | extern bool is_usb_connected; |
@@ -53,27 +55,70 @@ void putcenter_y(int y, const char* msg) | |||
53 | lcd_putsxy(x, y, msg); | 55 | lcd_putsxy(x, y, msg); |
54 | } | 56 | } |
55 | 57 | ||
56 | void putcenter_line(int line, const char* msg) | 58 | static void get_splash_size(const char* str, int* width, int* height) |
57 | { | 59 | { |
58 | int y = LCD_HEIGHT/2 + (line - 1)*SYSFONT_HEIGHT; | 60 | *width = 0; |
59 | putcenter_y(y, msg); | 61 | *height = 0; |
62 | |||
63 | while(str) { | ||
64 | const char* np = strchr(str, '\n'); | ||
65 | int len; | ||
66 | if(np) { | ||
67 | len = np - str; | ||
68 | np++; | ||
69 | } else { | ||
70 | len = strlen(str); | ||
71 | } | ||
72 | |||
73 | *width = MAX(len, *width); | ||
74 | *height += 1; | ||
75 | str = np; | ||
76 | } | ||
60 | } | 77 | } |
61 | 78 | ||
62 | void splash2(long delay, const char* msg, const char* msg2) | 79 | void splashf(long delay, const char* msg, ...) |
63 | { | 80 | { |
81 | static char buf[512]; | ||
82 | |||
83 | va_list ap; | ||
84 | va_start(ap, msg); | ||
85 | int len = vsnprintf(buf, sizeof(buf), msg, ap); | ||
86 | va_end(ap); | ||
87 | |||
88 | if(len < 0) | ||
89 | return; | ||
90 | |||
91 | int xpos, ypos; | ||
92 | int width, height; | ||
93 | get_splash_size(buf, &width, &height); | ||
94 | |||
95 | width *= SYSFONT_WIDTH; | ||
96 | height *= SYSFONT_HEIGHT; | ||
97 | xpos = (LCD_WIDTH - width) / 2; | ||
98 | ypos = (LCD_HEIGHT - height) / 2; | ||
99 | |||
100 | const int padding = 10; | ||
64 | clearscreen(); | 101 | clearscreen(); |
65 | putcenter_line(0, msg); | 102 | lcd_drawrect(xpos-padding, ypos-padding, |
66 | if(msg2) | 103 | width+2*padding, height+2*padding); |
67 | putcenter_line(1, msg2); | 104 | |
105 | char* str = buf; | ||
106 | do { | ||
107 | char* np = strchr(str, '\n'); | ||
108 | if(np) { | ||
109 | *np = '\0'; | ||
110 | np++; | ||
111 | } | ||
112 | |||
113 | lcd_putsxyf(xpos, ypos, "%s", str); | ||
114 | ypos += SYSFONT_HEIGHT; | ||
115 | str = np; | ||
116 | } while(str); | ||
117 | |||
68 | lcd_update(); | 118 | lcd_update(); |
69 | sleep(delay); | 119 | sleep(delay); |
70 | } | 120 | } |
71 | 121 | ||
72 | void splash(long delay, const char* msg) | ||
73 | { | ||
74 | splash2(delay, msg, NULL); | ||
75 | } | ||
76 | |||
77 | int get_button(int timeout) | 122 | int get_button(int timeout) |
78 | { | 123 | { |
79 | int btn = button_get_w_tmo(timeout); | 124 | int btn = button_get_w_tmo(timeout); |
diff --git a/bootloader/x1000/install.c b/bootloader/x1000/install.c index e4af66443b..18b853df7c 100644 --- a/bootloader/x1000/install.c +++ b/bootloader/x1000/install.c | |||
@@ -34,7 +34,7 @@ enum { | |||
34 | static void bootloader_action(int which) | 34 | static void bootloader_action(int which) |
35 | { | 35 | { |
36 | if(check_disk(true) != DISK_PRESENT) { | 36 | if(check_disk(true) != DISK_PRESENT) { |
37 | splash2(5*HZ, "Install aborted", "Cannot access SD card"); | 37 | splashf(5*HZ, "Install aborted\nCannot access SD card"); |
38 | return; | 38 | return; |
39 | } | 39 | } |
40 | 40 | ||
@@ -46,7 +46,7 @@ static void bootloader_action(int which) | |||
46 | default: return; /* can't happen */ | 46 | default: return; /* can't happen */ |
47 | } | 47 | } |
48 | 48 | ||
49 | splash(0, msg); | 49 | splashf(0, msg); |
50 | 50 | ||
51 | int rc; | 51 | int rc; |
52 | switch(which) { | 52 | switch(which) { |
@@ -60,7 +60,7 @@ static void bootloader_action(int which) | |||
60 | snprintf(buf, sizeof(buf), "%s (%d)", installer_strerror(rc), rc); | 60 | snprintf(buf, sizeof(buf), "%s (%d)", installer_strerror(rc), rc); |
61 | const char* msg1 = rc == 0 ? "Success" : buf; | 61 | const char* msg1 = rc == 0 ? "Success" : buf; |
62 | const char* msg2 = "Press " BL_QUIT_NAME " to continue"; | 62 | const char* msg2 = "Press " BL_QUIT_NAME " to continue"; |
63 | splash2(0, msg1, msg2); | 63 | splashf(0, "%s\n%s", msg1, msg2); |
64 | 64 | ||
65 | while(get_button(TIMEOUT_BLOCK) != BL_QUIT); | 65 | while(get_button(TIMEOUT_BLOCK) != BL_QUIT); |
66 | } | 66 | } |
diff --git a/bootloader/x1000/main.c b/bootloader/x1000/main.c index c507b1d2c9..0909a4c72a 100644 --- a/bootloader/x1000/main.c +++ b/bootloader/x1000/main.c | |||
@@ -44,7 +44,7 @@ void main(void) | |||
44 | enable_irq(); | 44 | enable_irq(); |
45 | 45 | ||
46 | if(storage_init() < 0) { | 46 | if(storage_init() < 0) { |
47 | splash(5*HZ, "storage_init() failed"); | 47 | splashf(5*HZ, "storage_init() failed"); |
48 | power_off(); | 48 | power_off(); |
49 | } | 49 | } |
50 | 50 | ||
diff --git a/bootloader/x1000/utils.c b/bootloader/x1000/utils.c index faeab40739..681ddbbd62 100644 --- a/bootloader/x1000/utils.c +++ b/bootloader/x1000/utils.c | |||
@@ -46,13 +46,13 @@ int check_disk(bool wait) | |||
46 | return DISK_ABSENT; | 46 | return DISK_ABSENT; |
47 | 47 | ||
48 | while(!storage_present(IF_MD(0))) { | 48 | while(!storage_present(IF_MD(0))) { |
49 | splash2(0, "Insert SD card", "Press " BL_QUIT_NAME " to cancel"); | 49 | splashf(0, "Insert SD card\nPress " BL_QUIT_NAME " to cancel"); |
50 | if(get_button(HZ/4) == BL_QUIT) | 50 | if(get_button(HZ/4) == BL_QUIT) |
51 | return DISK_CANCELED; | 51 | return DISK_CANCELED; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* a lie intended to give time for mounting the disk in the background */ | 54 | /* a lie intended to give time for mounting the disk in the background */ |
55 | splash(HZ, "Scanning disk"); | 55 | splashf(HZ, "Scanning disk"); |
56 | 56 | ||
57 | return DISK_PRESENT; | 57 | return DISK_PRESENT; |
58 | } | 58 | } |
@@ -60,19 +60,19 @@ int check_disk(bool wait) | |||
60 | void usb_mode(void) | 60 | void usb_mode(void) |
61 | { | 61 | { |
62 | if(!is_usb_connected) | 62 | if(!is_usb_connected) |
63 | splash2(0, "Waiting for USB", "Press " BL_QUIT_NAME " to cancel"); | 63 | splashf(0, "Waiting for USB\nPress " BL_QUIT_NAME " to cancel"); |
64 | 64 | ||
65 | while(!is_usb_connected) | 65 | while(!is_usb_connected) |
66 | if(get_button(TIMEOUT_BLOCK) == BL_QUIT) | 66 | if(get_button(TIMEOUT_BLOCK) == BL_QUIT) |
67 | return; | 67 | return; |
68 | 68 | ||
69 | splash(0, "USB mode"); | 69 | splashf(0, "USB mode"); |
70 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | 70 | usb_acknowledge(SYS_USB_CONNECTED_ACK); |
71 | 71 | ||
72 | while(is_usb_connected) | 72 | while(is_usb_connected) |
73 | get_button(TIMEOUT_BLOCK); | 73 | get_button(TIMEOUT_BLOCK); |
74 | 74 | ||
75 | splash(3*HZ, "USB disconnected"); | 75 | splashf(3*HZ, "USB disconnected"); |
76 | } | 76 | } |
77 | 77 | ||
78 | int load_rockbox(const char* filename, size_t* sizep) | 78 | int load_rockbox(const char* filename, size_t* sizep) |
@@ -82,7 +82,7 @@ int load_rockbox(const char* filename, size_t* sizep) | |||
82 | 82 | ||
83 | int handle = core_alloc_maximum("rockbox", sizep, &buflib_ops_locked); | 83 | int handle = core_alloc_maximum("rockbox", sizep, &buflib_ops_locked); |
84 | if(handle < 0) { | 84 | if(handle < 0) { |
85 | splash(5*HZ, "Out of memory"); | 85 | splashf(5*HZ, "Out of memory"); |
86 | return -2; | 86 | return -2; |
87 | } | 87 | } |
88 | 88 | ||
@@ -90,7 +90,7 @@ int load_rockbox(const char* filename, size_t* sizep) | |||
90 | int rc = load_firmware(loadbuffer, filename, *sizep); | 90 | int rc = load_firmware(loadbuffer, filename, *sizep); |
91 | if(rc <= 0) { | 91 | if(rc <= 0) { |
92 | core_free(handle); | 92 | core_free(handle); |
93 | splash2(5*HZ, "Error loading Rockbox", loader_strerror(rc)); | 93 | splashf(5*HZ, "Error loading Rockbox\n%s", loader_strerror(rc)); |
94 | return -3; | 94 | return -3; |
95 | } | 95 | } |
96 | 96 | ||
@@ -108,13 +108,13 @@ int load_uimage_file(const char* filename, | |||
108 | 108 | ||
109 | int fd = open(filename, O_RDONLY); | 109 | int fd = open(filename, O_RDONLY); |
110 | if(fd < 0) { | 110 | if(fd < 0) { |
111 | splash2(5*HZ, "Can't open file", filename); | 111 | splashf(5*HZ, "Can't open file\n%s", filename); |
112 | return -2; | 112 | return -2; |
113 | } | 113 | } |
114 | 114 | ||
115 | int handle = uimage_load(uh, sizep, uimage_fd_reader, (void*)(intptr_t)fd); | 115 | int handle = uimage_load(uh, sizep, uimage_fd_reader, (void*)(intptr_t)fd); |
116 | if(handle <= 0) { | 116 | if(handle <= 0) { |
117 | splash2(5*HZ, "Cannot load uImage", filename); | 117 | splashf(5*HZ, "Cannot load uImage\n%s", filename); |
118 | return -3; | 118 | return -3; |
119 | } | 119 | } |
120 | 120 | ||
@@ -155,7 +155,7 @@ int load_uimage_flash(uint32_t addr, uint32_t length, | |||
155 | 155 | ||
156 | nand_lock(n.ndrv); | 156 | nand_lock(n.ndrv); |
157 | if(nand_open(n.ndrv) != NAND_SUCCESS) { | 157 | if(nand_open(n.ndrv) != NAND_SUCCESS) { |
158 | splash(5*HZ, "NAND open failed"); | 158 | splashf(5*HZ, "NAND open failed"); |
159 | nand_unlock(n.ndrv); | 159 | nand_unlock(n.ndrv); |
160 | return -1; | 160 | return -1; |
161 | } | 161 | } |
@@ -166,7 +166,7 @@ int load_uimage_flash(uint32_t addr, uint32_t length, | |||
166 | nand_unlock(n.ndrv); | 166 | nand_unlock(n.ndrv); |
167 | 167 | ||
168 | if(handle <= 0) { | 168 | if(handle <= 0) { |
169 | splash(5*HZ, "uImage load failed"); | 169 | splashf(5*HZ, "uImage load failed"); |
170 | return -2; | 170 | return -2; |
171 | } | 171 | } |
172 | 172 | ||
diff --git a/bootloader/x1000/x1000bootloader.h b/bootloader/x1000/x1000bootloader.h index b0d8d378f4..0309421ced 100644 --- a/bootloader/x1000/x1000bootloader.h +++ b/bootloader/x1000/x1000bootloader.h | |||
@@ -118,9 +118,7 @@ struct bl_list { | |||
118 | void clearscreen(void); | 118 | void clearscreen(void); |
119 | void putversion(void); | 119 | void putversion(void); |
120 | void putcenter_y(int y, const char* msg); | 120 | void putcenter_y(int y, const char* msg); |
121 | void putcenter_line(int line, const char* msg); | 121 | void splashf(long delay, const char* msg, ...); |
122 | void splash2(long delay, const char* msg, const char* msg2); | ||
123 | void splash(long delay, const char* msg); | ||
124 | int get_button(int timeout); | 122 | int get_button(int timeout); |
125 | void init_lcd(void); | 123 | void init_lcd(void); |
126 | 124 | ||