drop COREBOOT_V2 and COREBOOT_V4 define. We're not sharing code with v3
[coreboot.git] / util / x86emu / x86_interrupts.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2001 Ronald G. Minnich
5  * Copyright (C) 2005 Nick.Barker9@btinternet.com
6  * Copyright (C) 2007-2009 coresystems GmbH
7  *
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.
11  *
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.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21
22 #include <device/pci.h>
23 #include <device/pci_ids.h>
24 #include <device/pci_ops.h>
25 #include <string.h>
26 #include <console/console.h>
27 #include <arch/io.h>
28 #include <arch/registers.h>
29 #define printk(x...) do_printk(x)
30
31 enum {
32         PCIBIOS_CHECK = 0xb101,
33         PCIBIOS_FINDDEV = 0xb102,
34         PCIBIOS_READCONFBYTE = 0xb108,
35         PCIBIOS_READCONFWORD = 0xb109,
36         PCIBIOS_READCONFDWORD = 0xb10a,
37         PCIBIOS_WRITECONFBYTE = 0xb10b,
38         PCIBIOS_WRITECONFWORD = 0xb10c,
39         PCIBIOS_WRITECONFDWORD = 0xb10d
40 };
41
42 // errors go in AH. Just set these up so that word assigns
43 // will work. KISS.
44 enum {
45         PCIBIOS_SUCCESSFUL = 0x0000,
46         PCIBIOS_UNSUPPORTED = 0x8100,
47         PCIBIOS_BADVENDOR = 0x8300,
48         PCIBIOS_NODEV = 0x8600,
49         PCIBIOS_BADREG = 0x8700
50 };
51
52 int int12_handler(struct eregs *regs);
53 int int1a_handler(struct eregs *regs);
54 int int15_handler(struct eregs *regs);
55
56 int int12_handler(struct eregs *regs)
57 {
58         regs->eax = 64 * 1024;
59         return 0;
60 }
61
62 int int1a_handler(struct eregs *regs)
63 {
64         unsigned short func = (unsigned short)regs->eax;
65         int retval = 0;
66         unsigned short devid, vendorid, devfn;
67         /* Use short to get rid of gabage in upper half of 32-bit register */
68         short devindex;
69         unsigned char bus;
70         struct device *dev;
71         u32 dword;
72         u16 word;
73         u8 byte, reg;
74
75         switch (func) {
76         case PCIBIOS_CHECK:
77                 regs->edx = 0x20494350; /* ' ICP' */
78                 regs->edi = 0x00000000; /* protected mode entry */
79                 retval = 0;
80                 break;
81         case PCIBIOS_FINDDEV:
82                 devid = regs->ecx;
83                 vendorid = regs->edx;
84                 devindex = regs->esi;
85                 dev = 0;
86                 while ((dev = dev_find_device(vendorid, devid, dev))) {
87                         if (devindex <= 0)
88                                 break;
89                         devindex--;
90                 }
91                 if (dev) {
92                         unsigned short busdevfn;
93                         regs->eax = 0;
94                         // busnum is an unsigned char;
95                         // devfn is an int, so we mask it off.
96                         busdevfn = (dev->bus->secondary << 8)
97                             | (dev->path.pci.devfn & 0xff);
98                         printk(BIOS_DEBUG, "0x%x: return 0x%x\n", func, busdevfn);
99                         regs->ebx = busdevfn;
100                         retval = 0;
101                 } else {
102                         regs->eax = PCIBIOS_NODEV;
103                         retval = -1;
104                 }
105                 break;
106         case PCIBIOS_READCONFDWORD:
107         case PCIBIOS_READCONFWORD:
108         case PCIBIOS_READCONFBYTE:
109         case PCIBIOS_WRITECONFDWORD:
110         case PCIBIOS_WRITECONFWORD:
111         case PCIBIOS_WRITECONFBYTE:
112                 devfn = regs->ebx & 0xff;
113                 bus = regs->ebx >> 8;
114                 reg = regs->edi;
115                 dev = dev_find_slot(bus, devfn);
116                 if (!dev) {
117                         printk(BIOS_DEBUG, "0x%x: BAD DEVICE bus %d devfn 0x%x\n", func, bus, devfn);
118                         // idiots. the pcibios guys assumed you'd never pass a bad bus/devfn!
119                         regs->eax = PCIBIOS_BADREG;
120                         retval = -1;
121                         return retval;
122                 }
123                 switch (func) {
124                 case PCIBIOS_READCONFBYTE:
125                         byte = pci_read_config8(dev, reg);
126                         regs->ecx = byte;
127                         break;
128                 case PCIBIOS_READCONFWORD:
129                         word = pci_read_config16(dev, reg);
130                         regs->ecx = word;
131                         break;
132                 case PCIBIOS_READCONFDWORD:
133                         dword = pci_read_config32(dev, reg);
134                         regs->ecx = dword;
135                         break;
136                 case PCIBIOS_WRITECONFBYTE:
137                         byte = regs->ecx;
138                         pci_write_config8(dev, reg, byte);
139                         break;
140                 case PCIBIOS_WRITECONFWORD:
141                         word = regs->ecx;
142                         pci_write_config16(dev, reg, word);
143                         break;
144                 case PCIBIOS_WRITECONFDWORD:
145                         dword = regs->ecx;
146                         pci_write_config32(dev, reg, dword);
147                         break;
148                 }
149
150                 printk(BIOS_DEBUG, "0x%x: bus %d devfn 0x%x reg 0x%x val 0x%x\n",
151                              func, bus, devfn, reg, regs->ecx);
152                 regs->eax = 0;
153                 retval = 0;
154                 break;
155         default:
156                 printk(BIOS_ERR, "UNSUPPORTED PCIBIOS FUNCTION 0x%x\n", func);
157                 retval = -1;
158                 break;
159         }
160
161         return retval;
162 }
163
164 int int15_handler(struct eregs *regs)
165 {
166         int res = -1;
167
168         /* This int15 handler is VIA Tech. specific. Other chipsets need other
169          * handlers. The right way to do this is to move this handler code into
170          * the mainboard or northbridge code.
171          */
172         switch (regs->eax & 0xffff) {
173         case 0x5f19:
174                 break;
175         case 0x5f18:
176                 regs->eax = 0x5f;
177                 // MCLK = 133, 32M frame buffer, 256 M main memory
178                 regs->ebx = 0x545;
179                 regs->ecx = 0x060;
180                 res = 0;
181                 break;
182         case 0x5f00:
183                 regs->eax = 0x8600;
184                 break;
185         case 0x5f01:
186                 regs->eax = 0x5f;
187                 regs->ecx = (regs->ecx & 0xffffff00 ) | 2; // panel type =  2 = 1024 * 768
188                 res = 0;
189                 break;
190         case 0x5f02:
191                 regs->eax = 0x5f;
192                 regs->ebx = (regs->ebx & 0xffff0000) | 2;
193                 regs->ecx = (regs->ecx & 0xffff0000) | 0x401;  // PAL + crt only
194                 regs->edx = (regs->edx & 0xffff0000) | 0;  // TV Layout - default
195                 res = 0;
196                 break;
197         case 0x5f0f:
198                 regs->eax = 0x860f;
199                 break;
200         /* And now Intel IGD code */
201 #define BOOT_DISPLAY_DEFAULT    0
202 #define BOOT_DISPLAY_CRT        (1 << 0)
203 #define BOOT_DISPLAY_TV         (1 << 1)
204 #define BOOT_DISPLAY_EFP        (1 << 2)
205 #define BOOT_DISPLAY_LCD        (1 << 3)
206 #define BOOT_DISPLAY_CRT2       (1 << 4)
207 #define BOOT_DISPLAY_TV2        (1 << 5)
208 #define BOOT_DISPLAY_EFP2       (1 << 6)
209 #define BOOT_DISPLAY_LCD2       (1 << 7)
210
211         case 0x5f35:
212                 regs->eax = 0x5f;
213                 regs->ecx = BOOT_DISPLAY_DEFAULT;
214                 res = 0;
215                 break;
216         case 0x5f40:
217                 regs->eax = 0x5f;
218                 regs->ecx = 3; // This is mainboard specific
219                 printk(BIOS_DEBUG, "DISPLAY=%x\n", regs->ecx);
220                 res = 0;
221                 break;
222         default:
223                 printk(BIOS_DEBUG, "Unknown INT15 function %04x!\n", 
224                                 regs->eax & 0xffff);
225         }
226
227         return res;
228 }
229