1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48#include <common.h>
49#include <bios_emul.h>
50#include <errno.h>
51#include <malloc.h>
52#include <vbe.h>
53#include "biosemui.h"
54
55
56#define MAX_BIOSLEN (128 * 1024L)
57
58
59static u32 saveROMBaseAddress;
60static u32 saveBaseAddress10;
61static u32 saveBaseAddress14;
62static u32 saveBaseAddress18;
63static u32 saveBaseAddress20;
64
65
66const int vbe_offset = 0x2000;
67
68static const void *bios_ptr(const void *buf, BE_VGAInfo *vga_info,
69 u32 x86_dword_ptr)
70{
71 u32 seg_ofs, flat;
72
73 seg_ofs = le32_to_cpu(x86_dword_ptr);
74 flat = ((seg_ofs & 0xffff0000) >> 12) | (seg_ofs & 0xffff);
75 if (flat >= 0xc0000)
76 return vga_info->BIOSImage + flat - 0xc0000;
77 else
78 return buf + (flat - vbe_offset);
79}
80
81static int atibios_debug_mode(BE_VGAInfo *vga_info, RMREGS *regs,
82 int vesa_mode, struct vbe_mode_info *mode_info)
83{
84 void *buffer = (void *)(M.mem_base + vbe_offset);
85 u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00;
86 u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff;
87 struct vesa_mode_info *vm;
88 struct vbe_info *info;
89 const u16 *modes_bios, *ptr;
90 u16 *modes;
91 int size;
92
93 debug("VBE: Getting information\n");
94 regs->e.eax = VESA_GET_INFO;
95 regs->e.esi = buffer_seg;
96 regs->e.edi = buffer_adr;
97 info = buffer;
98 memset(info, '\0', sizeof(*info));
99 strcpy(info->signature, "VBE2");
100 BE_int86(0x10, regs, regs);
101 if (regs->e.eax != 0x4f) {
102 debug("VESA_GET_INFO: error %x\n", regs->e.eax);
103 return -ENOSYS;
104 }
105 debug("version %x\n", le16_to_cpu(info->version));
106 debug("oem '%s'\n", (char *)bios_ptr(buffer, vga_info,
107 info->oem_string_ptr));
108 debug("vendor '%s'\n", (char *)bios_ptr(buffer, vga_info,
109 info->vendor_name_ptr));
110 debug("product '%s'\n", (char *)bios_ptr(buffer, vga_info,
111 info->product_name_ptr));
112 debug("rev '%s'\n", (char *)bios_ptr(buffer, vga_info,
113 info->product_rev_ptr));
114 modes_bios = bios_ptr(buffer, vga_info, info->modes_ptr);
115 debug("Modes: ");
116 for (ptr = modes_bios; *ptr != 0xffff; ptr++)
117 debug("%x ", le16_to_cpu(*ptr));
118 debug("\nmemory %dMB\n", le16_to_cpu(info->total_memory) >> 4);
119 size = (ptr - modes_bios) * sizeof(u16) + 2;
120 modes = malloc(size);
121 if (!modes)
122 return -ENOMEM;
123 memcpy(modes, modes_bios, size);
124
125 regs->e.eax = VESA_GET_CUR_MODE;
126 BE_int86(0x10, regs, regs);
127 if (regs->e.eax != 0x4f) {
128 debug("VESA_GET_CUR_MODE: error %x\n", regs->e.eax);
129 return -ENOSYS;
130 }
131 debug("Current mode %x\n", regs->e.ebx);
132
133 for (ptr = modes; *ptr != 0xffff; ptr++) {
134 int mode = le16_to_cpu(*ptr);
135 bool linear_ok;
136 int attr;
137
138 break;
139 debug("Mode %x: ", mode);
140 memset(buffer, '\0', sizeof(struct vbe_mode_info));
141 regs->e.eax = VESA_GET_MODE_INFO;
142 regs->e.ebx = 0;
143 regs->e.ecx = mode;
144 regs->e.edx = 0;
145 regs->e.esi = buffer_seg;
146 regs->e.edi = buffer_adr;
147 BE_int86(0x10, regs, regs);
148 if (regs->e.eax != 0x4f) {
149 debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax);
150 continue;
151 }
152 memcpy(mode_info->mode_info_block, buffer,
153 sizeof(struct vesa_mode_info));
154 mode_info->valid = true;
155 vm = &mode_info->vesa;
156 attr = le16_to_cpu(vm->mode_attributes);
157 linear_ok = attr & 0x80;
158 debug("res %d x %d, %d bpp, mm %d, (Linear %s, attr %02x)\n",
159 le16_to_cpu(vm->x_resolution),
160 le16_to_cpu(vm->y_resolution),
161 vm->bits_per_pixel, vm->memory_model,
162 linear_ok ? "OK" : "not available",
163 attr);
164 debug("\tRGB pos=%d,%d,%d, size=%d,%d,%d\n",
165 vm->red_mask_pos, vm->green_mask_pos, vm->blue_mask_pos,
166 vm->red_mask_size, vm->green_mask_size,
167 vm->blue_mask_size);
168 }
169
170 return 0;
171}
172
173static int atibios_set_vesa_mode(RMREGS *regs, int vesa_mode,
174 struct vbe_mode_info *mode_info)
175{
176 void *buffer = (void *)(M.mem_base + vbe_offset);
177 u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00;
178 u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff;
179 struct vesa_mode_info *vm;
180
181 debug("VBE: Setting VESA mode %#04x\n", vesa_mode);
182 regs->e.eax = VESA_SET_MODE;
183 regs->e.ebx = vesa_mode;
184
185 regs->e.ebx |= (1 << 14) | (1 << 15);
186 BE_int86(0x10, regs, regs);
187 if (regs->e.eax != 0x4f) {
188 debug("VESA_SET_MODE: error %x\n", regs->e.eax);
189 return -ENOSYS;
190 }
191
192 memset(buffer, '\0', sizeof(struct vbe_mode_info));
193 debug("VBE: Geting info for VESA mode %#04x\n", vesa_mode);
194 regs->e.eax = VESA_GET_MODE_INFO;
195 regs->e.ecx = vesa_mode;
196 regs->e.esi = buffer_seg;
197 regs->e.edi = buffer_adr;
198 BE_int86(0x10, regs, regs);
199 if (regs->e.eax != 0x4f) {
200 debug("VESA_GET_MODE_INFO: error %x\n", regs->e.eax);
201 return -ENOSYS;
202 }
203
204 memcpy(mode_info->mode_info_block, buffer,
205 sizeof(struct vesa_mode_info));
206 mode_info->valid = true;
207 mode_info->video_mode = vesa_mode;
208 vm = &mode_info->vesa;
209 vm->x_resolution = le16_to_cpu(vm->x_resolution);
210 vm->y_resolution = le16_to_cpu(vm->y_resolution);
211 vm->bytes_per_scanline = le16_to_cpu(vm->bytes_per_scanline);
212 vm->phys_base_ptr = le32_to_cpu(vm->phys_base_ptr);
213 vm->mode_attributes = le16_to_cpu(vm->mode_attributes);
214 debug("VBE: Init complete\n");
215
216 return 0;
217}
218
219
220
221
222
223
224
225
226
227
228
229#ifdef CONFIG_DM_PCI
230static void PCI_doBIOSPOST(struct udevice *pcidev, BE_VGAInfo *vga_info,
231 int vesa_mode, struct vbe_mode_info *mode_info)
232#else
233static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info,
234 int vesa_mode, struct vbe_mode_info *mode_info)
235#endif
236{
237 RMREGS regs;
238 RMSREGS sregs;
239#ifdef CONFIG_DM_PCI
240 pci_dev_t bdf;
241#endif
242
243
244
245
246
247 memset(®s, 0, sizeof(regs));
248 memset(&sregs, 0, sizeof(sregs));
249#ifdef CONFIG_DM_PCI
250 bdf = dm_pci_get_bdf(pcidev);
251 regs.x.ax = (int)PCI_BUS(bdf) << 8 |
252 (int)PCI_DEV(bdf) << 3 | (int)PCI_FUNC(bdf);
253#else
254 regs.x.ax = ((int)PCI_BUS(pcidev) << 8) |
255 ((int)PCI_DEV(pcidev) << 3) | (int)PCI_FUNC(pcidev);
256#endif
257
258 BE_setVGA(vga_info);
259
260
261 BE_callRealMode(0xC000, 0x0003, ®s, &sregs);
262
263
264 BE_getVGA(vga_info);
265
266
267 if (0)
268 atibios_debug_mode(vga_info, ®s, vesa_mode, mode_info);
269 if (vesa_mode != -1)
270 atibios_set_vesa_mode(®s, vesa_mode, mode_info);
271}
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297#ifdef CONFIG_DM_PCI
298static u32 PCI_findBIOSAddr(struct udevice *pcidev, int *bar)
299#else
300static u32 PCI_findBIOSAddr(pci_dev_t pcidev, int *bar)
301#endif
302{
303 u32 base, size;
304
305 for (*bar = 0x10; *bar <= 0x14; (*bar) += 4) {
306#ifdef CONFIG_DM_PCI
307 dm_pci_read_config32(pcidev, *bar, &base);
308#else
309 pci_read_config_dword(pcidev, *bar, &base);
310#endif
311 if (!(base & 0x1)) {
312#ifdef CONFIG_DM_PCI
313 dm_pci_write_config32(pcidev, *bar, 0xFFFFFFFF);
314 dm_pci_read_config32(pcidev, *bar, &size);
315#else
316 pci_write_config_dword(pcidev, *bar, 0xFFFFFFFF);
317 pci_read_config_dword(pcidev, *bar, &size);
318#endif
319 size = ~(size & ~0xFF) + 1;
320 if (size >= MAX_BIOSLEN)
321 return base & ~0xFF;
322 }
323 }
324 return 0;
325}
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341#ifdef CONFIG_DM_PCI
342static void PCI_fixupIObase(struct udevice *pcidev, int reg, u32 *base)
343#else
344static void PCI_fixupIObase(pci_dev_t pcidev, int reg, u32 * base)
345#endif
346{
347 if ((*base & 0x1) && (*base > 0xFFFE)) {
348 *base &= 0xFFFF;
349#ifdef CONFIG_DM_PCI
350 dm_pci_write_config32(pcidev, reg, *base);
351#else
352 pci_write_config_dword(pcidev, reg, *base);
353#endif
354
355 }
356}
357
358
359
360
361
362
363
364
365
366
367
368#ifdef CONFIG_DM_PCI
369void *PCI_mapBIOSImage(struct udevice *pcidev)
370#else
371void *PCI_mapBIOSImage(pci_dev_t pcidev)
372#endif
373{
374 u32 BIOSImageBus;
375 int BIOSImageBAR;
376 u8 *BIOSImage;
377
378
379#ifdef CONFIG_DM_PCI
380 dm_pci_read_config32(pcidev, PCI_ROM_ADDRESS, &saveROMBaseAddress);
381 dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_0, &saveBaseAddress10);
382 dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
383 dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_2, &saveBaseAddress18);
384 dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
385#else
386 pci_read_config_dword(pcidev, PCI_ROM_ADDRESS, &saveROMBaseAddress);
387 pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &saveBaseAddress10);
388 pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
389 pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_2, &saveBaseAddress18);
390 pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
391#endif
392
393
394 if(saveBaseAddress14 != 0)
395 PCI_fixupIObase(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
396 else
397 PCI_fixupIObase(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
398
399
400
401
402
403
404 BIOSImageBus = PCI_findBIOSAddr(pcidev, &BIOSImageBAR);
405 if (BIOSImageBus == 0) {
406 printf("Find bios addr error\n");
407 return NULL;
408 }
409
410#ifdef CONFIG_DM_PCI
411 BIOSImage = dm_pci_bus_to_virt(pcidev, BIOSImageBus,
412 PCI_REGION_MEM, 0, MAP_NOCACHE);
413
414
415 dm_pci_write_config32(pcidev, BIOSImageBAR, 0);
416 dm_pci_write_config32(pcidev, PCI_ROM_ADDRESS, BIOSImageBus | 0x1);
417#else
418 BIOSImage = pci_bus_to_virt(pcidev, BIOSImageBus,
419 PCI_REGION_MEM, 0, MAP_NOCACHE);
420
421
422 pci_write_config_dword(pcidev, BIOSImageBAR, 0);
423 pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, BIOSImageBus | 0x1);
424#endif
425 udelay(1);
426
427
428
429
430 if (BIOSImage[0] != 0x55 || BIOSImage[1] != 0xAA || BIOSImage[2] == 0) {
431 return NULL;
432 }
433
434 return BIOSImage;
435}
436
437
438
439
440
441
442
443
444#ifdef CONFIG_DM_PCI
445void PCI_unmapBIOSImage(struct udevice *pcidev, void *BIOSImage)
446{
447 dm_pci_write_config32(pcidev, PCI_ROM_ADDRESS, saveROMBaseAddress);
448 dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_0, saveBaseAddress10);
449 dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_1, saveBaseAddress14);
450 dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_2, saveBaseAddress18);
451 dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_4, saveBaseAddress20);
452}
453#else
454void PCI_unmapBIOSImage(pci_dev_t pcidev, void *BIOSImage)
455{
456 pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, saveROMBaseAddress);
457 pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0, saveBaseAddress10);
458 pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_1, saveBaseAddress14);
459 pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_2, saveBaseAddress18);
460 pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_4, saveBaseAddress20);
461}
462#endif
463
464
465
466
467
468
469
470
471
472
473
474
475
476#ifdef CONFIG_DM_PCI
477static int PCI_postController(struct udevice *pcidev, uchar *bios_rom,
478 int bios_len, BE_VGAInfo *vga_info,
479 int vesa_mode, struct vbe_mode_info *mode_info)
480#else
481static int PCI_postController(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
482 BE_VGAInfo *vga_info, int vesa_mode,
483 struct vbe_mode_info *mode_info)
484#endif
485{
486 u32 bios_image_len;
487 uchar *mapped_bios;
488 uchar *copy_of_bios;
489#ifdef CONFIG_DM_PCI
490 pci_dev_t bdf;
491#endif
492
493 if (bios_rom) {
494 copy_of_bios = bios_rom;
495 bios_image_len = bios_len;
496 } else {
497
498
499
500
501 mapped_bios = PCI_mapBIOSImage(pcidev);
502 if (mapped_bios == NULL) {
503 printf("videoboot: Video ROM failed to map!\n");
504 return false;
505 }
506
507 bios_image_len = mapped_bios[2] * 512;
508
509 copy_of_bios = malloc(bios_image_len);
510 if (copy_of_bios == NULL) {
511 printf("videoboot: Out of memory!\n");
512 return false;
513 }
514 memcpy(copy_of_bios, mapped_bios, bios_image_len);
515 PCI_unmapBIOSImage(pcidev, mapped_bios);
516 }
517
518
519#ifdef CONFIG_DM_PCI
520 bdf = dm_pci_get_bdf(pcidev);
521 vga_info->function = PCI_FUNC(bdf);
522 vga_info->device = PCI_DEV(bdf);
523 vga_info->bus = PCI_BUS(bdf);
524#else
525 vga_info->function = PCI_FUNC(pcidev);
526 vga_info->device = PCI_DEV(pcidev);
527 vga_info->bus = PCI_BUS(pcidev);
528#endif
529 vga_info->pcidev = pcidev;
530 vga_info->BIOSImage = copy_of_bios;
531 vga_info->BIOSImageLen = bios_image_len;
532
533
534 if (copy_of_bios[0] != 0x55 || copy_of_bios[1] != 0xAA) {
535 printf("videoboot: Video ROM image is invalid!\n");
536 return false;
537 }
538
539 PCI_doBIOSPOST(pcidev, vga_info, vesa_mode, mode_info);
540
541
542 vga_info->BIOSImageLen = copy_of_bios[2] * 512;
543 return true;
544}
545
546#ifdef CONFIG_DM_PCI
547int biosemu_setup(struct udevice *pcidev, BE_VGAInfo **vga_infop)
548#else
549int biosemu_setup(pci_dev_t pcidev, BE_VGAInfo **vga_infop)
550#endif
551{
552 BE_VGAInfo *VGAInfo;
553#ifdef CONFIG_DM_PCI
554 pci_dev_t bdf = dm_pci_get_bdf(pcidev);
555
556 printf("videoboot: Booting PCI video card bus %d, function %d, device %d\n",
557 PCI_BUS(bdf), PCI_FUNC(bdf), PCI_DEV(bdf));
558#else
559 printf("videoboot: Booting PCI video card bus %d, function %d, device %d\n",
560 PCI_BUS(pcidev), PCI_FUNC(pcidev), PCI_DEV(pcidev));
561#endif
562
563 if ((VGAInfo = malloc(sizeof(*VGAInfo))) == NULL) {
564 printf("videoboot: Out of memory!\n");
565 return -ENOMEM;
566 }
567 memset(VGAInfo, 0, sizeof(*VGAInfo));
568 BE_init(0, 65536, VGAInfo, 0);
569 *vga_infop = VGAInfo;
570
571 return 0;
572}
573
574void biosemu_set_interrupt_handler(int intnum, int (*int_func)(void))
575{
576 X86EMU_setupIntrFunc(intnum, (X86EMU_intrFuncs)int_func);
577}
578
579#ifdef CONFIG_DM_PCI
580int biosemu_run(struct udevice *pcidev, uchar *bios_rom, int bios_len,
581 BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
582 struct vbe_mode_info *mode_info)
583#else
584int biosemu_run(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
585 BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
586 struct vbe_mode_info *mode_info)
587#endif
588{
589
590 if (!PCI_postController(pcidev, bios_rom, bios_len, vga_info,
591 vesa_mode, mode_info))
592 return -EINVAL;
593
594
595
596
597
598
599 if (clean_up) {
600 BE_exit();
601 if (vga_info->BIOSImage &&
602 (ulong)(vga_info->BIOSImage) != 0xc0000)
603 free(vga_info->BIOSImage);
604 free(vga_info);
605 vga_info = NULL;
606 }
607
608 return 0;
609}
610
611
612
613
614
615
616
617
618
619
620
621#ifdef CONFIG_DM_PCI
622int BootVideoCardBIOS(struct udevice *pcidev, BE_VGAInfo **pVGAInfo,
623 int clean_up)
624#else
625int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo, int clean_up)
626#endif
627{
628 BE_VGAInfo *VGAInfo;
629 int ret;
630
631 ret = biosemu_setup(pcidev, &VGAInfo);
632 if (ret)
633 return false;
634 ret = biosemu_run(pcidev, NULL, 0, VGAInfo, clean_up, -1, NULL);
635 if (ret)
636 return false;
637
638
639 if (pVGAInfo)
640 *pVGAInfo = VGAInfo;
641
642 return true;
643}
644