[coreboot] New patch to review for coreboot: 38860f7 Refactor option rom initialization code in coreboot.

Stefan Reinauer (stefan.reinauer@coreboot.org) gerrit at coreboot.org
Thu Oct 13 00:48:56 CEST 2011


Stefan Reinauer (stefan.reinauer at coreboot.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/255

-gerrit

commit 38860f7f936d58ca777a55dfc3c458feccfc0137
Author: Stefan Reinauer <reinauer at chromium.org>
Date:   Wed Oct 12 14:25:07 2011 -0700

    Refactor option rom initialization code in coreboot.
    
    - move int15 handler out of the generic code into the mainboard directories
      of those mainboards that actually use it.
    - move vbe headers to vbe.h
    - move function prototypes used in native oprom code to x86.h
    
    Change-Id: Idfff5e804ea328f7b5feebac72497c97329320ee
    Signed-off-by: Stefan Reinauer <reinauer at google.com>
---
 src/devices/oprom/include/vbe.h            |  112 +++++++++++++++++++++
 src/devices/oprom/x86.c                    |   93 +-----------------
 src/devices/oprom/x86.h                    |   48 +++++++++
 src/devices/oprom/x86_interrupts.c         |  150 +++++++++++++++------------
 src/devices/oprom/yabel/vbe.c              |   94 +-----------------
 src/mainboard/kontron/986lcd-m/mainboard.c |   50 +++++++++-
 src/mainboard/roda/rk886ex/mainboard.c     |   49 +++++++++-
 7 files changed, 343 insertions(+), 253 deletions(-)

diff --git a/src/devices/oprom/include/vbe.h b/src/devices/oprom/include/vbe.h
new file mode 100644
index 0000000..b87b0d5
--- /dev/null
+++ b/src/devices/oprom/include/vbe.h
@@ -0,0 +1,112 @@
+/******************************************************************************
+ * Copyright (c) 2004, 2008 IBM Corporation
+ * Copyright (c) 2009 Pattrick Hueper <phueper at hueper.net>
+ * All rights reserved.
+ * This program and the accompanying materials
+ * are made available under the terms of the BSD License
+ * which accompanies this distribution, and is available at
+ * http://www.opensource.org/licenses/bsd-license.php
+ *
+ * Contributors:
+ *     IBM Corporation - initial implementation
+ *****************************************************************************/
+
+// these structs are for input from and output to OF
+typedef struct {
+	u8 display_type;	// 0=NONE, 1= analog, 2=digital
+	u16 screen_width;
+	u16 screen_height;
+	u16 screen_linebytes;	// bytes per line in framebuffer, may be more than screen_width
+	u8 color_depth;	// color depth in bpp
+	u32 framebuffer_address;
+	u8 edid_block_zero[128];
+} __attribute__ ((__packed__)) screen_info_t;
+
+typedef struct {
+	u8 signature[4];
+	u16 size_reserved;
+	u8 monitor_number;
+	u16 max_screen_width;
+	u8 color_depth;
+} __attribute__ ((__packed__)) screen_info_input_t;
+
+// these structs only store a subset of the VBE defined fields
+// only those needed.
+typedef struct {
+	char signature[4];
+	u16 version;
+	u8 *oem_string_ptr;
+	u32 capabilities;
+	u16 video_mode_list[256];	// lets hope we never have more than 256 video modes...
+	u16 total_memory;
+} vbe_info_t;
+
+typedef struct {
+	u16 mode_attributes; // 00
+	u8 win_a_attributes; // 02
+	u8 win_b_attributes; // 03
+	u16 win_granularity; // 04
+	u16 win_size;        // 06
+	u16 win_a_segment;   // 08
+	u16 win_b_segment;   // 0a
+	u32 win_func_ptr;    // 0c
+	u16 bytes_per_scanline; // 10
+	u16 x_resolution;    // 12
+	u16 y_resolution;    // 14
+	u8 x_charsize;       // 16
+	u8 y_charsize;       // 17
+	u8 number_of_planes; // 18
+	u8 bits_per_pixel;   // 19
+	u8 number_of_banks;  // 20
+	u8 memory_model;     // 21
+	u8 bank_size;        // 22
+	u8 number_of_image_pages; // 23
+	u8 reserved_page;
+	u8 red_mask_size;
+	u8 red_mask_pos;
+	u8 green_mask_size;
+	u8 green_mask_pos;
+	u8 blue_mask_size;
+	u8 blue_mask_pos;
+	u8 reserved_mask_size;
+	u8 reserved_mask_pos;
+	u8 direct_color_mode_info;
+	u32 phys_base_ptr;
+	u32 offscreen_mem_offset;
+	u16 offscreen_mem_size;
+	u8 reserved[206];
+} __attribute__ ((__packed__)) vesa_mode_info_t;
+
+typedef struct {
+	u16 video_mode;
+	union {
+		vesa_mode_info_t vesa;
+		u8 mode_info_block[256];
+	};
+	// our crap
+	//u16 attributes;
+	//u16 linebytes;
+	//u16 x_resolution;
+	//u16 y_resolution;
+	//u8 x_charsize;
+	//u8 y_charsize;
+	//u8 bits_per_pixel;
+	//u8 memory_model;
+	//u32 framebuffer_address;
+} vbe_mode_info_t;
+
+typedef struct {
+	u8 port_number;	// i.e. monitor number
+	u8 edid_transfer_time;
+	u8 ddc_level;
+	u8 edid_block_zero[128];
+} vbe_ddc_info_t;
+
+struct lb_framebuffer;
+
+void vbe_set_graphics(void); // yabel only
+
+void fill_lb_framebuffer(struct lb_framebuffer *framebuffer);
+void vbe_textmode_console(void);
+
+
diff --git a/src/devices/oprom/x86.c b/src/devices/oprom/x86.c
index 37b45e6..9a6ce41 100644
--- a/src/devices/oprom/x86.c
+++ b/src/devices/oprom/x86.c
@@ -26,18 +26,7 @@
 #include <console/console.h>
 #include <arch/interrupt.h>
 
-#define REALMODE_BASE ((void *)0x600)
-
-struct realmode_idt {
-	u16 offset, cs;
-};
-
-void x86_exception(struct eregs *info);
-
-/* From x86_asm.S */
-extern unsigned char __idt_handler, __idt_handler_size;
-extern unsigned char __realmode_code, __realmode_code_size;
-extern unsigned char __realmode_call, __realmode_interrupt;
+#include "x86.h"
 
 void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
 		u32 esi, u32 edi) __attribute__((regparm(0))) = (void *)&__realmode_call;
