OpenCores
URL https://opencores.org/ocsvn/s6soc/s6soc/trunk

Subversion Repositories s6soc

[/] [s6soc/] [trunk/] [sw/] [zipos/] [syspipe.c] - Diff between revs 27 and 45

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 27 Rev 45
Line 44... Line 44...
#include "board.h"
#include "board.h"
#include "taskp.h"
#include "taskp.h"
#include "syspipe.h"
#include "syspipe.h"
#include "zipsys.h"
#include "zipsys.h"
#include "ktraps.h"
#include "ktraps.h"
 
#include "string.h"
 
 
#ifndef NULL
#ifndef NULL
#define NULL    (void *)0
#define NULL    (void *)0
#endif
#endif
 
 
void    kpush_syspipe(SYSPIPE *pipe, int val) {
void    kpush_syspipe(SYSPIPE *pipe, char val) {
        int     tst = (pipe->m_head+1)&pipe->m_mask;
        int     tst = (pipe->m_head+1)&pipe->m_mask;
        if (tst != pipe->m_tail) {
        if (tst != pipe->m_tail) {
                pipe->m_buf[pipe->m_head] = val;
                pipe->m_buf[pipe->m_head] = val;
                pipe->m_head = tst;             // Increment the head pointer
                pipe->m_head = tst;             // Increment the head pointer
                if ((pipe->m_rdtask)&&(pipe->m_rdtask != INTERRUPT_READ_TASK))
                if ((pipe->m_rdtask)&&(pipe->m_rdtask != INTERRUPT_READ_TASK))
                        pipe->m_rdtask->state = SCHED_READY;
                        pipe->m_rdtask->state = SCHED_READY;
        } else pipe->m_error = 1;
        } else pipe->m_error = 1;
}
}
 
 
extern  void    pipe_panic(SYSPIPE *p);
extern  void    pipe_panic(SYSPIPE *p);
int     kpop_syspipe(SYSPIPE *pipe, int *vl) {
/*
 
 * kpop_syspipe
 
 *
 
 * Called from an interrupt context to pop one byte off of the syspipe.
 
 */
 
int     kpop_syspipe(SYSPIPE *pipe, char *vl) {
        if (pipe->m_head != pipe->m_tail) {
        if (pipe->m_head != pipe->m_tail) {
 
                // The head will *only* equal the tail if the pipe is empty.
 
                // We come in here, therefore, if the pipe is non-empty
                *vl = pipe->m_buf[pipe->m_tail];
                *vl = pipe->m_buf[pipe->m_tail];
                pipe->m_tail = (pipe->m_tail+1)&pipe->m_mask;
                pipe->m_tail = (pipe->m_tail+1)&pipe->m_mask;
                if (pipe->m_wrtask)
                if (pipe->m_wrtask)
                        pipe->m_wrtask->state = SCHED_READY;
                        pipe->m_wrtask->state = SCHED_READY;
                return 0;
                return 0;
        }
        }
        return 1; // Error condition
        return 1; // Error condition
}
}
 
 
/* Returns how many values are in the pipe
/*
 
 * kpop_short_syspipe
 
 *
 
 * This is identical to kpop_syspipe, save that we are pulling a short value
 
 * off of the syspipe (i.e. a pair of chars), not just a single char.
 */
 */
/* Of course ... if it's not used, why include it?
int     kpop_short_syspipe(SYSPIPE *pipe, unsigned short *vl) {
 
        if (pipe->m_head == pipe->m_tail)
 
                return 1; // Error condition
 
 
 
        unsigned short *sptr = (unsigned short *)&pipe->m_buf[pipe->m_tail];
 
        // sv = pipe->m_buf[pipe->m_tail];
 
        *vl = *sptr;;
 
        pipe->m_tail = (pipe->m_tail+2)&pipe->m_mask;
 
        if (pipe->m_wrtask)
 
                pipe->m_wrtask->state = SCHED_READY;
 
        return 0;
 
}
 
 
 
/*
int     len_syspipe(SYSPIPE *p) {
int     len_syspipe(SYSPIPE *p) {
        return (p->m_head-p->m_tail) & p->m_mask;
        return (p->m_head-p->m_tail) & p->m_mask;
} */
} */
 
 
/* Returns how many empty spaces are in the pipe
/* Returns how many empty spaces are in the pipe
 */
 */
