All pastes #669140 Raw Edit

cop queue/cache tester

public text v1 · immutable
#669140 ·published 2007-08-24 12:52 UTC
rendered paste body
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;
}