@@ -45,10 +34,6 @@ void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
 void (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx, u32 edx, 
 		u32 esi, u32 edi) __attribute__((regparm(0))) = (void *)&__realmode_interrupt;
 
-#define FAKE_MEMORY_SIZE (1024*1024) // only 1MB
-#define INITIAL_EBDA_SEGMENT 0xF600
-#define INITIAL_EBDA_SIZE 0x400
-
 static void setup_bda(void)
 {
 	/* clear BIOS DATA AREA */
@@ -104,79 +89,6 @@ void mainboard_interrupt_handlers(int intXX, void *intXX_func)
 	intXX_handler[intXX] = intXX_func;
 }
 
-static int int10_handler(struct eregs *regs)
-{
-	int res=-1;
-	static u8 cursor_row=0, cursor_col=0;
-	switch((regs->eax & 0xff00)>>8) {
-	case 0x01: // Set cursor shape
-		res = 0;
-		break;
-	case 0x02: // Set cursor position
-		if (cursor_row != ((regs->edx >> 8) & 0xff) ||
-		    cursor_col >= (regs->edx & 0xff)) {
-			printk(BIOS_INFO, "\n");
-		}
-		cursor_row = (regs->edx >> 8) & 0xff;
-		cursor_col = regs->edx & 0xff;
-		res = 0;
-		break;
-	case 0x03: // Get cursor position
-		regs->eax &= 0x00ff;
-		regs->ecx = 0x0607;
-		regs->edx = (cursor_row << 8) | cursor_col;
-		res = 0;
-		break;
-	case 0x06: // Scroll up
-		printk(BIOS_INFO, "\n");
-		res = 0;
-		break;
-	case 0x08: // Get Character and Mode at Cursor Position
-		regs->eax = 0x0f00 | 'A'; // White on black 'A'
-		res = 0;
-		break;
-	case 0x09: // Write Character and attribute
-	case 0x10: // Write Character
-		printk(BIOS_INFO, "%c", regs->eax & 0xff);
-		res = 0;
-		break;
-	case 0x0f: // Get video mode
-		regs->eax = 0x5002; //80x25
-		regs->ebx &= 0x00ff;
-		res = 0;
-		break;
-        default:
-		printk(BIOS_WARNING, "Unknown INT10 function %04x!\n",
-				regs->eax & 0xffff);
-		break;
-	}
-	return res;
-}
-
-static int int16_handler(struct eregs *regs)
-{
-	int res=-1;
-	switch((regs->eax & 0xff00)>>8) {
-	case 0x00: // Check for Keystroke
-		regs->eax = 0x6120; // Space Bar, Space
-		res = 0;
-		break;
-	case 0x01: // Check for Keystroke
-		regs->eflags |= 1<<6; // Zero Flag set (no key available)
-		res = 0;
-		break;
-        default:
-		printk(BIOS_WARNING, "Unknown INT16 function %04x!\n",
-				regs->eax & 0xffff);
-		break;
-	}
-	return res;
-}
-
-int int12_handler(struct eregs *regs);
-int int15_handler(struct eregs *regs);
-int int1a_handler(struct eregs *regs);
-
 static void setup_interrupt_handlers(void)
 {
 	int i;
@@ -206,9 +118,6 @@ static void setup_interrupt_handlers(void)
 			case 0x12:
 				intXX_handler[0x12] = &int12_handler;
 				break;
-			case 0x15:
-				intXX_handler[0x15] = &int15_handler;
-				break;
 			case 0x16:
 				intXX_handler[0x16] = &int16_handler;
 				break;
diff --git a/src/devices/oprom/x86.h b/src/devices/oprom/x86.h
new file mode 100644
index 0000000..0bc2412
--- /dev/null
+++ b/src/devices/oprom/x86.h
@@ -0,0 +1,48 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007 Advanced Micro Devices, Inc.
+ * Copyright (C) 2009-2010 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#define REALMODE_BASE ((void *)0x600)
+
+struct realmode_idt {
+	u16 offset, cs;
+};
+
+void x86_exception(struct eregs *info);
+
+/* From x86_asm.S */
+extern unsigned char __idt_handler, __idt_handler_size;
+extern unsigned char __realmode_code, __realmode_code_size;
+extern unsigned char __realmode_call, __realmode_interrupt;
+
+extern void (*realmode_call)(u32 addr, u32 eax, u32 ebx, u32 ecx, u32 edx,
+		u32 esi, u32 edi) __attribute__((regparm(0)));
+
+extern void (*realmode_interrupt)(u32 intno, u32 eax, u32 ebx, u32 ecx, u32 edx,
+		u32 esi, u32 edi) __attribute__((regparm(0)));
+
+#define FAKE_MEMORY_SIZE (1024*1024) // only 1MB
+#define INITIAL_EBDA_SEGMENT 0xF600
+#define INITIAL_EBDA_SIZE 0x400
+
+int int10_handler(struct eregs *regs);
+int int12_handler(struct eregs *regs);
+int int16_handler(struct eregs *regs);
+int int1a_handler(struct eregs *regs);
+
diff --git a/src/devices/oprom/x86_interrupts.c b/src/devices/oprom/x86_interrupts.c
index 1dd645b..86d20d7 100644
--- a/src/devices/oprom/x86_interrupts.c
+++ b/src/devices/oprom/x86_interrupts.c
@@ -26,17 +26,7 @@
 #include <console/console.h>
 #include <arch/io.h>
 #include <arch/registers.h>
-
-enum {
-	PCIBIOS_CHECK = 0xb101,
-	PCIBIOS_FINDDEV = 0xb102,
-	PCIBIOS_READCONFBYTE = 0xb108,
-	PCIBIOS_READCONFWORD = 0xb109,
-	PCIBIOS_READCONFDWORD = 0xb10a,
-	PCIBIOS_WRITECONFBYTE = 0xb10b,
-	PCIBIOS_WRITECONFWORD = 0xb10c,
-	PCIBIOS_WRITECONFDWORD = 0xb10d
-};
+#include "x86.h"
 
 // errors go in AH. Just set these up so that word assigns
 // will work. KISS.
@@ -48,9 +38,54 @@ enum {
 	PCIBIOS_BADREG = 0x8700
 };
 
-int int12_handler(struct eregs *regs);
-int int1a_handler(struct eregs *regs);
-int int15_handler(struct eregs *regs);
+int int10_handler(struct eregs *regs)
+{
+	int res=-1;
+	static u8 cursor_row=0, cursor_col=0;
+	switch((regs->eax & 0xff00)>>8) {
+	case 0x01: // Set cursor shape
+		res = 0;
+		break;
+	case 0x02: // Set cursor position
+		if (cursor_row != ((regs->edx >> 8) & 0xff) ||
+		    cursor_col >= (regs->edx & 0xff)) {
+			printk(BIOS_INFO, "\n");
+		}
+		cursor_row = (regs->edx >> 8) & 0xff;
+		cursor_col = regs->edx & 0xff;
+		res = 0;
+		break;
+	case 0x03: // Get cursor position
+		regs->eax &= 0x00ff;
+		regs->ecx = 0x0607;
+		regs->edx = (cursor_row << 8) | cursor_col;
+		res = 0;
+		break;
+	case 0x06: // Scroll up
+		printk(BIOS_INFO, "\n");
+		res = 0;
+		break;
+	case 0x08: // Get Character and Mode at Cursor Position
+		regs->eax = 0x0f00 | 'A'; // White on black 'A'
+		res = 0;
+		break;
+	case 0x09: // Write Character and attribute
+	case 0x10: // Write Character
+		printk(BIOS_INFO, "%c", regs->eax & 0xff);
+		res = 0;
+		break;
+	case 0x0f: // Get video mode
+		regs->eax = 0x5002; //80x25
+		regs->ebx &= 0x00ff;
+		res = 0;
+		break;
+        default:
+		printk(BIOS_WARNING, "Unknown INT10 function %04x!\n",
+				regs->eax & 0xffff);
+		break;
+	}
+	return res;
+}
 
 int int12_handler(struct eregs *regs)
 {
@@ -58,6 +93,26 @@ int int12_handler(struct eregs *regs)
 	return 0;
 }
 
+int int16_handler(struct eregs *regs)
+{
+	int res=-1;
+	switch((regs->eax & 0xff00)>>8) {
+	case 0x00: // Check for Keystroke
+		regs->eax = 0x6120; // Space Bar, Space
+		res = 0;
+		break;
+	case 0x01: // Check for Keystroke
+		regs->eflags |= 1<<6; // Zero Flag set (no key available)
+		res = 0;
+		break;
+        default:
+		printk(BIOS_WARNING, "Unknown INT16 function %04x!\n",
+				regs->eax & 0xffff);
+		break;
+	}
+	return res;
+}
+
 #define PCI_CONFIG_SPACE_TYPE1	(1 << 0)
 #define PCI_CONFIG_SPACE_TYPE2	(1 << 1)
 #define PCI_SPECIAL_CYCLE_TYPE1	(1 << 4)
@@ -77,7 +132,7 @@ int int1a_handler(struct eregs *regs)
 	u8 byte, reg;
 
 	switch (func) {
-	case PCIBIOS_CHECK:
+	case 0xb101: /* PCIBIOS Check */
 		regs->edx = 0x20494350;	/* ' ICP' */
 		regs->eax &= 0xffff0000; /* Clear AH / AL */
 		regs->eax |= PCI_CONFIG_SPACE_TYPE1 | PCI_SPECIAL_CYCLE_TYPE1;
@@ -87,7 +142,7 @@ int int1a_handler(struct eregs *regs)
 		regs->edi = 0x00000000;	/* protected mode entry */
 		retval = 0;
 		break;
-	case PCIBIOS_FINDDEV:
+	case 0xb102: /* Find Device */
 		devid = regs->ecx;
 		vendorid = regs->edx;
 		devindex = regs->esi;
@@ -114,12 +169,12 @@ int int1a_handler(struct eregs *regs)
 			retval = -1;
 		}
 		break;
-	case PCIBIOS_READCONFDWORD:
-	case PCIBIOS_READCONFWORD:
-	case PCIBIOS_READCONFBYTE:
-	case PCIBIOS_WRITECONFDWORD:
-	case PCIBIOS_WRITECONFWORD:
-	case PCIBIOS_WRITECONFBYTE:
+	case 0xb10a: /* Read Config Dword */
+	case 0xb109: /* Read Config Word */
+	case 0xb108: /* Read Config Byte */
+	case 0xb10d: /* Write Config Dword */
+	case 0xb10c: /* Write Config Word */
+	case 0xb10b: /* Write Config Byte */
 		devfn = regs->ebx & 0xff;
 		bus = regs->ebx >> 8;
 		reg = regs->edi;
@@ -133,27 +188,27 @@ int int1a_handler(struct eregs *regs)
 			return retval;
 		}
 		switch (func) {
-		case PCIBIOS_READCONFBYTE:
+		case 0xb108: /* Read Config Byte */
 			byte = pci_read_config8(dev, reg);
 			regs->ecx = byte;
 			break;
-		case PCIBIOS_READCONFWORD:
+		case 0xb109: /* Read Config Word */
 			word = pci_read_config16(dev, reg);
 			regs->ecx = word;
 			break;
-		case PCIBIOS_READCONFDWORD:
+		case 0xb10a: /* Read Config Dword */
 			dword = pci_read_config32(dev, reg);
 			regs->ecx = dword;
 			break;
-		case PCIBIOS_WRITECONFBYTE:
+		case 0xb10b: /* Write Config Byte */
 			byte = regs->ecx;
 			pci_write_config8(dev, reg, byte);
 			break;
-		case PCIBIOS_WRITECONFWORD:
+		case 0xb10c: /* Write Config Word */
 			word = regs->ecx;
 			pci_write_config16(dev, reg, word);
 			break;
-		case PCIBIOS_WRITECONFDWORD:
+		case 0xb10d: /* Write Config Dword */
 			dword = regs->ecx;
 			pci_write_config32(dev, reg, dword);
 			break;
@@ -178,42 +233,3 @@ int int1a_handler(struct eregs *regs)
 	return retval;
 }
 
