test_queue.c /*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2007 Michael Sevakis * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "oldmenuapi.h" PLUGIN_HEADER PLUGIN_IRAM_DECLARE static struct plugin_api *rb NOCACHEBSS_ATTR; static struct event_queue cop_queue NOCACHEBSS_ATTR; static struct queue_sender_list cop_queue_senders NOCACHEBSS_ATTR; static int cop_thread_stack[2*DEFAULT_STACK_SIZE/sizeof(int)]; #ifdef TOSHIBA_GIGABEAT_F #define invalidate_icache() #define flush_icache() #endif #if CONFIG_KEYPAD == IRIVER_H100_PAD #define TEST_QUEUE_QUIT BUTTON_OFF #elif CONFIG_KEYPAD == SANSA_E200_PAD #define TEST_QUEUE_QUIT BUTTON_POWER #elif CONFIG_KEYPAD == GIGABEAT_PAD #define TEST_QUEUE_QUIT BUTTON_POWER #else #error Unsupported Keypad #endif void cop_thread(void) { struct queue_event ev; int last_i = 0; while (1) { rb->queue_wait_w_tmo(&cop_queue, &ev, 3600*HZ); switch (ev.id) { case 0: /* each data should be one greater than the last */ if (ev.data != last_i + 1) rb->queue_reply(&cop_queue, -1); // else // rb->splash(0, "%ld", ev.data); last_i = ev.data; break; case 777: /* commanded to exit - reply explicitly since we won't wait here again */ rb->queue_reply(&cop_queue, 0); invalidate_icache(); return; default: rb->queue_reply(&cop_queue, -2); } } } enum plugin_status plugin_start(struct plugin_api *api, void *parameter) { int i, ret = 0; PLUGIN_IRAM_INIT(api); rb = api; i = 0; rb->queue_init(&cop_queue, false); rb->queue_enable_queue_send(&cop_queue, &cop_queue_senders); flush_icache(); rb->create_thread(cop_thread, cop_thread_stack, sizeof(cop_thread_stack), 0, "cop_thread", PRIORITY_SYSTEM IF_COP(, CPU)); rb->lcd_setfont(FONT_SYSFIXED); rb->lcd_puts(0, 0, "Test running..."); rb->lcd_update(); i = 0; long tick = *rb->current_tick + 10*HZ; int loops = 0; /* loop around sending last data+1 */ while (TIME_BEFORE(*rb->current_tick, tick)) //rb->button_get(false) != TEST_QUEUE_QUIT) { ret = rb->queue_send(&cop_queue, 0, ++i); if (ret == -1) { rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Data miss"); break; } else if (ret == -2) { rb->lcd_clear_display(); rb->lcd_puts(0, 0, "Unexpected message"); break; } loops++; } rb->splash(HZ*3, "%d.%d", loops/10, loops%10); if (ret < 0) { while (rb->button_get(true) == BUTTON_NONE); } /* tell cop thread to exit */ rb->queue_send(&cop_queue, 777, 0); /* give it time to leave plugin code */ rb->sleep(HZ/10); invalidate_icache(); return PLUGIN_OK; (void)parameter; } test_cache.c /*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2007 Michael Sevakis * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "oldmenuapi.h" PLUGIN_HEADER PLUGIN_IRAM_DECLARE static struct plugin_api *rb NOCACHEBSS_ATTR; static struct event_queue cop_queue NOCACHEBSS_ATTR; static struct queue_sender_list cop_queue_senders NOCACHEBSS_ATTR; static int cop_thread_stack[DEFAULT_STACK_SIZE/sizeof(int)]; static uint8_t cached_buf[16]; static uint8_t uncached_buf[16] NOCACHEBSS_ATTR; static uint8_t cop_buf[16] NOCACHEBSS_ATTR; #ifdef TOSHIBA_GIGABEAT_F #define invalidate_icache() #define flush_icache() #endif void cop_thread(void) { int i; struct queue_event ev; while (1) { invalidate_icache(); rb->queue_wait_w_tmo(&cop_queue, &ev, 3600*HZ); switch (ev.id) { case 0: /* avoid memcpy/memcmp to help localize code execution */ for (i = 0; i < 16; i++) { if (cached_buf[i] != uncached_buf[i]) { for (i = 0; i < 16; i++) { /* copy what COP sees to an uncacheable buffer */ cop_buf[i] = cached_buf[i]; } /* return failure */ rb->queue_reply(&cop_queue, -1); break; } } break; case 666: /* commanded to exit - reply explicitly since we won't wait here again */ rb->queue_reply(&cop_queue, 0); flush_icache(); return; } } } enum plugin_status plugin_start(struct plugin_api *api, void *parameter) { int ret; unsigned char buf[64]; unsigned int rand; unsigned int test_num = 0; PLUGIN_IRAM_INIT(api); rb = api; rand = *rb->current_tick; ret = 0; rb->queue_init(&cop_queue, false); rb->queue_enable_queue_send(&cop_queue, &cop_queue_senders); flush_icache(); rb->create_thread(cop_thread, cop_thread_stack, sizeof(cop_thread_stack), 0, "cop_thread", PRIORITY_SYSTEM IF_COP(, COP)); rb->lcd_setfont(FONT_SYSFIXED); rb->lcd_puts(0, 0, "Test running..."); rb->lcd_puts(0, 1, "Will dump upon byte mismatch."); rb->lcd_update(); while (rb->button_get(false) == BUTTON_NONE) { int i; test_num++; for (i = 0; i < 16; i++) { unsigned val; rand = rand*0x0019660dL + 0x3c6ef35fL; val = rand & 0xff; cached_buf[i] = val; uncached_buf[i] = val; } //rb->lcd_update(); invalidate_icache(); ret = rb->queue_send(&cop_queue, 0, 0); if (ret < 0) break; rb->yield(); } if (ret < 0) { int i, x, y = 0; rb->lcd_clear_display(); rb->snprintf(buf, 64, "Test #%u failed:", test_num); rb->lcd_puts(0, y++, buf); rb->lcd_puts(0, y, "cached_buf"); rb->lcd_puts(0, y+3, "uncached_buf"); rb->lcd_puts(0, y+6, "cop_buf"); for (i = 0, x = 0, y = 2; i < 16; i++, x += 3) { if (i % 8 == 0) x = 0, y++; /* show bytes in the shared, cached buffer */ rb->snprintf(buf, 64, "%02X ", cached_buf[i]); rb->lcd_puts(x, y+0, buf); /* show bytes in the shared, uncached buffer */ rb->snprintf(buf, 64, "%02X ", uncached_buf[i]); rb->lcd_puts(x, y+3, buf); /* show bytes that cop saw in the shared, cached buffer */ rb->snprintf(buf, 64, "%02X ", cop_buf[i]); rb->lcd_puts(x, y+6, buf); } rb->lcd_update(); while (rb->button_get(true) == BUTTON_NONE); } /* tell cop thread to exit */ rb->queue_send(&cop_queue, 666, 0); /* give it time to leave plugin code */ rb->sleep(HZ/10); flush_icache(); return PLUGIN_OK; (void)parameter; }