2 * This file is part of the coreboot project.
4 * Copyright (C) 2001 Ronald G. Minnich
5 * Copyright (C) 2005 Nick.Barker9@btinternet.com
6 * Copyright (C) 2007-2009 coresystems GmbH
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
19 #include <arch/registers.h>
20 #include <console/console.h>
21 #include <device/pci.h>
22 #include <device/pci_ids.h>
23 #include <device/pci_ops.h>
26 /* we use x86emu's register file representation */
27 #include <x86emu/regs.h>
31 // errors go in AH. Just set these up so that word assigns
34 PCIBIOS_SUCCESSFUL
= 0x0000,
35 PCIBIOS_UNSUPPORTED
= 0x8100,
36 PCIBIOS_BADVENDOR
= 0x8300,
37 PCIBIOS_NODEV
= 0x8600,
38 PCIBIOS_BADREG
= 0x8700
41 int int10_handler(void)
44 static u8 cursor_row
=0, cursor_col
=0;
45 switch((X86_EAX
& 0xff00)>>8) {
46 case 0x01: // Set cursor shape
49 case 0x02: // Set cursor position
50 if (cursor_row
!= ((X86_EDX
>> 8) & 0xff) ||
51 cursor_col
>= (X86_EDX
& 0xff)) {
52 printk(BIOS_INFO
, "\n");
54 cursor_row
= (X86_EDX
>> 8) & 0xff;
55 cursor_col
= X86_EDX
& 0xff;
58 case 0x03: // Get cursor position
61 X86_EDX
= (cursor_row
<< 8) | cursor_col
;
64 case 0x06: // Scroll up
65 printk(BIOS_INFO
, "\n");
68 case 0x08: // Get Character and Mode at Cursor Position
69 X86_EAX
= 0x0f00 | 'A'; // White on black 'A'
72 case 0x09: // Write Character and attribute
73 case 0x0e: // Write Character
74 printk(BIOS_INFO
, "%c", X86_EAX
& 0xff);
77 case 0x0f: // Get video mode
78 X86_EAX
= 0x5002; //80x25
83 printk(BIOS_WARNING
, "Unknown INT10 function %04x!\n",
90 int int12_handler(void)
96 int int16_handler(void)
99 switch((X86_EAX
& 0xff00)>>8) {
100 case 0x00: // Check for Keystroke
101 X86_EAX
= 0x6120; // Space Bar, Space
104 case 0x01: // Check for Keystroke
105 X86_EFLAGS
|= 1<<6; // Zero Flag set (no key available)
109 printk(BIOS_WARNING
, "Unknown INT16 function %04x!\n",
116 #define PCI_CONFIG_SPACE_TYPE1 (1 << 0)
117 #define PCI_SPECIAL_CYCLE_TYPE1 (1 << 4)
119 int int1a_handler(void)
121 unsigned short func
= (unsigned short)X86_EAX
;
123 unsigned short devid
, vendorid
, devfn
;
124 /* Use short to get rid of garbage in upper half of 32-bit register */
133 case 0xb101: /* PCIBIOS Check */
134 X86_EDX
= 0x20494350; /* ' ICP' */
135 X86_EAX
&= 0xffff0000; /* Clear AH / AL */
136 X86_EAX
|= PCI_CONFIG_SPACE_TYPE1
| PCI_SPECIAL_CYCLE_TYPE1
;
137 // last bus in the system. Hard code to 255 for now.
138 // dev_enumerate() does not seem to tell us (publicly)
140 X86_EDI
= 0x00000000; /* protected mode entry */
143 case 0xb102: /* Find Device */
148 while ((dev
= dev_find_device(vendorid
, devid
, dev
))) {
154 unsigned short busdevfn
;
155 X86_EAX
&= 0xffff00ff; /* Clear AH */
156 X86_EAX
|= PCIBIOS_SUCCESSFUL
;
157 // busnum is an unsigned char;
158 // devfn is an int, so we mask it off.
159 busdevfn
= (dev
->bus
->secondary
<< 8)
160 | (dev
->path
.pci
.devfn
& 0xff);
161 printk(BIOS_DEBUG
, "0x%x: return 0x%x\n", func
, busdevfn
);
165 X86_EAX
&= 0xffff00ff; /* Clear AH */
166 X86_EAX
|= PCIBIOS_NODEV
;
170 case 0xb10a: /* Read Config Dword */
171 case 0xb109: /* Read Config Word */
172 case 0xb108: /* Read Config Byte */
173 case 0xb10d: /* Write Config Dword */
174 case 0xb10c: /* Write Config Word */
175 case 0xb10b: /* Write Config Byte */
176 devfn
= X86_EBX
& 0xff;
179 dev
= dev_find_slot(bus
, devfn
);
181 printk(BIOS_DEBUG
, "0x%x: BAD DEVICE bus %d devfn 0x%x\n", func
, bus
, devfn
);
182 // Or are we supposed to return PCIBIOS_NODEV?
183 X86_EAX
&= 0xffff00ff; /* Clear AH */
184 X86_EAX
|= PCIBIOS_BADREG
;
189 case 0xb108: /* Read Config Byte */
190 byte
= pci_read_config8(dev
, reg
);
193 case 0xb109: /* Read Config Word */
194 word
= pci_read_config16(dev
, reg
);
197 case 0xb10a: /* Read Config Dword */
198 dword
= pci_read_config32(dev
, reg
);
201 case 0xb10b: /* Write Config Byte */
203 pci_write_config8(dev
, reg
, byte
);
205 case 0xb10c: /* Write Config Word */
207 pci_write_config16(dev
, reg
, word
);
209 case 0xb10d: /* Write Config Dword */
211 pci_write_config32(dev
, reg
, dword
);
215 #if CONFIG_REALMODE_DEBUG
216 printk(BIOS_DEBUG
, "0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n",
217 func
, bus
, devfn
, reg
, X86_ECX
);
219 X86_EAX
&= 0xffff00ff; /* Clear AH */
220 X86_EAX
|= PCIBIOS_SUCCESSFUL
;
224 printk(BIOS_ERR
, "UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func
);
225 X86_EAX
&= 0xffff00ff; /* Clear AH */
226 X86_EAX
|= PCIBIOS_UNSUPPORTED
;