added PCI expansion ROM support,
[coreboot.git] / src / devices / emulator / pcbios / pcibios.c
1 #include <console/console.h>
2 #include <device/device.h>
3 #include <device/pci.h>
4 #include <device/pci_ids.h>
5 #include <device/pci_ops.h>
6 #include <x86emu/x86emu.h>
7
8 #include "pcibios.h"
9
10 int pcibios_handler()
11 {
12         int i, ret = 0;
13         struct device *dev = 0;
14
15         printk_debug("%s AX = %x\n", __func__, X86_AX);
16
17         switch (X86_AX) {
18         case PCI_BIOS_PRESENT:
19                 X86_AH  = 0x00;         /* no config space/special cycle support */
20                 X86_AL  = 0x01;         /* config mechanism 1 */
21                 X86_EDX = 'P' | 'C' << 8 | 'I' | ' ' << 24;
22                 X86_EBX = 0x0210;       /* Version 2.10 */
23                 X86_ECX = 0xFF00;       /* FixME: Max bus number */
24                 X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
25                 ret = 1;
26                 break;
27         case FIND_PCI_DEVICE:
28                 /* FixME: support SI != 0 */
29                 dev = dev_find_device(X86_DX, X86_CX, dev);
30                 if (dev != 0) {
31                         X86_BH = dev->bus->secondary;
32                         X86_BL = dev->path.u.pci.devfn;
33                         X86_AH = SUCCESSFUL;
34                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
35                         ret = 1;
36                 } else {
37                         X86_AH = DEVICE_NOT_FOUND;
38                         X86_EFLAGS |= FB_CF;    /* set carry flag */
39                         ret = 0;
40                 }
41                 break;
42         case FIND_PCI_CLASS_CODE:
43                 /* FixME: support SI != 0 */
44                 dev = dev_find_class(X86_ECX, dev);
45                 if (dev != 0) {
46                         X86_BH = dev->bus->secondary;
47                         X86_BL = dev->path.u.pci.devfn;
48                         X86_AH = SUCCESSFUL;
49                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
50                         ret = 1;
51                 } else {
52                         X86_AH = DEVICE_NOT_FOUND;
53                         X86_EFLAGS |= FB_CF;    /* set carry flag */
54                         ret = 0;
55                 }
56                 break;
57         case READ_CONFIG_BYTE:
58                 dev = dev_find_slot(X86_BH, X86_BL);
59                 if (dev != 0) {
60                         X86_CL = pci_read_config8(dev, X86_DI);
61                         X86_AH = SUCCESSFUL;
62                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
63                         ret = 1;
64                 } else {
65                         X86_AH = DEVICE_NOT_FOUND;
66                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
67                         ret = 0;
68                 }
69                 break;
70         case READ_CONFIG_WORD:
71                 dev = dev_find_slot(X86_BH, X86_BL);
72                 if (dev != 0) {
73                         X86_CX = pci_read_config16(dev, X86_DI);
74                         X86_AH = SUCCESSFUL;
75                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
76                         ret = 1;
77                 } else {
78                         X86_AH = DEVICE_NOT_FOUND;
79                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
80                         ret = 0;
81                 }
82                 break;
83         case READ_CONFIG_DWORD:
84                 dev = dev_find_slot(X86_BH, X86_BL);
85                 if (dev != 0) {
86                         X86_ECX = pci_read_config32(dev, X86_DI);
87                         X86_AH = SUCCESSFUL;
88                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
89                         ret = 1;
90                 } else {
91                         X86_AH = DEVICE_NOT_FOUND;
92                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
93                         ret = 0;
94                 }
95                 break;
96         case WRITE_CONFIG_BYTE:
97                 dev = dev_find_slot(X86_BH, X86_BL);
98                 if (dev != 0) {
99                         pci_write_config8(dev, X86_DI, X86_CL);
100                         X86_AH = SUCCESSFUL;
101                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
102                         ret = 1;
103                 } else {
104                         X86_AH = DEVICE_NOT_FOUND;
105                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
106                         ret = 0;
107                 }
108                 break;
109         case WRITE_CONFIG_WORD:
110                 dev = dev_find_slot(X86_BH, X86_BL);
111                 if (dev != 0) {
112                         pci_write_config16(dev, X86_DI, X86_CX);
113                         X86_AH = SUCCESSFUL;
114                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
115                         ret = 1;
116                 } else {
117                         X86_AH = DEVICE_NOT_FOUND;
118                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
119                         ret = 0;
120                 }
121                 break;
122         case WRITE_CONFIG_DWORD:
123                 dev = dev_find_slot(X86_BH, X86_BL);
124                 if (dev != 0) {
125                         pci_write_config16(dev, X86_DI, X86_ECX);
126                         X86_AH = SUCCESSFUL;
127                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
128                         ret = 1;
129                 } else {
130                         X86_AH = DEVICE_NOT_FOUND;
131                         X86_EFLAGS |= FB_CF;    /* set carry flag */    
132                         ret = 0;
133                 }
134                 break;
135         default:
136                 X86_AH = FUNC_NOT_SUPPORTED;
137                 X86_EFLAGS |= FB_CF; 
138                 break;
139         }
140
141         return ret;
142 }