Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
//
2
// channel element driver
3
//
4
#include "u.h"
5
#include "../port/lib.h"
6
#include "mem.h"
7
#include "dat.h"
8
#include "fns.h"
9
#include "io.h"
10
#include "../port/error.h"
11
#include "msaturn.h"
12
 
13
enum{
14
	Ucuunknown = 0,
15
	Ucu64,
16
 
17
	Ndsp = 16,
18
 
19
	Cedead = 0,
20
	Cereset,
21
	Celoaded,
22
	Cerunning,
23
 
24
	Qdir = 0,
25
	Qctl,
26
	Qce,
27
 
28
	Cpldbase = Saturn + 0x6000000,
29
		Cplducuversion_ucu = 0x1c,
30
	Cebase = Saturn + 0x3000000,
31
	Cesize = 0x100000,
32
};
33
 
34
typedef struct Cpld Cpld;
35
struct Cpld{
36
	uchar	led;
37
	uchar	fpga1;
38
	uchar	slotid;
39
	uchar	version;
40
	uchar	watchdog;
41
	uchar	spi;
42
	uchar	asicreset;
43
	uchar	dspreset;
44
	uchar	generalreset;
45
	uchar	ucuversion;
46
	uchar	fpga2;
47
};
48
 
49
typedef struct Circbuf Circbuf;
50
struct Circbuf{
51
	uchar	*nextin;
52
	uchar	*nextout;
53
	uchar	*start;
54
	uchar	*end;
55
};
56
 
57
typedef struct Dsp Dsp;
58
struct Dsp{
59
	Ref;
60
	int		state;
61
	Circbuf	*cb;
62
};
63
 
64
typedef struct Ce Ce;
65
struct Ce{
66
	int		ucutype;
67
	Ce		*ces[Ndsp];
68
};
69
 
70
static Cpld*cpld = (Cpld*)Cpldbase;
71
static Ce ce;
72
 
73
static void
74
ceinit(void)
75
{
76
	if(cpld->ucuversion & Cplducuversion_ucu)
77
		ce.ucutype = Ucu64;
78
	else{
79
		print("ceinit: unsuppoerted UCU\n");
80
		return;
81
	}
82
 
83
}
84
 
85
static Chan*
86
ceattach(char*spec)
87
{
88
	return devattach('C', spec);
89
}
90
 
91
#define DEV(q)			((int)(((q).path >> 8) & 0xff))
92
#define TYPE(q)			((int)((q).path & 0xff))
93
#define QID(d, t)		((((d) & 0xff) << 8) | (t))
94
 
95
static int
96
cegen(Chan*c, char*, Dirtab*, int, int i, Dir*dp)
97
{
98
	Qid qid;
99
 
100
	switch(TYPE(c->qid)){
101
	case Qdir:
102
		if(i == DEVDOTDOT){
103
			mkqid(&qid, QID(0, Qdir), 0, QTDIR);
104
			devdir(c, qid, "#C", 0, eve, 0555, dp);
105
			return 1;
106
		}
107
 
108
		if(i == 0){
109
			mkqid(&qid, QID(-1, Qctl), 0, QTFILE);
110
			devdir(c, qid, "cectl", 0, eve, 0644, dp);
111
			return 1;
112
		}
113
 
114
		if (--i >= Ndsp)
115
			return -1;
116
 
117
		mkqid(&qid, QID(Qce, i), 0, QTFILE);
118
		snprint(up->genbuf, sizeof(up->genbuf), "ce%d", i);
119
		devdir(c, qid, up->genbuf, 0, eve, 0644, dp);
120
		return 1;
121
 
122
	default:
123
		return -1;
124
	}
125
}
126
 
127
static Walkqid *
128
cewalk(Chan*c, Chan*nc, char**name, int nname)
129
{
130
	return devwalk(c, nc, name, nname, 0, 0, cegen);
131
}
132
 
133
static int
134
cestat(Chan*c, uchar*db, int n)
135
{
136
	return devstat(c, db, n, 0, 0, cegen);
137
}
138
 
139
static Chan*
140
ceopen(Chan*c, int omode)
141
{
142
	c->mode = openmode(omode);
143
	c->flag |= COPEN;
144
	c->offset = 0;
145
	return c;
146
}
147
 
148
static void
149
ceclose(Chan*)
150
{}
151
 
152
static long
153
ceread(Chan*c, void*a, long n, vlong)
154
{
155
	switch(TYPE(c->qid)){
156
	case Qdir:
157
		return devdirread(c, a, n, 0, 0, cegen);
158
 
159
	default:
160
		error("unsupported operation");
161
	}
162
	return 0;
163
}
164
 
165
static long
166
cewrite(Chan*, void*, long, vlong)
167
{
168
	return 0;
169
}
170
 
171
Dev cedevtab = {
172
	'C',
173
	"channel element",
174
 
175
	devreset,
176
	ceinit,
177
	devshutdown,
178
	ceattach,
179
	cewalk,
180
	cestat,
181
	ceopen,
182
	devcreate,
183
	ceclose,
184
	ceread,
185
	devbread,
186
	cewrite,
187
	devbwrite,
188
	devremove,
189
	devwstat,
190
	devpower,
191
};