fix Qemu
[coreboot.git] / util / x86emu / pcbios / pcibios.c
1 /*
2  * This software and ancillary information (herein called SOFTWARE )
3  * called LinuxBIOS          is made available under the terms described
4  * here.  The SOFTWARE has been approved for release with associated
5  * LA-CC Number 00-34   .  Unless otherwise indicated, this SOFTWARE has
6  * been authored by an employee or employees of the University of
7  * California, operator of the Los Alamos National Laboratory under
8  * Contract No. W-7405-ENG-36 with the U.S. Department of Energy.  The
9  * U.S. Government has rights to use, reproduce, and distribute this
10  * SOFTWARE.  The public may copy, distribute, prepare derivative works
11  * and publicly display this SOFTWARE without charge, provided that this
12  * Notice and any statement of authorship are reproduced on all copies.
13  * Neither the Government nor the University makes any warranty, express
14  * or implied, or assumes any liability or responsibility for the use of
15  * this SOFTWARE.  If SOFTWARE is modified to produce derivative works,
16  * such modified SOFTWARE should be clearly marked, so as not to confuse
17  * it with the version available from LANL.
18  */
19  /*
20  * This file is part of the coreboot project.
21  *
22  *  (c) Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
23  *
24  * This program is free software; you can redistribute it and/or modify
25  * it under the terms of the GNU General Public License as published by 
26  * the Free Software Foundation; either version 2 of the License, or
27  * (at your option) any later version.
28  *
29  * This program is distributed in the hope that it will be useful,
30  * but WITHOUT ANY WARRANTY; without even the implied warranty of
31  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32  * GNU General Public License for more details.
33  *
34  * You should have received a copy of the GNU General Public License
35  * along with this program; if not, write to the Free Software
36  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
37  */
38 #ifdef CONFIG_COREBOOT_V2
39 #include <console/console.h>
40 #else
41 #include <console.h>
42 #endif
43 #include <device/device.h>
44 #include <device/pci.h>
45 #include <device/pci_ids.h>
46 #include <device/pci_ops.h>
47 #include <x86emu/x86emu.h>
48
49 #include "pcibios.h"
50
51 int pcibios_handler(void)
52 {
53         int ret = 0;
54         struct device *dev = 0;
55
56         switch (X86_AX) {
57         case PCI_BIOS_PRESENT:
58                 X86_AH  = 0x00;         /* no config space/special cycle support */
59                 X86_AL  = 0x01;         /* config mechanism 1 */
60                 X86_EDX = 'P' | 'C' << 8 | 'I' << 16 | ' ' << 24;
61                 X86_EBX = 0x0210;       /* Version 2.10 */
62                 X86_ECX = 0xFF00;       /* FixME: Max bus number */
63                 X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
64                 ret = 1;
65                 break;
66         case FIND_PCI_DEVICE:
67                 /* FixME: support SI != 0 */
68 #ifdef CONFIG_COREBOOT_V2
69                 dev = dev_find_device(X86_DX, X86_CX, dev);
70 #else
71                 dev = dev_find_pci_device(X86_DX, X86_CX, dev);
72 #endif
73                 if (dev != 0) {
74                         X86_BH = dev->bus->secondary;
75                         X86_BL = dev->path.pci.devfn;
76                         X86_AH = SUCCESSFUL;
77                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
78                         ret = 1;
79                 } else {
80                         X86_AH = DEVICE_NOT_FOUND;
81                         X86_EFLAGS |= FB_CF;    /* set carry flag */
82                         ret = 0;
83                 }
84                 break;
85         case FIND_PCI_CLASS_CODE:
86                 /* FixME: support SI != 0 */
87                 dev = dev_find_class(X86_ECX, dev);
88                 if (dev != 0) {
89                         X86_BH = dev->bus->secondary;
90                         X86_BL = dev->path.pci.devfn;
91                         X86_AH = SUCCESSFUL;
92                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
93                         ret = 1;
94                 } else {
95                         X86_AH = DEVICE_NOT_FOUND;
96                         X86_EFLAGS |= FB_CF;    /* set carry flag */
97                         ret = 0;
98                 }
99                 break;
100         case READ_CONFIG_BYTE:
101                 dev = dev_find_slot(X86_BH, X86_BL);
102                 if (dev != 0) {
103                         X86_CL = pci_read_config8(dev, X86_DI);
104                         X86_AH = SUCCESSFUL;
105                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
106                         ret = 1;
107                 } else {
108                         X86_AH = DEVICE_NOT_FOUND;
109                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
110                         ret = 0;
111                 }
112                 break;
113         case READ_CONFIG_WORD:
114                 dev = dev_find_slot(X86_BH, X86_BL);
115                 if (dev != 0) {
116                         X86_CX = pci_read_config16(dev, X86_DI);
117                         X86_AH = SUCCESSFUL;
118                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
119                         ret = 1;
120                 } else {
121                         X86_AH = DEVICE_NOT_FOUND;
122                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
123                         ret = 0;
124                 }
125                 break;
126         case READ_CONFIG_DWORD:
127                 dev = dev_find_slot(X86_BH, X86_BL);
128                 if (dev != 0) {
129                         X86_ECX = pci_read_config32(dev, X86_DI);
130                         X86_AH = SUCCESSFUL;
131                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
132                         ret = 1;
133                 } else {
134                         X86_AH = DEVICE_NOT_FOUND;
135                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
136                         ret = 0;
137                 }
138                 break;
139         case WRITE_CONFIG_BYTE:
140                 dev = dev_find_slot(X86_BH, X86_BL);
141                 if (dev != 0) {
142                         pci_write_config8(dev, X86_DI, X86_CL);
143                         X86_AH = SUCCESSFUL;
144                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
145                         ret = 1;
146                 } else {
147                         X86_AH = DEVICE_NOT_FOUND;
148                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
149                         ret = 0;
150                 }
151                 break;
152         case WRITE_CONFIG_WORD:
153                 dev = dev_find_slot(X86_BH, X86_BL);
154                 if (dev != 0) {
155                         pci_write_config16(dev, X86_DI, X86_CX);
156                         X86_AH = SUCCESSFUL;
157                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
158                         ret = 1;
159                 } else {
160                         X86_AH = DEVICE_NOT_FOUND;
161                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
162                         ret = 0;
163                 }
164                 break;
165         case WRITE_CONFIG_DWORD:
166                 dev = dev_find_slot(X86_BH, X86_BL);
167                 if (dev != 0) {
168                         pci_write_config16(dev, X86_DI, X86_ECX);
169                         X86_AH = SUCCESSFUL;
170                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
171                         ret = 1;
172                 } else {
173                         X86_AH = DEVICE_NOT_FOUND;
174                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
175                         ret = 0;
176                 }
177                 break;
178         default:
179                 X86_AH = FUNC_NOT_SUPPORTED;
180                 X86_EFLAGS |= FB_CF; 
181                 break;
182         }
183
184         return ret;
185 }