-int int15_handler(struct eregs *regs)
-{
-	int res = -1;
-
-	/* This int15 handler is Intel IGD. specific. Other chipsets need other
-	 * handlers. The right way to do this is to move this handler code into
-	 * the mainboard or northbridge code.
-	 * TODO: completely move to mainboards / chipsets.
-	 */
-	switch (regs->eax & 0xffff) {
-	/* And now Intel IGD code */
-#define BOOT_DISPLAY_DEFAULT    0
-#define BOOT_DISPLAY_CRT        (1 << 0)
-#define BOOT_DISPLAY_TV         (1 << 1)
-#define BOOT_DISPLAY_EFP        (1 << 2)
-#define BOOT_DISPLAY_LCD        (1 << 3)
-#define BOOT_DISPLAY_CRT2       (1 << 4)
-#define BOOT_DISPLAY_TV2        (1 << 5)
-#define BOOT_DISPLAY_EFP2       (1 << 6)
-#define BOOT_DISPLAY_LCD2       (1 << 7)
-	case 0x5f35:
-		regs->eax = 0x5f;
-		regs->ecx = BOOT_DISPLAY_DEFAULT;
-		res = 0;
-		break;
-	case 0x5f40:
-		regs->eax = 0x5f;
-		regs->ecx = 3; // This is mainboard specific
-		printk(BIOS_DEBUG, "DISPLAY=%x\n", regs->ecx);
-		res = 0;
-		break;
-	default:
-		printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n",
-				regs->eax & 0xffff);
-	}
-
-	return res;
-}
-
diff --git a/src/devices/oprom/yabel/vbe.c b/src/devices/oprom/yabel/vbe.c
index 75e8f3e..27bf5e6 100644
--- a/src/devices/oprom/yabel/vbe.c
+++ b/src/devices/oprom/yabel/vbe.c
@@ -31,13 +31,14 @@
 #include "mem.h"
 #include "interrupt.h"
 #include "device.h"
