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

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [nanox/] [nxproto.c] - Blame information for rev 673

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3
 *
4
 * Nano-X Core Protocol Client Request Handling Routines
5
 */
6
#include <stdio.h>
7
#include <unistd.h>
8
#include <stdlib.h>
9
#include <assert.h>
10
#include <errno.h>
11
#include <string.h>
12
#include "serv.h"
13
#include "nxproto.h"
14
 
15
#define SZREQBUF        2048    /* initial request buffer size*/
16
 
17
#ifndef __ECOS
18
static REQBUF   reqbuf;         /* request buffer*/
19
extern int      nxSocket;
20
extern char *   nxSharedMem;
21
#endif
22
 
23
/* Allocate a request buffer of passed size and fill in header fields*/
24
void *
25
nxAllocReq(int type, long size, long extra)
26
{
27
        nxReq * req;
28
        long    aligned_len;
29
        ACCESS_PER_THREAD_DATA();
30
 
31
        /* variable size requests must be hand-padded*/
32
        if(extra)
33
                assert((size & (long)(ALIGNSZ-1)) == 0);
34
 
35
        /* calculate aligned length of request buffer*/
36
        aligned_len = (size + extra + (long)(ALIGNSZ-1)) & ~(long)(ALIGNSZ-1);
37
 
38
        /* verify we're not greater than max request size*/
39
        assert(aligned_len <= MAXREQUESTSZ);
40
 
41
        /* flush buffer if required, and allocate larger one if required*/
42
        if(reqbuf.bufptr + aligned_len >= reqbuf.bufmax)
43
                nxFlushReq(aligned_len,1);
44
 
45
        /* fill in request header*/
46
        req = (nxReq *)reqbuf.bufptr;
47
        req->reqType = (BYTE8)type;
48
        req->hilength = (BYTE8)((size + extra) >> 16);
49
        req->length = (UINT16)(size + extra);
50
        reqbuf.bufptr += aligned_len;
51
        return req;
52
}
53
 
54
static void nxAllocReqbuffer(long newsize)
55
{
56
        ACCESS_PER_THREAD_DATA();
57
 
58
        if(newsize < (long)SZREQBUF)
59
                newsize = SZREQBUF;
60
        reqbuf.buffer = malloc(newsize);
61
        if(!reqbuf.buffer) {
62
                EPRINTF("nxFlushReq: Can't allocate initial request buffer\n");
63
                exit(1);
64
        }
65
        reqbuf.bufptr = reqbuf.buffer;
66
        reqbuf.bufmax = reqbuf.buffer + newsize;
67
}
68
 
69
void
70
nxAssignReqbuffer(char *buffer, long size)
71
{
72
        ACCESS_PER_THREAD_DATA();
73
 
74
        if ( reqbuf.buffer != 0 )
75
                free(reqbuf.buffer);
76
        reqbuf.buffer = buffer;
77
        reqbuf.bufptr = reqbuf.buffer;
78
        reqbuf.bufmax = reqbuf.buffer + size;
79
}
80
 
81
/* Write a block of data on the socket to the nano-X server */
82
void
83
nxWriteSocket(char *buf, int todo)
84
{
85
        int written;
86
        ACCESS_PER_THREAD_DATA();
87
 
88
        do {
89
                written = write(nxSocket, buf, todo);
90
                if ( written < 0 ) {
91
                        if ( errno == EAGAIN || errno == EINTR )
92
                                continue;
93
                        EPRINTF("nxFlushReq: write failed: %m\n");
94
                        exit(1);
95
                }
96
                buf += written;
97
                todo -= written;
98
        } while ( todo > 0 );
99
}
100
 
