view TaskManager/kernel/spe/SpeTask.cc @ 3:2356238ebea7

*** empty log message ***
author gongo
date Tue, 05 Feb 2008 20:22:50 +0900
parents
children 1eb4cd18abfd
line wrap: on
line source

#include <stdio.h>
#include "SpeTask.h"
#include "SpeTaskList.h"
#include "SpeNop2Ready.h"
#include "DmaManager.h"
#include "error.h"

int add(void*, void*);
int sub(void*, void*);
int mul(void*, void*);
int div(void*, void*);
int sum(void*, void*);
int sum2(void*, void*);

int (*func_list[16])(void* wbuf, void* rbuf) = {add, sub, mul, div, sum, sum2, 0};

int
add(void *wbuf, void *rbuf)
{
    int *ret = (int*)wbuf;
    int *data = (int*)rbuf;

    *ret = data[0] + data[1];

    return sizeof(int);
}

int
sub(void *wbuf, void *rbuf)
{
    int *ret = (int*)wbuf;
    int *data = (int*)rbuf;

    *ret = data[0]-data[1];

    return sizeof(int);
}

int
mul(void *wbuf, void *rbuf)
{
    int *ret = (int*)wbuf;
    int *data = (int*)rbuf;

    *ret = data[0]*data[1];

    return sizeof(int);
}

int
div(void *wbuf, void *rbuf)
{
    int *ret = (int*)wbuf;
    int *data = (int*)rbuf;

    *ret = data[0]/data[1];

    return sizeof(int);
}

int
sum(void *wbuf, void *rbuf)
{
    int *ret = (int*)wbuf;
    int *data = (int*)rbuf;
    int i;

    *ret = 0;

    printf("[FIFO] sum\n");

    for (i = 0; i < 16; i++) {
	*ret += data[i];
    }

    return sizeof(int);
}

int
sum2(void *wbuf, void *rbuf)
{
    int *ret = (int*)wbuf;
    int *data = (int*)rbuf;
    int i;

    *ret = 0;

    for (i = 0; i < 64; i++) {
	*ret += data[i*4];
    }

    return sizeof(int);
}


SpeTask::SpeTask(TaskListPtr _list, void *rbuf, void *wbuf, DmaManager* cn)
{
    list = _list;
    readbuf = rbuf;
    writebuf = wbuf;
    connector = cn;
}

void
SpeTask::read(void)
{    
    __debug("SpeTask::read()");

    task = &list->tasks[--list->length];
    connector->dma_load(readbuf, task->in_addr, task->in_size, DMA_READ);
}

void
SpeTask::exec(void)
{
    __debug("SpeTask::exec()");

    connector->dma_wait(DMA_READ);

#ifdef DEBUG
    printf("  task->command  = %d\n", task->command);
    printf("  task->in_size  = %d\n", task->in_size);
    printf("  task->in_addr  = 0x%x\n", task->in_addr);
    printf("  task->out_addr = 0x%x\n", task->out_addr);
    printf("  list->next   = 0x%x\n", (unsigned int)list->next);
    printf("  list->length = 0x%x\n", (unsigned int)list->length);
#endif

    task->in_size = func_list[task->command](writebuf, readbuf);
    connector->dma_store(writebuf, task->out_addr, task->in_size, DMA_WRITE);
}

void
SpeTask::write(void)
{
    __debug("SpeTask::write()");

    connector->dma_wait(DMA_WRITE);
    connector->mail_write((unsigned int)task->self);
}

SpeTaskBase*
SpeTask::next(SpeManager *m, SpeTaskBase *p)
{
    __debug("SpeTask::next()");

    delete p;
 
    // ここ直さねば。どうやって if 文消そう?
    // オブジェクト増やせばいいのかな
    if (list->length == 0) {
	if (list->next == 0) {
	    return new SpeNop2Ready(connector);
	} else {
	    return new SpeTaskList((unsigned int)list->next, m->get_curListBuf(), connector);
	}
    } else {
	return new SpeTask(list, m->get_curReadBuf(),
			   m->get_curWriteBuf(), connector);
    }
}