xref: /plan9-contrib/sys/src/cmd/aux/vga/db.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ndb.h>
5 
6 #include "vga.h"
7 
8 static Ndb*
9 dbopen(char *dbname)
10 {
11 	Ndb *db;
12 
13 	if((db = ndbopen(dbname)) == 0)
14 		error("dbopen: %s: %r\n", dbname);
15 	return db;
16 }
17 
18 static Ctlr*
19 addctlr(Vga *vga, char *val)
20 {
21 	Ctlr **ctlr;
22 	char name[NAMELEN+1], *p;
23 	int i;
24 
25 	/*
26 	 * A controller name may have an extension on the end
27 	 * following a '-' which can be used as a speed grade or
28 	 * subtype.  Do the match without the extension.
29 	 * The linked copy of the controller struct gets the
30 	 * full name with extension.
31 	 */
32 	strncpy(name, val, NAMELEN);
33 	name[NAMELEN] = 0;
34 	if(p = strchr(name, '-'))
35 		*p = 0;
36 
37 	for(i = 0; ctlrs[i]; i++){
38 		if(strcmp(ctlrs[i]->name, name))
39 			continue;
40 		for(ctlr = &vga->link; *ctlr; ctlr = &((*ctlr)->link))
41 			;
42 		*ctlr = alloc(sizeof(Ctlr));
43 		**ctlr = *ctlrs[i];
44 		strncpy((*ctlr)->name, val, NAMELEN);
45 		return *ctlr;
46 	}
47 
48 	error("don't know how to programme a \"%s\" ctlr\n", val);
49 	return 0;
50 }
51 
52 int
53 dbctlr(char *name, Vga *vga)
54 {
55 	Ndb *db;
56 	Ndbs s;
57 	Ndbtuple *t, *tuple;
58 	char bios[128];
59 	char *string;
60 	long offset;
61 	int len;
62 
63 	db = dbopen(name);
64 
65 	for(tuple = ndbsearch(db, &s, "ctlr", ""); tuple; tuple = ndbsnext(&s, "ctlr", "")){
66 		for(t = tuple->entry; t; t = t->entry){
67 			if((offset = strtoul(t->attr, 0, 0)) == 0)
68 				continue;
69 
70 			string = t->val;
71 			len = strlen(string);
72 			readbios(bios, len, offset);
73 			if(strncmp(bios, string, len) == 0){
74 				for(t = tuple->entry; t; t = t->entry){
75 					if(strcmp(t->attr, "ctlr") == 0)
76 						vga->ctlr = addctlr(vga, t->val);
77 					else if(strcmp(t->attr, "ramdac") == 0)
78 						vga->ramdac = addctlr(vga, t->val);
79 					else if(strcmp(t->attr, "clock") == 0)
80 						vga->clock = addctlr(vga, t->val);
81 					else if(strcmp(t->attr, "hwgc") == 0)
82 						vga->hwgc = addctlr(vga, t->val);
83 					else if(strcmp(t->attr, "link") == 0)
84 						addctlr(vga, t->val);
85 				}
86 				ndbfree(tuple);
87 				ndbclose(db);
88 				return 1;
89 			}
90 		}
91 
92 		ndbfree(tuple);
93 	}
94 
95 	ndbclose(db);
96 	return 0;
97 }
98 
99 static int
100 dbmonitor(Ndb *db, Mode *mode, char *type, char *size)
101 {
102 	Ndbs s;
103 	Ndbtuple *t, *tuple;
104 	char *p, attr[NAMELEN+1], val[NAMELEN+1];
105 	int x;
106 
107 	memset(mode, 0, sizeof(Mode));
108 	strcpy(attr, type);
109 	strcpy(val, size);
110 buggery:
111 	if((tuple = ndbsearch(db, &s, attr, val)) == 0)
112 		return 0;
113 
114 	if(mode->x == 0 && ((mode->x = strtol(val, &p, 0)) == 0 || *p++ != 'x'))
115 		return 0;
116 	if(mode->y == 0 && ((mode->y = strtol(p, &p, 0)) == 0 || *p++ != 'x'))
117 		return 0;
118 	if(mode->z == 0 && ((mode->z = strtol(p, &p, 0)) == 0))
119 		return 0;
120 
121 	for(t = tuple->entry; t; t = t->entry){
122 		if(strcmp(t->attr, "clock") == 0 && mode->frequency == 0)
123 			mode->frequency = strtod(t->val, 0)*1000000;
124 		else if(strcmp(t->attr, "ht") == 0 && mode->ht == 0)
125 			mode->ht = strtol(t->val, 0, 0);
126 		else if(strcmp(t->attr, "shb") == 0 && mode->shb == 0)
127 			mode->shb = strtol(t->val, 0, 0);
128 		else if(strcmp(t->attr, "ehb") == 0 && mode->ehb == 0)
129 			mode->ehb = strtol(t->val, 0, 0);
130 		else if(strcmp(t->attr, "vt") == 0 && mode->vt == 0)
131 			mode->vt = strtol(t->val, 0, 0);
132 		else if(strcmp(t->attr, "vrs") == 0 && mode->vrs == 0)
133 			mode->vrs = strtol(t->val, 0, 0);
134 		else if(strcmp(t->attr, "vre") == 0 && mode->vre == 0)
135 			mode->vre = strtol(t->val, 0, 0);
136 		else if(strcmp(t->attr, "hsync") == 0)
137 			mode->hsync = *t->val;
138 		else if(strcmp(t->attr, "vsync") == 0)
139 			mode->vsync = *t->val;
140 		else if(strcmp(t->attr, "interlace") == 0)
141 			mode->interlace = *t->val;
142 		else{
143 			strcpy(attr, t->attr);
144 			strcpy(val, t->val);
145 			ndbfree(tuple);
146 			goto buggery;
147 		}
148 	}
149 	ndbfree(tuple);
150 
151 	if((x = strtol(size, &p, 0)) == 0 || x != mode->x || *p++ != 'x')
152 		return 0;
153 	if((x = strtol(p, &p, 0)) == 0 || x != mode->y || *p++ != 'x')
154 		return 0;
155 	if((x = strtol(p, &p, 0)) == 0 || x != mode->z)
156 		return 0;
157 
158 	return 1;
159 }
160 
161 Mode*
162 dbmode(char *name, char *type, char *size)
163 {
164 	Ndb *db;
165 	Ndbs s;
166 	Ndbtuple *t, *tuple;
167 	Mode *mode;
168 	char attr[NAMELEN+1];
169 
170 	db = dbopen(name);
171 	mode = alloc(sizeof(Mode));
172 	strcpy(attr, type);
173 
174 	/*
175 	 * Look for the attr=size entry.
176 	 */
177 	if(dbmonitor(db, mode, attr, size)){
178 		strcpy(mode->type, type);
179 		strcpy(mode->size, size);
180 		ndbclose(db);
181 		return mode;
182 	}
183 
184 	/*
185 	 * Not found. Look for an attr="" entry and then
186 	 * for an alias=attr within.
187 	 */
188 buggery:
189 	for(tuple = ndbsearch(db, &s, attr, ""); tuple; tuple = ndbsnext(&s, attr, "")){
190 		for(t = tuple->entry; t; t = t->entry){
191 			if(strcmp(t->attr, "alias"))
192 				continue;
193 			strcpy(attr, t->val);
194 			if(dbmonitor(db, mode, attr, size)){
195 				strcpy(mode->type, type);
196 				strcpy(mode->size, size);
197 				ndbfree(tuple);
198 				ndbclose(db);
199 				return mode;
200 			}
201 
202 			/*
203 			 * Found an alias but no match for size,
204 			 * restart looking for attr="" with the
205 			 * new attr.
206 			 */
207 			ndbfree(tuple);
208 			goto buggery;
209 		}
210 		ndbfree(tuple);
211 	}
212 
213 	free(mode);
214 	ndbclose(db);
215 	return 0;
216 }
217 
218 void
219 dbdumpmode(Mode *mode)
220 {
221 	verbose("dbdumpmode\n");
222 
223 	print("type=%s, size=%s\n", mode->type, mode->size);
224 	print("frequency=%d\n", mode->frequency);
225 	print("x=%d (0x%X), y=%d (0x%X), z=%d (0x%X)\n",
226 		mode->x, mode->x, mode->y,  mode->y, mode->z, mode->z);
227 	print("ht=%d (0x%X), shb=%d (0x%X), ehb=%d (0x%X)\n",
228 		mode->ht, mode->ht, mode->shb, mode->shb, mode->ehb, mode->ehb);
229 	print("vt=%d (0x%X), vrs=%d (0x%X), vre=%d (0x%X)\n",
230 		mode->vt, mode->vt, mode->vrs, mode->vrs, mode->vre, mode->vre);
231 	print("hsync=%d, vsync=%d, interlace=%d\n",
232 		mode->hsync, mode->vsync, mode->interlace);
233 }
234