diff options
Diffstat (limited to 'firmware/target/hosted/system-hosted.c')
-rw-r--r-- | firmware/target/hosted/system-hosted.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/firmware/target/hosted/system-hosted.c b/firmware/target/hosted/system-hosted.c new file mode 100644 index 0000000000..7f0949daf2 --- /dev/null +++ b/firmware/target/hosted/system-hosted.c | |||
@@ -0,0 +1,184 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * | ||
9 | * Copyright (C) 2017 Marcin Bukat | ||
10 | * Copyright (C) 2016 Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include <unistd.h> | ||
22 | #include <signal.h> | ||
23 | #include <string.h> | ||
24 | #include <ucontext.h> | ||
25 | #include <backtrace.h> | ||
26 | |||
27 | #include "system.h" | ||
28 | #include "mv.h" | ||
29 | #include "font.h" | ||
30 | #include "power.h" | ||
31 | #include "button.h" | ||
32 | #include "backlight-target.h" | ||
33 | #include "lcd.h" | ||
34 | |||
35 | /* to make thread-internal.h happy */ | ||
36 | uintptr_t *stackbegin; | ||
37 | uintptr_t *stackend; | ||
38 | |||
39 | static void sig_handler(int sig, siginfo_t *siginfo, void *context) | ||
40 | { | ||
41 | /* safe guard variable - we call backtrace() only on first | ||
42 | * UIE call. This prevent endless loop if backtrace() touches | ||
43 | * memory regions which cause abort | ||
44 | */ | ||
45 | static bool triggered = false; | ||
46 | |||
47 | lcd_set_backdrop(NULL); | ||
48 | lcd_set_drawmode(DRMODE_SOLID); | ||
49 | lcd_set_foreground(LCD_BLACK); | ||
50 | lcd_set_background(LCD_WHITE); | ||
51 | unsigned line = 0; | ||
52 | |||
53 | lcd_setfont(FONT_SYSFIXED); | ||
54 | lcd_set_viewport(NULL); | ||
55 | lcd_clear_display(); | ||
56 | |||
57 | /* get context info */ | ||
58 | ucontext_t *uc = (ucontext_t *)context; | ||
59 | unsigned long pc = uc->uc_mcontext.pc; | ||
60 | unsigned long sp = uc->uc_mcontext.gregs[29]; | ||
61 | |||
62 | lcd_putsf(0, line++, "%s at %08x", strsignal(sig), pc); | ||
63 | |||
64 | if(sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || sig == SIGBUS || sig == SIGTRAP) | ||
65 | lcd_putsf(0, line++, "address 0x%08x", siginfo->si_addr); | ||
66 | |||
67 | if(!triggered) | ||
68 | { | ||
69 | triggered = true; | ||
70 | rb_backtrace(pc, sp, &line); | ||
71 | } | ||
72 | |||
73 | #ifdef ROCKBOX_HAS_LOGF | ||
74 | lcd_putsf(0, line++, "logf:"); | ||
75 | logf_panic_dump(&line); | ||
76 | #endif | ||
77 | |||
78 | lcd_update(); | ||
79 | |||
80 | system_exception_wait(); /* If this returns, try to reboot */ | ||
81 | system_reboot(); | ||
82 | while (1); /* halt */ | ||
83 | } | ||
84 | |||
85 | void power_off(void) | ||
86 | { | ||
87 | system("/sbin/poweroff"); | ||
88 | } | ||
89 | |||
90 | void system_init(void) | ||
91 | { | ||
92 | int *s; | ||
93 | /* fake stack, to make thread-internal.h happy */ | ||
94 | stackbegin = stackend = (uintptr_t*)&s; | ||
95 | /* catch some signals for easier debugging */ | ||
96 | struct sigaction sa; | ||
97 | sigfillset(&sa.sa_mask); | ||
98 | sa.sa_flags = SA_SIGINFO; | ||
99 | sa.sa_sigaction = &sig_handler; | ||
100 | sigaction(SIGILL, &sa, NULL); | ||
101 | sigaction(SIGABRT, &sa, NULL); | ||
102 | sigaction(SIGFPE, &sa, NULL); | ||
103 | sigaction(SIGSEGV, &sa, NULL); | ||
104 | sigaction(SIGPIPE, &sa, NULL); | ||
105 | sigaction(SIGTERM, &sa, NULL); | ||
106 | sigaction(SIGBUS, &sa, NULL); | ||
107 | sigaction(SIGTERM, &sa, NULL); | ||
108 | } | ||
109 | |||
110 | void system_reboot(void) | ||
111 | { | ||
112 | system("/sbin/reboot"); | ||
113 | } | ||
114 | |||
115 | void system_exception_wait(void) | ||
116 | { | ||
117 | backlight_hw_on(); | ||
118 | backlight_hw_brightness(DEFAULT_BRIGHTNESS_SETTING); | ||
119 | /* wait until button press and release */ | ||
120 | while(button_read_device() != 0) {} | ||
121 | while(button_read_device() == 0) {} | ||
122 | while(button_read_device() != 0) {} | ||
123 | while(button_read_device() == 0) {} | ||
124 | } | ||
125 | |||
126 | bool hostfs_removable(IF_MD_NONVOID(int drive)) | ||
127 | { | ||
128 | #ifdef HAVE_MULTIDRIVE | ||
129 | if (drive > 0) /* Active LOW */ | ||
130 | return true; | ||
131 | else | ||
132 | #endif | ||
133 | return false; /* internal: always present */ | ||
134 | } | ||
135 | |||
136 | bool hostfs_present(IF_MD_NONVOID(int drive)) | ||
137 | { | ||
138 | #ifdef HAVE_MULTIDRIVE | ||
139 | if (drive > 0) /* Active LOW */ | ||
140 | return true; //FIXME | ||
141 | else | ||
142 | #endif | ||
143 | return true; /* internal: always present */ | ||
144 | } | ||
145 | |||
146 | #ifdef HAVE_MULTIDRIVE | ||
147 | int volume_drive(int drive) | ||
148 | { | ||
149 | return drive; | ||
150 | } | ||
151 | #endif /* HAVE_MULTIDRIVE */ | ||
152 | |||
153 | #ifdef CONFIG_STORAGE_MULTI | ||
154 | int hostfs_driver_type(int drive) | ||
155 | { | ||
156 | return drive > 0 ? STORAGE_SD_NUM : STORAGE_HOSTFS_NUM; | ||
157 | } | ||
158 | #endif /* CONFIG_STORAGE_MULTI */ | ||
159 | |||
160 | int hostfs_init(void) | ||
161 | { | ||
162 | return 0; | ||
163 | } | ||
164 | |||
165 | int hostfs_flush(void) | ||
166 | { | ||
167 | sync(); | ||
168 | return 0; | ||
169 | } | ||
170 | |||
171 | #ifdef HAVE_HOTSWAP | ||
172 | bool volume_removable(int volume) | ||
173 | { | ||
174 | /* don't support more than one partition yet, so volume == drive */ | ||
175 | return hostfs_removable(volume); | ||
176 | } | ||
177 | |||
178 | bool volume_present(int volume) | ||
179 | { | ||
180 | /* don't support more than one partition yet, so volume == drive */ | ||
181 | return hostfs_present(volume); | ||
182 | } | ||
183 | #endif | ||
184 | |||