-#include "vbe.h"
 
 #include <cbfs.h>
 
 #include <delay.h>
 #include "../../src/lib/jpeg.h"
 
+#include <vbe.h>
+
 // pointer to VBEInfoBuffer, set by vbe_prepare
 u8 *vbe_info_buffer = 0;
 
@@ -45,97 +46,6 @@ u8 *vbe_info_buffer = 0;
 u8 *biosmem;
 u32 biosmem_size;
 
-// these structs are for input from and output to OF
-typedef struct {
-	u8 display_type;	// 0=NONE, 1= analog, 2=digital
-	u16 screen_width;
-	u16 screen_height;
-	u16 screen_linebytes;	// bytes per line in framebuffer, may be more than screen_width
-	u8 color_depth;	// color depth in bpp
-	u32 framebuffer_address;
-	u8 edid_block_zero[128];
-} __attribute__ ((__packed__)) screen_info_t;
-
-typedef struct {
-	u8 signature[4];
-	u16 size_reserved;
-	u8 monitor_number;
-	u16 max_screen_width;
-	u8 color_depth;
-} __attribute__ ((__packed__)) screen_info_input_t;
-
-// these structs only store a subset of the VBE defined fields
-// only those needed.
-typedef struct {
-	char signature[4];
-	u16 version;
-	u8 *oem_string_ptr;
-	u32 capabilities;
-	u16 video_mode_list[256];	// lets hope we never have more than 256 video modes...
-	u16 total_memory;
-} vbe_info_t;
-
-typedef struct {
-	u16 mode_attributes; // 00
-	u8 win_a_attributes; // 02
-	u8 win_b_attributes; // 03
-	u16 win_granularity; // 04
-	u16 win_size;        // 06
-	u16 win_a_segment;   // 08
-	u16 win_b_segment;   // 0a
-	u32 win_func_ptr;    // 0c
-	u16 bytes_per_scanline; // 10
-	u16 x_resolution;    // 12
-	u16 y_resolution;    // 14
-	u8 x_charsize;       // 16
-	u8 y_charsize;       // 17
-	u8 number_of_planes; // 18
-	u8 bits_per_pixel;   // 19
-	u8 number_of_banks;  // 20
-	u8 memory_model;     // 21
-	u8 bank_size;        // 22
-	u8 number_of_image_pages; // 23
-	u8 reserved_page;
-	u8 red_mask_size;
-	u8 red_mask_pos;
-	u8 green_mask_size;
-	u8 green_mask_pos;
-	u8 blue_mask_size;
-	u8 blue_mask_pos;
-	u8 reserved_mask_size;
-	u8 reserved_mask_pos;
-	u8 direct_color_mode_info;
-	u32 phys_base_ptr;
-	u32 offscreen_mem_offset;
-	u16 offscreen_mem_size;
-	u8 reserved[206];
-} __attribute__ ((__packed__)) vesa_mode_info_t;
-
-typedef struct {
-	u16 video_mode;
-	union {
-		vesa_mode_info_t vesa;
-		u8 mode_info_block[256];
-	};
-	// our crap
-	//u16 attributes;
-	//u16 linebytes;
-	//u16 x_resolution;
-	//u16 y_resolution;
-	//u8 x_charsize;
-	//u8 y_charsize;
-	//u8 bits_per_pixel;
-	//u8 memory_model;
-	//u32 framebuffer_address;
-} vbe_mode_info_t;
-
-typedef struct {
-	u8 port_number;	// i.e. monitor number
-	u8 edid_transfer_time;
-	u8 ddc_level;
-	u8 edid_block_zero[128];
-} vbe_ddc_info_t;
-
 static inline u8
 vbe_prepare(void)
 {
diff --git a/src/mainboard/kontron/986lcd-m/mainboard.c b/src/mainboard/kontron/986lcd-m/mainboard.c
index 1d0c494..d7b1f13 100644
--- a/src/mainboard/kontron/986lcd-m/mainboard.c
+++ b/src/mainboard/kontron/986lcd-m/mainboard.c
@@ -25,6 +25,7 @@
 #endif
 #include <pc80/mc146818rtc.h>
 #include <arch/io.h>
+#include <arch/interrupt.h>
 #include "chip.h"
 
 #if CONFIG_PCI_OPTION_ROM_RUN_YABEL
@@ -70,6 +71,53 @@ static void int15_install(void)
 }
 #endif
 
