diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/config.h | 4 | ||||
-rw-r--r-- | firmware/export/kernel.h | 23 | ||||
-rw-r--r-- | firmware/kernel.c | 78 |
3 files changed, 105 insertions, 0 deletions
diff --git a/firmware/export/config.h b/firmware/export/config.h index 1a288dd590..cd98fc9dca 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -335,6 +335,10 @@ | |||
335 | #endif /* SIMULATOR */ | 335 | #endif /* SIMULATOR */ |
336 | #define HAVE_SEMAPHORE_OBJECTS | 336 | #define HAVE_SEMAPHORE_OBJECTS |
337 | #define HAVE_EVENT_OBJECTS | 337 | #define HAVE_EVENT_OBJECTS |
338 | |||
339 | #if defined (TOSHIBA_GIGABEAT_F) || defined (TOSHIBA_GIGABEAT_S) | ||
340 | #define HAVE_WAKEUP_OBJECTS | ||
341 | #endif | ||
338 | #endif | 342 | #endif |
339 | 343 | ||
340 | /* define for all cpus from SH family */ | 344 | /* define for all cpus from SH family */ |
diff --git a/firmware/export/kernel.h b/firmware/export/kernel.h index 78403c8b7d..337f249dfe 100644 --- a/firmware/export/kernel.h +++ b/firmware/export/kernel.h | |||
@@ -78,6 +78,11 @@ | |||
78 | 78 | ||
79 | #define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT) | 79 | #define IS_SYSEVENT(ev) ((ev & SYS_EVENT) == SYS_EVENT) |
80 | 80 | ||
81 | #ifndef TIMEOUT_BLOCK | ||
82 | #define TIMEOUT_BLOCK -1 | ||
83 | #define TIMEOUT_NOBLOCK 0 | ||
84 | #endif | ||
85 | |||
81 | struct queue_event | 86 | struct queue_event |
82 | { | 87 | { |
83 | long id; | 88 | long id; |
@@ -178,6 +183,17 @@ struct event | |||
178 | }; | 183 | }; |
179 | #endif | 184 | #endif |
180 | 185 | ||
186 | |||
187 | #ifdef HAVE_WAKEUP_OBJECTS | ||
188 | struct wakeup | ||
189 | { | ||
190 | struct thread_entry *queue; /* waiter list */ | ||
191 | unsigned char signalled; /* signalled status */ | ||
192 | IF_COP( struct corelock cl; ) /* multiprocessor sync */ | ||
193 | }; | ||
194 | #endif | ||
195 | |||
196 | |||
181 | /* global tick variable */ | 197 | /* global tick variable */ |
182 | #if defined(CPU_PP) && defined(BOOTLOADER) | 198 | #if defined(CPU_PP) && defined(BOOTLOADER) |
183 | /* We don't enable interrupts in the iPod bootloader, so we need to fake | 199 | /* We don't enable interrupts in the iPod bootloader, so we need to fake |
@@ -225,6 +241,7 @@ void timeout_cancel(struct timeout *tmo); | |||
225 | #define STATE_SIGNALED 1 | 241 | #define STATE_SIGNALED 1 |
226 | 242 | ||
227 | #define WAIT_TIMEDOUT (-1) | 243 | #define WAIT_TIMEDOUT (-1) |
244 | #define WAIT_FAILED 0 | ||
228 | #define WAIT_SUCCEEDED 1 | 245 | #define WAIT_SUCCEEDED 1 |
229 | 246 | ||
230 | extern void queue_init(struct event_queue *q, bool register_queue); | 247 | extern void queue_init(struct event_queue *q, bool register_queue); |
@@ -274,4 +291,10 @@ extern void event_wait(struct event *e, unsigned int for_state); | |||
274 | extern void event_set_state(struct event *e, unsigned int state); | 291 | extern void event_set_state(struct event *e, unsigned int state); |
275 | #endif /* HAVE_EVENT_OBJECTS */ | 292 | #endif /* HAVE_EVENT_OBJECTS */ |
276 | 293 | ||
294 | #ifdef HAVE_WAKEUP_OBJECTS | ||
295 | extern void wakeup_init(struct wakeup *w); | ||
296 | extern int wakeup_wait(struct wakeup *w, int timeout); | ||
297 | extern int wakeup_signal(struct wakeup *w); | ||
298 | #endif /* HAVE_WAKEUP_OBJECTS */ | ||
299 | |||
277 | #endif /* _KERNEL_H_ */ | 300 | #endif /* _KERNEL_H_ */ |
diff --git a/firmware/kernel.c b/firmware/kernel.c index 184d29fe93..439aea584a 100644 --- a/firmware/kernel.c +++ b/firmware/kernel.c | |||
@@ -1368,3 +1368,81 @@ void event_set_state(struct event *e, unsigned int state) | |||
1368 | #endif | 1368 | #endif |
1369 | } | 1369 | } |
1370 | #endif /* HAVE_EVENT_OBJECTS */ | 1370 | #endif /* HAVE_EVENT_OBJECTS */ |
1371 | |||
1372 | |||
1373 | #ifdef HAVE_WAKEUP_OBJECTS | ||
1374 | /**************************************************************************** | ||
1375 | * Lightweight IRQ-compatible wakeup object | ||
1376 | */ | ||
1377 | |||
1378 | /* Initialize the wakeup object */ | ||
1379 | void wakeup_init(struct wakeup *w) | ||
1380 | { | ||
1381 | w->queue = NULL; | ||
1382 | w->signalled = 0; | ||
1383 | IF_COP( corelock_init(&w->cl); ) | ||
1384 | } | ||
1385 | |||
1386 | /* Wait for a signal blocking indefinitely or for a specified period */ | ||
1387 | int wakeup_wait(struct wakeup *w, int timeout) | ||
1388 | { | ||
1389 | int ret = WAIT_SUCCEEDED; /* Presume success */ | ||
1390 | int oldlevel = disable_irq_save(); | ||
1391 | |||
1392 | corelock_lock(&w->cl); | ||
1393 | |||
1394 | if(w->signalled == 0 && timeout != TIMEOUT_NOBLOCK) | ||
1395 | { | ||
1396 | struct thread_entry * current = cores[CURRENT_CORE].running; | ||
1397 | |||
1398 | IF_COP( current->obj_cl = &w->cl; ) | ||
1399 | current->bqp = &w->queue; | ||
1400 | |||
1401 | if (timeout != TIMEOUT_BLOCK) | ||
1402 | block_thread_w_tmo(current, timeout); | ||
1403 | else | ||
1404 | block_thread(current); | ||
1405 | |||
1406 | corelock_unlock(&w->cl); | ||
1407 | switch_thread(); | ||
1408 | |||
1409 | oldlevel = disable_irq_save(); | ||
1410 | corelock_lock(&w->cl); | ||
1411 | } | ||
1412 | |||
1413 | if(w->signalled == 0) | ||
1414 | { | ||
1415 | /* Timed-out or failed */ | ||
1416 | ret = (timeout != TIMEOUT_BLOCK) ? WAIT_TIMEDOUT : WAIT_FAILED; | ||
1417 | } | ||
1418 | |||
1419 | w->signalled = 0; /* Reset */ | ||
1420 | |||
1421 | corelock_unlock(&w->cl); | ||
1422 | restore_irq(oldlevel); | ||
1423 | |||
1424 | return ret; | ||
1425 | } | ||
1426 | |||
1427 | /* Signal the thread waiting or leave the signal if the thread hasn't | ||
1428 | * waited yet. | ||
1429 | * | ||
1430 | * returns THREAD_NONE or THREAD_OK | ||
1431 | */ | ||
1432 | int wakeup_signal(struct wakeup *w) | ||
1433 | { | ||
1434 | int oldlevel = disable_irq_save(); | ||
1435 | int ret; | ||
1436 | |||
1437 | corelock_lock(&w->cl); | ||
1438 | |||
1439 | w->signalled = 1; | ||
1440 | ret = wakeup_thread(&w->queue); | ||
1441 | |||
1442 | corelock_unlock(&w->cl); | ||
1443 | restore_irq(oldlevel); | ||
1444 | |||
1445 | return ret; | ||
1446 | } | ||
1447 | #endif /* HAVE_WAKEUP_OBJECTS */ | ||
1448 | |||