int     num_avail_syspipe(SYSPIPE *p) {
int     num_avail_syspipe(SYSPIPE *p) {
        // if (head+1 == tail)  PIPE is full
        // if (head+1 == tail)  PIPE is full
        //      (mask+tail-tail+1)=mask+1 &mask = 0
        //      (mask+tail-tail+1)=mask+1 &mask = 0
Line 94... Line 120...
 
 
// This will be called from a user context.
// This will be called from a user context.
// Another task may write to the pipe during this call.  If the pipe becomes
// Another task may write to the pipe during this call.  If the pipe becomes
// full, that task will block.
// full, that task will block.
//
//
static int      uread_syspipe(TASKP tsk __attribute__((__unused__)), SYSPIPE *p, int *dst, int len) {
static int uread_syspipe(TASKP tsk __attribute__((__unused__)),
 
                SYSPIPE *p, char *dst, int len) {
        int nleft= len, h;
        int nleft= len, h;
        if (len == 0) {
        if (len == 0) {
                // We'll only get here if we were released from within a 
                // We'll only get here if we were released from within a 
                // writing task.
                // writing task.
                return p->m_nread;
                return p->m_nread;
Line 114... Line 141...
                        // The buffer wraps around the end.  Thus, we first
                        // The buffer wraps around the end.  Thus, we first
                        // read anything between the tail pointer and the end
                        // read anything between the tail pointer and the end
                        int ln1 = p->m_mask+1 - p->m_tail; // Navail to be read
                        int ln1 = p->m_mask+1 - p->m_tail; // Navail to be read
                        ln1 = (ln1 > nleft) ? nleft : ln1;
                        ln1 = (ln1 > nleft) ? nleft : ln1;
                        if (ln1 > 0) {
                        if (ln1 > 0) {
                                register int *src = &p->m_buf[p->m_tail];
                                memcpy(dst, &p->m_buf[p->m_tail], ln1);
                                for(int i=0; i<ln1; i++)
                                dst += ln1;
                                        *dst++ = *src++;
 
 
 
                                p->m_nread += ln1;
                                p->m_nread += ln1;
                                nleft -= ln1;
                                nleft -= ln1;
 
 
                                int nt = p->m_tail+ln1;
                                int nt = p->m_tail+ln1;
Line 142... Line 168...
                        // Still need to do more, wrap around our buffer and
                        // Still need to do more, wrap around our buffer and
                        // restart
                        // restart
                        int ln1 = h - p->m_tail;
                        int ln1 = h - p->m_tail;
                        ln1 = (ln1 < nleft) ? ln1 : nleft;
                        ln1 = (ln1 < nleft) ? ln1 : nleft;
 
 
                        int *src = &p->m_buf[p->m_tail];
                        memcpy(dst, &p->m_buf[p->m_tail], ln1);
                        for(int i=0; i<ln1; i++)
                        dst += ln1;
                                *dst++ = *src++;
 
 
 
                        p->m_nread += ln1;
                        p->m_nread += ln1;
                        nleft -= ln1;
                        nleft -= ln1;
                        int nt = p->m_tail+ln1; // nt = new tail value
                        int nt = p->m_tail+ln1; // nt = new tail value
                        if ((unsigned)nt > p->m_mask)
                        if ((unsigned)nt > p->m_mask)
Line 170... Line 195...
                // we are active, then it is blocked and waiting for us to
                // we are active, then it is blocked and waiting for us to
                // complete.  Note also that this is treated as a volatile
                // complete.  Note also that this is treated as a volatile
                // pointer.  It can change from one time through our loop
                // pointer.  It can change from one time through our loop
                // to the next.
                // to the next.
                if (((volatile SYSPIPE *)p)->m_wrtask) {
                if (((volatile SYSPIPE *)p)->m_wrtask) {
                        int     *src, ln;
                        int     ln;
 
                        char    *src;
 
 
                        // If the head changed before the write task blocked,
                        // If the head changed before the write task blocked,
                        // then go around again and copy some more before
                        // then go around again and copy some more before
                        // getting started
                        // getting started
                        //
                        //
Line 187... Line 213...
                        //      continue;
                        //      continue;
 
 
                        ln = nleft;
                        ln = nleft;
                        if (p->m_wrtask->context[4] < nleft)
                        if (p->m_wrtask->context[4] < nleft)
                                ln = p->m_wrtask->context[4];
                                ln = p->m_wrtask->context[4];
                        src = (int *)p->m_wrtask->context[3];
                        src = (char *)p->m_wrtask->context[3];
 
                        memcpy(dst, src, ln);
                        for(int i=0; i<ln; i++)
                        dst += ln;
                                *dst++ = *src++;
                        src += ln;
 
 
                        p->m_nwritten += ln;
                        p->m_nwritten += ln;
                        p->m_nread    += ln;
                        p->m_nread    += ln;
 
 
                        nleft -= ln;
                        nleft -= ln;
Line 242... Line 268...
        //
        //
        return len;
        return len;
}
}
 
 
static int      uwrite_syspipe(TASKP tsk __attribute__((__unused__)),
static int      uwrite_syspipe(TASKP tsk __attribute__((__unused__)),
                SYSPIPE *p, int *src, int len) {
                SYSPIPE *p, char *src, int len) {
        int nleft = len;
        int nleft = len;
 
 
        // The kernel guarantees, before we come into here, that we have a 
        // The kernel guarantees, before we come into here, that we have a 
        // valid write request.  
        // valid write request.  
        do {
        do {
Line 261... Line 287...
                        // We need to copy everything to the buffer
                        // We need to copy everything to the buffer
                } else if (rdtask) {
                } else if (rdtask) {
                        int ln = nleft;
                        int ln = nleft;
                        if (ln > p->m_rdtask->context[4])
                        if (ln > p->m_rdtask->context[4])
                                ln = p->m_rdtask->context[4];
                                ln = p->m_rdtask->context[4];
                        int *dst = (int *)p->m_rdtask->context[3];
                        memcpy((char *)p->m_rdtask->context[3], src, ln);
                        for(int i=0; i<ln; i++)
                        src += ln;
                                *dst++ = *src++;
 
                        p->m_nread += ln;
                        p->m_nread += ln;
                        p->m_rdtask->context[3]+= ln;
                        p->m_rdtask->context[3]+= ln;
                        p->m_rdtask->context[4]-= ln;
                        p->m_rdtask->context[4]-= ln;
                        nleft -= ln;
                        nleft -= ln;
                        p->m_nwritten += ln;
                        p->m_nwritten += ln;
Line 316... Line 341...
                        { // Write into the first half of the pipe
                        { // Write into the first half of the pipe
                        // Be careful not to change head until all is written
                        // Be careful not to change head until all is written
                        // so that it remains consistent under interrupt
                        // so that it remains consistent under interrupt
                        // conditions.
                        // conditions.
                                int ln = p->m_mask+1-p->m_head;
                                int ln = p->m_mask+1-p->m_head;
                                int *dst = &p->m_buf[p->m_head];
 
                                if (ln > nleft) ln = nleft;
                                if (ln > nleft) ln = nleft;
                                if (ln > navail) ln = navail;
                                if (ln > navail) ln = navail;
 
 
                                for(int i=0; i<ln; i++)
                                memcpy((void *)&p->m_buf[p->m_head], src, ln);
                                        *dst++ = *src++;
                                src += ln;
 
 
                                p->m_head = (p->m_head+ln)&p->m_mask;
                                p->m_head = (p->m_head+ln)&p->m_mask;
                                nleft -= ln;
                                nleft -= ln;
                                p->m_nwritten += ln;
                                p->m_nwritten += ln;
                                navail -= ln;
                                navail -= ln;
                        }
                        }
 
 
                        /*
 
                        // Write into the rest of the pipe
 
                        if ((0 == p->m_head)&&(nleft>0)&&(navail>0)) {
 
                                int ln = navail;
 
                                if (nleft < ln)
 
                                        ln = nleft;
 
                                int *dst = &p->m_buf[p->m_head];
 
 
 
                                for(int i=0; i<ln; i++)
 
                                        *dst++ = *src++;
 
 
 
                                p->m_head += ln;
 
                                p->m_nwritten += ln;
 
                                nleft -= ln;
 
                        }*/
 
                }
                }
 
 
                if ((nleft > 0)&&(navail == 0)) {
                if ((nleft > 0)&&(navail == 0)) {
                        if (rdtask == INTERRUPT_READ_TASK) {
                        if (rdtask == INTERRUPT_READ_TASK) {
                                DISABLE_INTS();
                                DISABLE_INTS();
Line 369... Line 377...
        p->m_wrtask = 0;
        p->m_wrtask = 0;
        return nw;
        return nw;
}
}
 
 
// This will be called from a kernel (interrupt) context
// This will be called from a kernel (interrupt) context
void    kread_syspipe(TASKP tsk, int dev, int *dst, int len) {
void    kread_syspipe(TASKP tsk, int dev, char *dst, int len) {
        SYSPIPE *p = (SYSPIPE *)dev;
        SYSPIPE *p = (SYSPIPE *)dev;
        if (p->m_rdtask != NULL) {
        if (p->m_rdtask != NULL) {
                // If the pipe already has a read task, then we fail
                // If the pipe already has a read task, then we fail
                tsk->context[1] = -EBUSY;
                tsk->context[1] = -EBUSY;
                zip_halt();
                zip_halt();
Line 413... Line 421...
                // On return, this will bring us back to user space, inside our
                // On return, this will bring us back to user space, inside our
                // user space version of the read system call
                // user space version of the read system call
        }
        }
}
}
 
 
void    kwrite_syspipe(TASKP tsk, int dev, int *src, int len) {
void    kwrite_syspipe(TASKP tsk, int dev, char *src, int len) {
        SYSPIPE *p = (SYSPIPE *)dev;
        SYSPIPE *p = (SYSPIPE *)dev;
        if (p->m_wrtask != NULL) {
        if (p->m_wrtask != NULL) {
                // If the pipe already has a write task, then we fail
                // If the pipe already has a write task, then we fail
                tsk->context[1] = -EBUSY;
                tsk->context[1] = -EBUSY;
        } else if (len <= 0) {
        } else if (len <= 0) {

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.