+#if defined(CONFIG_PCI_OPTION_ROM_RUN_REALMODE) && CONFIG_PCI_OPTION_ROM_RUN_REALMODE
+static int int15_handler(struct eregs *regs)
+{
+	int res = -1;
+
+	/* This int15 handler is Intel IGD. specific. Other chipsets need other
+	 * handlers. The right way to do this is to move this handler code into
+	 * the mainboard or northbridge code.
+	 * TODO: completely move to mainboards / chipsets.
+	 */
+	switch (regs->eax & 0xffff) {
+	/* And now Intel IGD code */
+#define BOOT_DISPLAY_DEFAULT    0
+#define BOOT_DISPLAY_CRT        (1 << 0)
+#define BOOT_DISPLAY_TV         (1 << 1)
+#define BOOT_DISPLAY_EFP        (1 << 2)
+#define BOOT_DISPLAY_LCD        (1 << 3)
+#define BOOT_DISPLAY_CRT2       (1 << 4)
+#define BOOT_DISPLAY_TV2        (1 << 5)
+#define BOOT_DISPLAY_EFP2       (1 << 6)
+#define BOOT_DISPLAY_LCD2       (1 << 7)
+	case 0x5f35:
+		regs->eax = 0x5f;
+		regs->ecx = BOOT_DISPLAY_DEFAULT;
+		res = 0;
+		break;
+	case 0x5f40:
+		regs->eax = 0x5f;
+		regs->ecx = 3; // This is mainboard specific
+		printk(BIOS_DEBUG, "DISPLAY=%x\n", regs->ecx);
+		res = 0;
+		break;
+	default:
+		printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n",
+				regs->eax & 0xffff);
+	}
+
+	return res;
+}
+
+static void int15_install(void)
+{
+	mainboard_interrupt_handlers(0x15, &int15_handler);
+}
+#endif
+
+
 /* Hardware Monitor */
 
 static u16 hwm_base = 0xa00;
