]>
git.ipfire.org Git - people/dweismueller/ipfire-2.x.git/blob - src/hwinfo/src/int10/int10.c
04c1507f465bee053a94c755f97c8946626a6495
13 static unsigned segofs2addr(unsigned char *segofs
);
14 static unsigned get_data(unsigned char *buf
, unsigned buf_size
, unsigned addr
);
15 static void read_vbe_info(hd_data_t
*hd_data
, vbe_info_t
*vbe
, unsigned char *vbeinfo
, unsigned cpuemu
);
17 static hd_data_t
*log_hd_data
;
18 void log_err(char *format
, ...) __attribute__ ((format (printf
, 1, 2)));
20 void get_vbe_info(hd_data_t
*hd_data
, vbe_info_t
*vbe
)
23 unsigned char vbeinfo
[0x200];
25 unsigned cpuemu
= hd_data
->flags
.cpuemu
;
27 log_hd_data
= hd_data
;
29 if(InitInt10(hd_data
, hd_data
->pci_config_type
)) {
30 ADD2LOG("VBE: Could not init Int10\n");
34 memset(vbeinfo
, 0, sizeof vbeinfo
);
35 strcpy(vbeinfo
, "VBE2");
37 PROGRESS(4, 1, "vbe info");
39 if(hd_probe_feature(hd_data
, pr_cpuemu_debug
)) cpuemu
|= 2;
42 if(hd_data
->flags
.cpuemu
)
44 ADD2LOG("vm86: using CPU emulation\n");
46 ax
= 0x4f00; bx
= 0; cx
= 0;
47 i
= CallInt10(&ax
, &bx
, &cx
, vbeinfo
, sizeof vbeinfo
, cpuemu
) & 0xffff;
50 ADD2LOG("VBE: Error (0x4f00): 0x%04x\n", i
);
55 if(hd_probe_feature(hd_data
, pr_bios_fb
)) {
56 PROGRESS(4, 2, "mode info");
58 read_vbe_info(hd_data
, vbe
, vbeinfo
, cpuemu
);
61 if(hd_probe_feature(hd_data
, pr_bios_ddc
)) {
62 PROGRESS(4, 3, "ddc info");
64 memset(vbeinfo
, 0, sizeof vbeinfo
);
65 ax
= 0x4f15; bx
= 1; cx
= 0;
66 i
= CallInt10(&ax
, &bx
, &cx
, vbeinfo
, sizeof vbeinfo
, cpuemu
) & 0xffff;
69 ADD2LOG("Error (0x4f15): 0x%04x\n", i
);
72 memcpy(vbe
->ddc
, vbeinfo
, sizeof vbe
->ddc
);
74 ADD2LOG("edid record:\n");
75 for(i
= 0; (unsigned) i
< sizeof vbe
->ddc
; i
+= 0x10) {
77 hexdump(&hd_data
->log
, 1, 0x10, vbe
->ddc
+ i
);
83 if(hd_probe_feature(hd_data
, pr_bios_mode
)) {
84 PROGRESS(4, 4, "gfx mode");
86 ax
= 0x4f03; bx
= 0; cx
= 0;
87 i
= CallInt10(&ax
, &bx
, &cx
, vbeinfo
, sizeof vbeinfo
, cpuemu
) & 0xffff;
90 ADD2LOG("Error (0x4f03): 0x%04x\n", i
);
92 vbe
->current_mode
= bx
;
101 unsigned segofs2addr(unsigned char *segofs
)
103 return segofs
[0] + (segofs
[1] << 8) + (segofs
[2] << 4)+ (segofs
[3] << 12);
107 unsigned get_data(unsigned char *buf
, unsigned buf_size
, unsigned addr
)
109 unsigned bufferaddr
= 0x7e00;
115 if(addr
>= bufferaddr
&& addr
< bufferaddr
+ 0x200) {
116 len
= bufferaddr
+ 0x200 - addr
;
117 if(len
>= buf_size
) len
= buf_size
- 1;
118 memcpy(buf
, addr
+ (char *) 0, len
);
120 else if(addr
>= 0x0c0000 && addr
< 0x100000) {
121 len
= 0x100000 - addr
;
122 if(len
>= buf_size
) len
= buf_size
- 1;
123 memcpy(buf
, addr
+ (char *) 0, len
);
132 void read_vbe_info(hd_data_t
*hd_data
, vbe_info_t
*vbe
, unsigned char *v
, unsigned cpuemu
)
134 unsigned char tmp
[1024], s
[64];
136 unsigned modelist
[0x100];
137 unsigned bpp
, res_bpp
, fb
, clock
;
143 vbe
->version
= v
[0x04] + (v
[0x05] << 8);
144 vbe
->oem_version
= v
[0x14] + (v
[0x15] << 8);
145 vbe
->memory
= (v
[0x12] + (v
[0x13] << 8)) << 16;
148 "version = %u.%u, oem version = %u.%u\n",
149 vbe
->version
>> 8, vbe
->version
& 0xff, vbe
->oem_version
>> 8, vbe
->oem_version
& 0xff
152 ADD2LOG("memory = %uk\n", vbe
->memory
>> 10);
154 l
= get_data(tmp
, sizeof tmp
, u
= segofs2addr(v
+ 0x06));
155 vbe
->oem_name
= canon_str(tmp
, l
);
156 ADD2LOG("oem name [0x%05x] = \"%s\"\n", u
, vbe
->oem_name
);
158 l
= get_data(tmp
, sizeof tmp
, u
= segofs2addr(v
+ 0x16));
159 vbe
->vendor_name
= canon_str(tmp
, l
);
160 ADD2LOG("vendor name [0x%05x] = \"%s\"\n", u
, vbe
->vendor_name
);
162 l
= get_data(tmp
, sizeof tmp
, u
= segofs2addr(v
+ 0x1a));
163 vbe
->product_name
= canon_str(tmp
, l
);
164 ADD2LOG("product name [0x%05x] = \"%s\"\n", u
, vbe
->product_name
);
166 l
= get_data(tmp
, sizeof tmp
, u
= segofs2addr(v
+ 0x1e));
167 vbe
->product_revision
= canon_str(tmp
, l
);
168 ADD2LOG("product revision [0x%05x] = \"%s\"\n", u
, vbe
->product_revision
);
170 l
= get_data(tmp
, sizeof tmp
, u
= segofs2addr(v
+ 0x0e)) >> 1;
172 for(i
= vbe
->modes
= 0; i
< l
&& i
< sizeof modelist
/ sizeof *modelist
; i
++) {
173 u
= tmp
[2 * i
] + (tmp
[2 * i
+ 1] << 8);
175 modelist
[vbe
->modes
++] = u
;
180 ADD2LOG("%u video modes:\n", vbe
->modes
);
182 vbe
->mode
= new_mem(vbe
->modes
* sizeof *vbe
->mode
);
184 if(!vbe
->mode
) return;
186 for(i
= 0; i
< vbe
->modes
; i
++) {
190 mi
->number
= modelist
[i
];
192 ax
= 0x4f01; bx
= 0; cx
= modelist
[i
];
193 l
= CallInt10(&ax
, &bx
, &cx
, tmp
, sizeof tmp
, cpuemu
) & 0xffff;
196 ADD2LOG("0x%04x: no mode info\n", modelist
[i
]);
200 mi
->attributes
= tmp
[0x00] + (tmp
[0x01] << 8);
202 mi
->width
= tmp
[0x12] + (tmp
[0x13] << 8);
203 mi
->height
= tmp
[0x14] + (tmp
[0x15] << 8);
204 mi
->bytes_p_line
= tmp
[0x10] + (tmp
[0x11] << 8);
206 mi
->win_A_start
= (tmp
[0x08] + (tmp
[0x09] << 8)) << 4;
207 mi
->win_B_start
= (tmp
[0x0a] + (tmp
[0x0b] << 8)) << 4;
209 mi
->win_A_attr
= tmp
[0x02];
210 mi
->win_B_attr
= tmp
[0x03];
212 mi
->win_gran
= (tmp
[0x04] + (tmp
[0x05] << 8)) << 10;
213 mi
->win_size
= (tmp
[0x06] + (tmp
[0x07] << 8)) << 10;
238 bpp
= tmp
[0x19] - tmp
[0x25];
243 if(vbe
->version
>= 0x0200) {
244 mi
->fb_start
= tmp
[0x28] + (tmp
[0x29] << 8) + (tmp
[0x2a] << 16) + (tmp
[0x2b] << 24);
248 if(vbe
->version
>= 0x0300) {
249 mi
->pixel_clock
= tmp
[0x3e] + (tmp
[0x3f] << 8) + (tmp
[0x40] << 16) + (tmp
[0x41] << 24);
252 mi
->pixel_size
= bpp
;
255 ADD2LOG(" 0x%04x[%02x]: %ux%u, text\n", mi
->number
, mi
->attributes
, mi
->width
, mi
->height
);
259 (mi
->attributes
& 1) && /* mode is supported */
262 if(!vbe
->fb_start
) vbe
->fb_start
= mi
->fb_start
;
265 if(res_bpp
) sprintf(s
, "+%u", res_bpp
);
267 " 0x%04x[%02x]: %ux%u+%u, %u%s bpp",
268 mi
->number
, mi
->attributes
, mi
->width
, mi
->height
, mi
->bytes_p_line
, mi
->pixel_size
, s
271 if(mi
->pixel_clock
) ADD2LOG(", max. %u MHz", mi
->pixel_clock
/1000000);
273 if(mi
->fb_start
) ADD2LOG(", fb: 0x%08x", mi
->fb_start
);
275 ADD2LOG(", %04x.%x", mi
->win_A_start
, mi
->win_A_attr
);
277 if(mi
->win_B_start
|| mi
->win_B_attr
) ADD2LOG("/%04x.%x", mi
->win_B_start
, mi
->win_B_attr
);
279 ADD2LOG(": %uk", mi
->win_size
>> 10);
281 if(mi
->win_gran
!= mi
->win_size
) ADD2LOG("/%uk", mi
->win_gran
>> 10);
289 void log_err(char *format
, ...)
294 va_start(args
, format
);
295 vsnprintf(buf
, sizeof buf
, format
, args
);
296 str_printf(&log_hd_data
->log
, -2, "%s", buf
);