101
/* Flush request buffer if required, possibly reallocate buffer size*/
102
void
103
nxFlushReq(long newsize, int reply_needed)
104
{
105
        ACCESS_PER_THREAD_DATA();
106
 
107
        /* handle one-time initialization case*/
108
        if(reqbuf.buffer == NULL) {
109
                nxAllocReqbuffer(newsize);
110
                return;
111
        }
112
 
113
        /* flush buffer if required*/
114
        if(reqbuf.bufptr > reqbuf.buffer) {
115
                char *  buf = reqbuf.buffer;
116
                int     todo = reqbuf.bufptr - reqbuf.buffer;
117
 
118
#if HAVE_SHAREDMEM_SUPPORT
119
                if ( nxSharedMem != 0 ) {
120
                        /* There is a shared memory segment used for the
121
                         * request buffer.  Make up a flush command and
122
                         * send it over the socket, to tell the server to
123
                         * process the shared memory segment.
124
                         * The 'reply_needed' argument should be non-zero
125
                         * when a confirmation is needed that all commands
126
                         * are flushed, so new ones can be filled into the
127
                         * request buffer.  NOTE:  This is *only* needed
128
                         * when explicitely flushing the request buffer, or
129
                         * when flushing it to make space for new commands.
130
                         * DO NOT REQUEST A REPLY when flushing the request
131
                         * buffer because the last command in the buffer
132
                         * will send a response:  This response would be
133
                         * queued up first and had to be drained before the
134
                         * response to the flush command itsel....
135
                         * So the GrReadBlock used to read replys to commands
136
                         * must not specify a nonzero 'reply_needed'.
137
                         * Not requesting a reply in this case is
138
                         * safe, since the command executed will wait for
139
                         * the reply *it* is waiting for, and thus make
140
                         * sure the request buffer is flushed before
141
                         * continuing.
142
                         *
143
                         * We have to make the protocol request by hand,
144
                         * as it has to be sent over the socket to wake
145
                         * up the Nano-X server.
146
                         */
147
                        char c;
148
                        nxShmCmdsFlushReq req;
149
 
150
                        req.reqType = GrNumShmCmdsFlush;
151
                        req.hilength = 0;
152
                        req.length = sizeof(req);
153
                        req.size = todo;
154
                        req.reply = reply_needed;
155
 
156
                        nxWriteSocket((char *)&req,sizeof(req));
157
 
158
                        if ( reply_needed )
159
                                while ( read(nxSocket, &c, 1) != 1 )
160
                                        ;
161
 
162
                        reqbuf.bufptr = reqbuf.buffer;
163
 
164
                        if ( reqbuf.buffer + newsize > reqbuf.bufmax ) {
165
                                /* Shared memory too small, critical */
166
                                EPRINTF("nxFlushReq: shm region too small\n");
167
                                exit(1);
168
                        }
169
                        return;
170
                }
171
#endif /* HAVE_SHAREDMEM_SUPPORT*/
172
 
173
                /* Standard Socket transfer */
174
                nxWriteSocket(buf,todo);
175
                reqbuf.bufptr = reqbuf.buffer;
176
        }
177
 
178
        /* allocate larger buffer for current request, if needed*/
179
        if(reqbuf.bufptr + newsize >= reqbuf.bufmax) {
180
                reqbuf.buffer = realloc(reqbuf.buffer, newsize);
181
                if(!reqbuf.buffer) {
182
                       EPRINTF("nxFlushReq: Can't reallocate request buffer\n");
183
                        exit(1);
184
                }
185
                reqbuf.bufptr = reqbuf.buffer;
186
                reqbuf.bufmax = reqbuf.buffer + newsize;
187
        }
188
}
189
 
190
/* calc # bytes required for passed string according to encoding*/
191
int
192
nxCalcStringBytes(void *str, int count, int flags)
193
{
194
        int     nbytes;
195
 
196
        /* calc byte length of data*/
197
        if(flags & MWTF_UC16)
198
                nbytes = count * 2;
199
        else if(flags & MWTF_UC32)
200
                nbytes = count * 4;
201
        else
202
                nbytes = count;
203
 
204
        return nbytes;
205
}

powered by: WebSVN 2.1.0

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