@@ -221,7 +269,7 @@ static void verb_setup(void)
 
 static void mainboard_enable(device_t dev)
 {
-#if CONFIG_PCI_OPTION_ROM_RUN_YABEL
+#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE
 	/* Install custom int15 handler for VGA OPROM */
 	int15_install();
 #endif
diff --git a/src/mainboard/roda/rk886ex/mainboard.c b/src/mainboard/roda/rk886ex/mainboard.c
index 2c5b5e3..d87d712 100644
--- a/src/mainboard/roda/rk886ex/mainboard.c
+++ b/src/mainboard/roda/rk886ex/mainboard.c
@@ -22,6 +22,7 @@
 #include <console/console.h>
 #include <device/device.h>
 #include <arch/io.h>
+#include <arch/interrupt.h>
 #include <boot/tables.h>
 #include <delay.h>
 #if CONFIG_PCI_OPTION_ROM_RUN_YABEL
@@ -99,6 +100,52 @@ static void int15_install(void)
 }
 #endif
 
+#if CONFIG_PCI_OPTION_ROM_RUN_REALMODE
+static int int15_handler(struct eregs *regs)
+{
+	int res = -1;
+
+	/* This int15 handler is Intel IGD. specific. Other chipsets need other
+	 * handlers. The right way to do this is to move this handler code into
+	 * the mainboard or northbridge code.
+	 * TODO: completely move to mainboards / chipsets.
+	 */
+	switch (regs->eax & 0xffff) {
+	/* And now Intel IGD code */
+#define BOOT_DISPLAY_DEFAULT    0
+#define BOOT_DISPLAY_CRT        (1 << 0)
+#define BOOT_DISPLAY_TV         (1 << 1)
+#define BOOT_DISPLAY_EFP        (1 << 2)
+#define BOOT_DISPLAY_LCD        (1 << 3)
+#define BOOT_DISPLAY_CRT2       (1 << 4)
+#define BOOT_DISPLAY_TV2        (1 << 5)
+#define BOOT_DISPLAY_EFP2       (1 << 6)
+#define BOOT_DISPLAY_LCD2       (1 << 7)
+	case 0x5f35:
+		regs->eax = 0x5f;
+		regs->ecx = BOOT_DISPLAY_DEFAULT;
+		res = 0;
+		break;
+	case 0x5f40:
+		regs->eax = 0x5f;
+		regs->ecx = 3; // This is mainboard specific
+		printk(BIOS_DEBUG, "DISPLAY=%x\n", regs->ecx);
+		res = 0;
+		break;
+	default:
+		printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n",
+				regs->eax & 0xffff);
+	}
+
+	return res;
+}
+
+static void int15_install(void)
+{
+	mainboard_interrupt_handlers(0x15, &int15_handler);
+}
+#endif
+
 #if DUMP_RUNTIME_REGISTERS
 static void dump_runtime_registers(void)
 {
@@ -125,7 +172,7 @@ static void mainboard_enable(device_t dev)
 	/* Disable Dummy DCC -> GP45 = 1 */
 	outb(inb(0x60f) | (1 << 5), 0x60f);
 
-#if CONFIG_PCI_OPTION_ROM_RUN_YABEL
+#if CONFIG_PCI_OPTION_ROM_RUN_YABEL || CONFIG_PCI_OPTION_ROM_RUN_REALMODE
 	/* Install custom int15 handler for VGA OPROM */
 	int15_install();
 #endif




More information about the coreboot mailing list