1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <arch/registers.h>
4 #include <console/console.h>
5 #include <device/pci.h>
6 #include <device/pci_ops.h>
8 /* we use x86emu's register file representation */
9 #include <x86emu/regs.h>
13 // errors go in AH. Just set these up so that word assigns
16 PCIBIOS_SUCCESSFUL
= 0x0000,
17 PCIBIOS_UNSUPPORTED
= 0x8100,
18 PCIBIOS_BADVENDOR
= 0x8300,
19 PCIBIOS_NODEV
= 0x8600,
20 PCIBIOS_BADREG
= 0x8700
23 int int10_handler(void)
26 static u8 cursor_row
=0, cursor_col
=0;
27 switch((X86_EAX
& 0xff00)>>8) {
28 case 0x01: // Set cursor shape
31 case 0x02: // Set cursor position
32 if (cursor_row
!= ((X86_EDX
>> 8) & 0xff) ||
33 cursor_col
>= (X86_EDX
& 0xff)) {
34 printk(BIOS_INFO
, "\n");
36 cursor_row
= (X86_EDX
>> 8) & 0xff;
37 cursor_col
= X86_EDX
& 0xff;
40 case 0x03: // Get cursor position
43 X86_EDX
= (cursor_row
<< 8) | cursor_col
;
46 case 0x06: // Scroll up
47 printk(BIOS_INFO
, "\n");
50 case 0x08: // Get Character and Mode at Cursor Position
51 X86_EAX
= 0x0f00 | 'A'; // White on black 'A'
54 case 0x09: // Write Character and attribute
55 case 0x0e: // Write Character
56 printk(BIOS_INFO
, "%c", X86_EAX
& 0xff);
59 case 0x0f: // Get video mode
60 X86_EAX
= 0x5002; //80x25
65 printk(BIOS_WARNING
, "Unknown INT10 function %04x!\n",
72 int int12_handler(void)
78 int int16_handler(void)
81 switch((X86_EAX
& 0xff00)>>8) {
82 case 0x00: // Check for Keystroke
83 X86_EAX
= 0x6120; // Space Bar, Space
86 case 0x01: // Check for Keystroke
87 X86_EFLAGS
|= 1<<6; // Zero Flag set (no key available)
91 printk(BIOS_WARNING
, "Unknown INT16 function %04x!\n",
98 #define PCI_CONFIG_SPACE_TYPE1 (1 << 0)
99 #define PCI_SPECIAL_CYCLE_TYPE1 (1 << 4)
101 int int1a_handler(void)
103 unsigned short func
= (unsigned short)X86_EAX
;
105 unsigned short devid
, vendorid
, devfn
;
106 /* Use short to get rid of garbage in upper half of 32-bit register */
115 case 0xb101: /* PCIBIOS Check */
116 X86_EDX
= 0x20494350; /* ' ICP' */
117 X86_EAX
&= 0xffff0000; /* Clear AH / AL */
118 X86_EAX
|= PCI_CONFIG_SPACE_TYPE1
| PCI_SPECIAL_CYCLE_TYPE1
;
119 // last bus in the system. Hard code to 255 for now.
120 // dev_enumerate() does not seem to tell us (publicly)
122 X86_EDI
= 0x00000000; /* protected mode entry */
125 case 0xb102: /* Find Device */
130 while ((dev
= dev_find_device(vendorid
, devid
, dev
))) {
136 unsigned short busdevfn
;
137 X86_EAX
&= 0xffff00ff; /* Clear AH */
138 X86_EAX
|= PCIBIOS_SUCCESSFUL
;
139 // busnum is an unsigned char;
140 // devfn is an int, so we mask it off.
141 busdevfn
= (dev
->bus
->secondary
<< 8)
142 | (dev
->path
.pci
.devfn
& 0xff);
143 printk(BIOS_DEBUG
, "0x%x: return 0x%x\n", func
, busdevfn
);
147 X86_EAX
&= 0xffff00ff; /* Clear AH */
148 X86_EAX
|= PCIBIOS_NODEV
;
152 case 0xb10a: /* Read Config Dword */
153 case 0xb109: /* Read Config Word */
154 case 0xb108: /* Read Config Byte */
155 case 0xb10d: /* Write Config Dword */
156 case 0xb10c: /* Write Config Word */
157 case 0xb10b: /* Write Config Byte */
158 devfn
= X86_EBX
& 0xff;
161 dev
= pcidev_path_on_bus(bus
, devfn
);
163 printk(BIOS_DEBUG
, "0x%x: BAD DEVICE bus %d devfn 0x%x\n", func
, bus
, devfn
);
164 // Or are we supposed to return PCIBIOS_NODEV?
165 X86_EAX
&= 0xffff00ff; /* Clear AH */
166 X86_EAX
|= PCIBIOS_BADREG
;
171 case 0xb108: /* Read Config Byte */
172 byte
= pci_read_config8(dev
, reg
);
175 case 0xb109: /* Read Config Word */
176 word
= pci_read_config16(dev
, reg
);
179 case 0xb10a: /* Read Config Dword */
180 dword
= pci_read_config32(dev
, reg
);
183 case 0xb10b: /* Write Config Byte */
185 pci_write_config8(dev
, reg
, byte
);
187 case 0xb10c: /* Write Config Word */
189 pci_write_config16(dev
, reg
, word
);
191 case 0xb10d: /* Write Config Dword */
193 pci_write_config32(dev
, reg
, dword
);
197 #if CONFIG(REALMODE_DEBUG)
198 printk(BIOS_DEBUG
, "0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n",
199 func
, bus
, devfn
, reg
, X86_ECX
);
201 X86_EAX
&= 0xffff00ff; /* Clear AH */
202 X86_EAX
|= PCIBIOS_SUCCESSFUL
;
206 printk(BIOS_ERR
, "UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func
);
207 X86_EAX
&= 0xffff00ff; /* Clear AH */
208 X86_EAX
|= PCIBIOS_UNSUPPORTED
;