• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2 *
3 *		     Video BOOT Graphics Card POST Module
4 *
5 *  ========================================================================
6 *   Copyright (C) 2007 Freescale Semiconductor, Inc.
7 *   Jason Jin <Jason.jin@freescale.com>
8 *
9 *   Copyright (C) 1991-2004 SciTech Software, Inc. All rights reserved.
10 *
11 *   This file may be distributed and/or modified under the terms of the
12 *   GNU General Public License version 2.0 as published by the Free
13 *   Software Foundation and appearing in the file LICENSE.GPL included
14 *   in the packaging of this file.
15 *
16 *   Licensees holding a valid Commercial License for this product from
17 *   SciTech Software, Inc. may use this file in accordance with the
18 *   Commercial License Agreement provided with the Software.
19 *
20 *   This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING
21 *   THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 *   PURPOSE.
23 *
24 *   See http://www.scitechsoft.com/license/ for information about
25 *   the licensing options available and how to purchase a Commercial
26 *   License Agreement.
27 *
28 *   Contact license@scitechsoft.com if any conditions of this licensing
29 *   are not clear to you, or you have questions about licensing options.
30 *
31 *  ========================================================================
32 *
33 * Language:	ANSI C
34 * Environment:	Linux Kernel
35 * Developer:	Kendall Bennett
36 *
37 * Description:	Module to implement booting PCI/AGP controllers on the
38 *		bus. We use the x86 real mode emulator to run the BIOS on
39 *		graphics controllers to bring the cards up.
40 *
41 *		Note that at present this module does *not* support
42 *		multiple controllers.
43 *
44 *		The orignal name of this file is warmboot.c.
45 *		Jason ported this file to u-boot to run the ATI video card
46 *		BIOS in u-boot.
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 /* Length of the BIOS image */
56 #define MAX_BIOSLEN	    (128 * 1024L)
57 
58 /* Place to save PCI BAR's that we change and later restore */
59 static u32 saveROMBaseAddress;
60 static u32 saveBaseAddress10;
61 static u32 saveBaseAddress14;
62 static u32 saveBaseAddress18;
63 static u32 saveBaseAddress20;
64 
65 /* Addres im memory of VBE region */
66 const int vbe_offset = 0x2000;
67 
68 #ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
bios_ptr(const void * buf,BE_VGAInfo * vga_info,u32 x86_dword_ptr)69 static const void *bios_ptr(const void *buf, BE_VGAInfo *vga_info,
70 			    u32 x86_dword_ptr)
71 {
72 	u32 seg_ofs, flat;
73 
74 	seg_ofs = le32_to_cpu(x86_dword_ptr);
75 	flat = ((seg_ofs & 0xffff0000) >> 12) | (seg_ofs & 0xffff);
76 	if (flat >= 0xc0000)
77 		return vga_info->BIOSImage + flat - 0xc0000;
78 	else
79 		return buf + (flat - vbe_offset);
80 }
81 
atibios_debug_mode(BE_VGAInfo * vga_info,RMREGS * regs,int vesa_mode,struct vbe_mode_info * mode_info)82 static int atibios_debug_mode(BE_VGAInfo *vga_info, RMREGS *regs,
83 			      int vesa_mode, struct vbe_mode_info *mode_info)
84 {
85 	void *buffer = (void *)(M.mem_base + vbe_offset);
86 	u16 buffer_seg = (((unsigned long)vbe_offset) >> 4) & 0xff00;
87 	u16 buffer_adr = ((unsigned long)vbe_offset) & 0xffff;
88 	struct vesa_mode_info *vm;
89 	struct vbe_info *info;
90 	const u16 *modes_bios, *ptr;
91 	u16 *modes;
92 	int size;
93 
94 	debug("VBE: Getting information\n");
95 	regs->e.eax = VESA_GET_INFO;
96 	regs->e.esi = buffer_seg;
97 	regs->e.edi = buffer_adr;
98 	info = buffer;
99 	memset(info, '\0', sizeof(*info));
100 	strcpy(info->signature, "VBE2");
101 	BE_int86(0x10, regs, regs);
102 	if (regs->e.eax != 0x4f) {
103 		debug("VESA_GET_INFO: error %x\n", regs->e.eax);
104 		return -ENOSYS;
105 	}
106 	debug("version %x\n", le16_to_cpu(info->version));
107 	debug("oem '%s'\n", (char *)bios_ptr(buffer, vga_info,
108 					     info->oem_string_ptr));
109 	debug("vendor '%s'\n", (char *)bios_ptr(buffer, vga_info,
110 						info->vendor_name_ptr));
111 	debug("product '%s'\n", (char *)bios_ptr(buffer, vga_info,
112 						 info->product_name_ptr));
113 	debug("rev '%s'\n", (char *)bios_ptr(buffer, vga_info,
114 					     info->product_rev_ptr));
115 	modes_bios = bios_ptr(buffer, vga_info, info->modes_ptr);
116 	debug("Modes: ");
117 	for (ptr = modes_bios; *ptr != 0xffff; ptr++)
118 		debug("%x ", le16_to_cpu(*ptr));
119 	debug("\nmemory %dMB\n", le16_to_cpu(info->total_memory) >> 4);
120 	size = (ptr - modes_bios) * sizeof(u16) + 2;
121 	modes = malloc(size);
122 	if (!modes)
123 		return -ENOMEM;
124 	memcpy(modes, modes_bios, size);
125 
126 	regs->e.eax = VESA_GET_CUR_MODE;
127 	BE_int86(0x10, regs, regs);
128 	if (regs->e.eax != 0x4f) {
129 		debug("VESA_GET_CUR_MODE: error %x\n", regs->e.eax);
130 		return -ENOSYS;
131 	}
132 	debug("Current mode %x\n", regs->e.ebx);
133 
134 	for (ptr = modes; *ptr != 0xffff; ptr++) {
135 		int mode = le16_to_cpu(*ptr);
136 		bool linear_ok;
137 		int attr;
138 
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 
atibios_set_vesa_mode(RMREGS * regs,int vesa_mode,struct vbe_mode_info * mode_info)173 static 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 	/* request linear framebuffer mode and don't clear display */
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 #endif /* CONFIG_FRAMEBUFFER_SET_VESA_MODE */
219 
220 /****************************************************************************
221 PARAMETERS:
222 pcidev	- PCI device info for the video card on the bus to boot
223 vga_info - BIOS emulator VGA info structure
224 
225 REMARKS:
226 This function executes the BIOS POST code on the controller. We assume that
227 at this stage the controller has its I/O and memory space enabled and
228 that all other controllers are in a disabled state.
229 ****************************************************************************/
230 #ifdef CONFIG_DM_PCI
PCI_doBIOSPOST(struct udevice * pcidev,BE_VGAInfo * vga_info,int vesa_mode,struct vbe_mode_info * mode_info)231 static void PCI_doBIOSPOST(struct udevice *pcidev, BE_VGAInfo *vga_info,
232 			   int vesa_mode, struct vbe_mode_info *mode_info)
233 #else
234 static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo *vga_info,
235 			   int vesa_mode, struct vbe_mode_info *mode_info)
236 #endif
237 {
238 	RMREGS regs;
239 	RMSREGS sregs;
240 #ifdef CONFIG_DM_PCI
241 	pci_dev_t bdf;
242 #endif
243 
244 	/* Determine the value to store in AX for BIOS POST. Per the PCI specs,
245 	 AH must contain the bus and AL must contain the devfn, encoded as
246 	 (dev << 3) | fn
247 	 */
248 	memset(&regs, 0, sizeof(regs));
249 	memset(&sregs, 0, sizeof(sregs));
250 #ifdef CONFIG_DM_PCI
251 	bdf = dm_pci_get_bdf(pcidev);
252 	regs.x.ax = (int)PCI_BUS(bdf) << 8 |
253 			(int)PCI_DEV(bdf) << 3 | (int)PCI_FUNC(bdf);
254 #else
255 	regs.x.ax = ((int)PCI_BUS(pcidev) << 8) |
256 	    ((int)PCI_DEV(pcidev) << 3) | (int)PCI_FUNC(pcidev);
257 #endif
258 	/*Setup the X86 emulator for the VGA BIOS*/
259 	BE_setVGA(vga_info);
260 
261 	/*Execute the BIOS POST code*/
262 	BE_callRealMode(0xC000, 0x0003, &regs, &sregs);
263 
264 	/*Cleanup and exit*/
265 	BE_getVGA(vga_info);
266 
267 #ifdef CONFIG_FRAMEBUFFER_SET_VESA_MODE
268 	/* Useful for debugging */
269 	if (0)
270 		atibios_debug_mode(vga_info, &regs, vesa_mode, mode_info);
271 	if (vesa_mode != -1)
272 		atibios_set_vesa_mode(&regs, vesa_mode, mode_info);
273 #endif
274 }
275 
276 /****************************************************************************
277 PARAMETERS:
278 pcidev	- PCI device info for the video card on the bus
279 bar	- Place to return the base address register offset to use
280 
281 RETURNS:
282 The address to use to map the secondary BIOS (AGP devices)
283 
284 REMARKS:
285 Searches all the PCI base address registers for the device looking for a
286 memory mapping that is large enough to hold our ROM BIOS. We usually end up
287 finding the framebuffer mapping (usually BAR 0x10), and we use this mapping
288 to map the BIOS for the device into. We use a mapping that is already
289 assigned to the device to ensure the memory range will be passed through
290 by any PCI->PCI or AGP->PCI bridge that may be present.
291 
292 NOTE: Usually this function is only used for AGP devices, but it may be
293       used for PCI devices that have already been POST'ed and the BIOS
294       ROM base address has been zero'ed out.
295 
296 NOTE: This function leaves the original memory aperture disabled by leaving
297       it programmed to all 1's. It must be restored to the correct value
298       later.
299 ****************************************************************************/
300 #ifdef CONFIG_DM_PCI
PCI_findBIOSAddr(struct udevice * pcidev,int * bar)301 static u32 PCI_findBIOSAddr(struct udevice *pcidev, int *bar)
302 #else
303 static u32 PCI_findBIOSAddr(pci_dev_t pcidev, int *bar)
304 #endif
305 {
306 	u32 base, size;
307 
308 	for (*bar = 0x10; *bar <= 0x14; (*bar) += 4) {
309 #ifdef CONFIG_DM_PCI
310 		dm_pci_read_config32(pcidev, *bar, &base);
311 #else
312 		pci_read_config_dword(pcidev, *bar, &base);
313 #endif
314 		if (!(base & 0x1)) {
315 #ifdef CONFIG_DM_PCI
316 			dm_pci_write_config32(pcidev, *bar, 0xFFFFFFFF);
317 			dm_pci_read_config32(pcidev, *bar, &size);
318 #else
319 			pci_write_config_dword(pcidev, *bar, 0xFFFFFFFF);
320 			pci_read_config_dword(pcidev, *bar, &size);
321 #endif
322 			size = ~(size & ~0xFF) + 1;
323 			if (size >= MAX_BIOSLEN)
324 				return base & ~0xFF;
325 		}
326 	}
327 	return 0;
328 }
329 
330 /****************************************************************************
331 REMARKS:
332 Some non-x86 Linux kernels map PCI relocateable I/O to values that
333 are above 64K, which will not work with the BIOS image that requires
334 the offset for the I/O ports to be a maximum of 16-bits. Ideally
335 someone should fix the kernel to map the I/O ports for VGA compatible
336 devices to a different location (or just all I/O ports since it is
337 unlikely you can have enough devices in the machine to use up all
338 64K of the I/O space - a total of more than 256 cards would be
339 necessary).
340 
341 Anyway to fix this we change all I/O mapped base registers and
342 chop off the top bits.
343 ****************************************************************************/
344 #ifdef CONFIG_DM_PCI
PCI_fixupIObase(struct udevice * pcidev,int reg,u32 * base)345 static void PCI_fixupIObase(struct udevice *pcidev, int reg, u32 *base)
346 #else
347 static void PCI_fixupIObase(pci_dev_t pcidev, int reg, u32 * base)
348 #endif
349 {
350 	if ((*base & 0x1) && (*base > 0xFFFE)) {
351 		*base &= 0xFFFF;
352 #ifdef CONFIG_DM_PCI
353 		dm_pci_write_config32(pcidev, reg, *base);
354 #else
355 		pci_write_config_dword(pcidev, reg, *base);
356 #endif
357 
358 	}
359 }
360 
361 /****************************************************************************
362 PARAMETERS:
363 pcidev	- PCI device info for the video card on the bus
364 
365 RETURNS:
366 Pointers to the mapped BIOS image
367 
368 REMARKS:
369 Maps a pointer to the BIOS image on the graphics card on the PCI bus.
370 ****************************************************************************/
371 #ifdef CONFIG_DM_PCI
PCI_mapBIOSImage(struct udevice * pcidev)372 void *PCI_mapBIOSImage(struct udevice *pcidev)
373 #else
374 void *PCI_mapBIOSImage(pci_dev_t pcidev)
375 #endif
376 {
377 	u32 BIOSImageBus;
378 	int BIOSImageBAR;
379 	u8 *BIOSImage;
380 
381 	/*Save PCI BAR registers that might get changed*/
382 #ifdef CONFIG_DM_PCI
383 	dm_pci_read_config32(pcidev, PCI_ROM_ADDRESS, &saveROMBaseAddress);
384 	dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_0, &saveBaseAddress10);
385 	dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
386 	dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_2, &saveBaseAddress18);
387 	dm_pci_read_config32(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
388 #else
389 	pci_read_config_dword(pcidev, PCI_ROM_ADDRESS, &saveROMBaseAddress);
390 	pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_0, &saveBaseAddress10);
391 	pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
392 	pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_2, &saveBaseAddress18);
393 	pci_read_config_dword(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
394 #endif
395 
396 	/*Fix up I/O base registers to less than 64K */
397 	if(saveBaseAddress14 != 0)
398 		PCI_fixupIObase(pcidev, PCI_BASE_ADDRESS_1, &saveBaseAddress14);
399 	else
400 		PCI_fixupIObase(pcidev, PCI_BASE_ADDRESS_4, &saveBaseAddress20);
401 
402 	/* Some cards have problems that stop us from being able to read the
403 	 BIOS image from the ROM BAR. To fix this we have to do some chipset
404 	 specific programming for different cards to solve this problem.
405 	*/
406 
407 	BIOSImageBus = PCI_findBIOSAddr(pcidev, &BIOSImageBAR);
408 	if (BIOSImageBus == 0) {
409 		printf("Find bios addr error\n");
410 		return NULL;
411 	}
412 
413 #ifdef CONFIG_DM_PCI
414 	BIOSImage = dm_pci_bus_to_virt(pcidev, BIOSImageBus,
415 				       PCI_REGION_MEM, 0, MAP_NOCACHE);
416 
417 	/*Change the PCI BAR registers to map it onto the bus.*/
418 	dm_pci_write_config32(pcidev, BIOSImageBAR, 0);
419 	dm_pci_write_config32(pcidev, PCI_ROM_ADDRESS, BIOSImageBus | 0x1);
420 #else
421 	BIOSImage = pci_bus_to_virt(pcidev, BIOSImageBus,
422 				    PCI_REGION_MEM, 0, MAP_NOCACHE);
423 
424 	/*Change the PCI BAR registers to map it onto the bus.*/
425 	pci_write_config_dword(pcidev, BIOSImageBAR, 0);
426 	pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, BIOSImageBus | 0x1);
427 #endif
428 	udelay(1);
429 
430 	/*Check that the BIOS image is valid. If not fail, or return the
431 	 compiled in BIOS image if that option was enabled
432 	 */
433 	if (BIOSImage[0] != 0x55 || BIOSImage[1] != 0xAA || BIOSImage[2] == 0) {
434 		return NULL;
435 	}
436 
437 	return BIOSImage;
438 }
439 
440 /****************************************************************************
441 PARAMETERS:
442 pcidev	- PCI device info for the video card on the bus
443 
444 REMARKS:
445 Unmaps the BIOS image for the device and restores framebuffer mappings
446 ****************************************************************************/
447 #ifdef CONFIG_DM_PCI
PCI_unmapBIOSImage(struct udevice * pcidev,void * BIOSImage)448 void PCI_unmapBIOSImage(struct udevice *pcidev, void *BIOSImage)
449 {
450 	dm_pci_write_config32(pcidev, PCI_ROM_ADDRESS, saveROMBaseAddress);
451 	dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_0, saveBaseAddress10);
452 	dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_1, saveBaseAddress14);
453 	dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_2, saveBaseAddress18);
454 	dm_pci_write_config32(pcidev, PCI_BASE_ADDRESS_4, saveBaseAddress20);
455 }
456 #else
PCI_unmapBIOSImage(pci_dev_t pcidev,void * BIOSImage)457 void PCI_unmapBIOSImage(pci_dev_t pcidev, void *BIOSImage)
458 {
459 	pci_write_config_dword(pcidev, PCI_ROM_ADDRESS, saveROMBaseAddress);
460 	pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_0, saveBaseAddress10);
461 	pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_1, saveBaseAddress14);
462 	pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_2, saveBaseAddress18);
463 	pci_write_config_dword(pcidev, PCI_BASE_ADDRESS_4, saveBaseAddress20);
464 }
465 #endif
466 
467 /****************************************************************************
468 PARAMETERS:
469 pcidev	- PCI device info for the video card on the bus to boot
470 VGAInfo - BIOS emulator VGA info structure
471 
472 RETURNS:
473 true if successfully initialised, false if not.
474 
475 REMARKS:
476 Loads and POST's the display controllers BIOS, directly from the BIOS
477 image we can extract over the PCI bus.
478 ****************************************************************************/
479 #ifdef CONFIG_DM_PCI
PCI_postController(struct udevice * pcidev,uchar * bios_rom,int bios_len,BE_VGAInfo * vga_info,int vesa_mode,struct vbe_mode_info * mode_info)480 static int PCI_postController(struct udevice *pcidev, uchar *bios_rom,
481 			      int bios_len, BE_VGAInfo *vga_info,
482 			      int vesa_mode, struct vbe_mode_info *mode_info)
483 #else
484 static int PCI_postController(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
485 			      BE_VGAInfo *vga_info, int vesa_mode,
486 			      struct vbe_mode_info *mode_info)
487 #endif
488 {
489 	u32 bios_image_len;
490 	uchar *mapped_bios;
491 	uchar *copy_of_bios;
492 #ifdef CONFIG_DM_PCI
493 	pci_dev_t bdf;
494 #endif
495 
496 	if (bios_rom) {
497 		copy_of_bios = bios_rom;
498 		bios_image_len = bios_len;
499 	} else {
500 		/*
501 		 * Allocate memory to store copy of BIOS from display
502 		 * controller
503 		 */
504 		mapped_bios = PCI_mapBIOSImage(pcidev);
505 		if (mapped_bios == NULL) {
506 			printf("videoboot: Video ROM failed to map!\n");
507 			return false;
508 		}
509 
510 		bios_image_len = mapped_bios[2] * 512;
511 
512 		copy_of_bios = malloc(bios_image_len);
513 		if (copy_of_bios == NULL) {
514 			printf("videoboot: Out of memory!\n");
515 			return false;
516 		}
517 		memcpy(copy_of_bios, mapped_bios, bios_image_len);
518 		PCI_unmapBIOSImage(pcidev, mapped_bios);
519 	}
520 
521 	/*Save information in vga_info structure*/
522 #ifdef CONFIG_DM_PCI
523 	bdf = dm_pci_get_bdf(pcidev);
524 	vga_info->function = PCI_FUNC(bdf);
525 	vga_info->device = PCI_DEV(bdf);
526 	vga_info->bus = PCI_BUS(bdf);
527 #else
528 	vga_info->function = PCI_FUNC(pcidev);
529 	vga_info->device = PCI_DEV(pcidev);
530 	vga_info->bus = PCI_BUS(pcidev);
531 #endif
532 	vga_info->pcidev = pcidev;
533 	vga_info->BIOSImage = copy_of_bios;
534 	vga_info->BIOSImageLen = bios_image_len;
535 
536 	/*Now execute the BIOS POST for the device*/
537 	if (copy_of_bios[0] != 0x55 || copy_of_bios[1] != 0xAA) {
538 		printf("videoboot: Video ROM image is invalid!\n");
539 		return false;
540 	}
541 
542 	PCI_doBIOSPOST(pcidev, vga_info, vesa_mode, mode_info);
543 
544 	/*Reset the size of the BIOS image to the final size*/
545 	vga_info->BIOSImageLen = copy_of_bios[2] * 512;
546 	return true;
547 }
548 
549 #ifdef CONFIG_DM_PCI
biosemu_setup(struct udevice * pcidev,BE_VGAInfo ** vga_infop)550 int biosemu_setup(struct udevice *pcidev, BE_VGAInfo **vga_infop)
551 #else
552 int biosemu_setup(pci_dev_t pcidev, BE_VGAInfo **vga_infop)
553 #endif
554 {
555 	BE_VGAInfo *VGAInfo;
556 #ifdef CONFIG_DM_PCI
557 	pci_dev_t bdf = dm_pci_get_bdf(pcidev);
558 
559 	printf("videoboot: Booting PCI video card bus %d, function %d, device %d\n",
560 	       PCI_BUS(bdf), PCI_FUNC(bdf), PCI_DEV(bdf));
561 #else
562 	printf("videoboot: Booting PCI video card bus %d, function %d, device %d\n",
563 	       PCI_BUS(pcidev), PCI_FUNC(pcidev), PCI_DEV(pcidev));
564 #endif
565 	/*Initialise the x86 BIOS emulator*/
566 	if ((VGAInfo = malloc(sizeof(*VGAInfo))) == NULL) {
567 		printf("videoboot: Out of memory!\n");
568 		return -ENOMEM;
569 	}
570 	memset(VGAInfo, 0, sizeof(*VGAInfo));
571 	BE_init(0, 65536, VGAInfo, 0);
572 	*vga_infop = VGAInfo;
573 
574 	return 0;
575 }
576 
biosemu_set_interrupt_handler(int intnum,int (* int_func)(void))577 void biosemu_set_interrupt_handler(int intnum, int (*int_func)(void))
578 {
579 	X86EMU_setupIntrFunc(intnum, (X86EMU_intrFuncs)int_func);
580 }
581 
582 #ifdef CONFIG_DM_PCI
biosemu_run(struct udevice * pcidev,uchar * bios_rom,int bios_len,BE_VGAInfo * vga_info,int clean_up,int vesa_mode,struct vbe_mode_info * mode_info)583 int biosemu_run(struct udevice *pcidev, uchar *bios_rom, int bios_len,
584 		BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
585 		struct vbe_mode_info *mode_info)
586 #else
587 int biosemu_run(pci_dev_t pcidev, uchar *bios_rom, int bios_len,
588 		BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
589 		struct vbe_mode_info *mode_info)
590 #endif
591 {
592 	/*Post all the display controller BIOS'es*/
593 	if (!PCI_postController(pcidev, bios_rom, bios_len, vga_info,
594 				vesa_mode, mode_info))
595 		return -EINVAL;
596 
597 	/*
598 	 * Cleanup and exit the emulator if requested. If the BIOS emulator
599 	 * is needed after booting the card, we will not call BE_exit and
600 	 * leave it enabled for further use (ie: VESA driver etc).
601 	*/
602 	if (clean_up) {
603 		BE_exit();
604 		if (vga_info->BIOSImage &&
605 		    (ulong)(vga_info->BIOSImage) != 0xc0000)
606 			free(vga_info->BIOSImage);
607 		free(vga_info);
608 	}
609 
610 	return 0;
611 }
612 
613 /****************************************************************************
614 PARAMETERS:
615 pcidev	    - PCI device info for the video card on the bus to boot
616 pVGAInfo    - Place to return VGA info structure is requested
617 cleanUp	    - true to clean up on exit, false to leave emulator active
618 
619 REMARKS:
620 Boots the PCI/AGP video card on the bus using the Video ROM BIOS image
621 and the X86 BIOS emulator module.
622 ****************************************************************************/
623 #ifdef CONFIG_DM_PCI
BootVideoCardBIOS(struct udevice * pcidev,BE_VGAInfo ** pVGAInfo,int clean_up)624 int BootVideoCardBIOS(struct udevice *pcidev, BE_VGAInfo **pVGAInfo,
625 		      int clean_up)
626 #else
627 int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo **pVGAInfo, int clean_up)
628 #endif
629 {
630 	BE_VGAInfo *VGAInfo;
631 	int ret;
632 
633 	ret = biosemu_setup(pcidev, &VGAInfo);
634 	if (ret)
635 		return false;
636 	ret = biosemu_run(pcidev, NULL, 0, VGAInfo, clean_up, -1, NULL);
637 	if (ret)
638 		return false;
639 
640 	/* Return VGA info pointer if the caller requested it*/
641 	if (pVGAInfo)
642 		*pVGAInfo = VGAInfo;
643 
644 	return true;
645 }
646