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