|
|
1.1 root 1: /* Simplistic PCI support.
2:
3: Copyright (C) 2011 Richard Henderson
4:
5: This file is part of QEMU PALcode.
6:
7: This program is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2 of the License or
10: (at your option) any later version.
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 text
15: of the 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; see the file COPYING. If not see
19: <http://www.gnu.org/licenses/>. */
20:
21: /* We don't bother supporting PCI bridges, because the device model we're
22: currently using for QEMU doesn't build any.
23:
24: We don't bother to build real datastructures in memory, because it's
25: fairly quick under emulation simply to access configuration space again.
26: This helps when running kernels under the emulator that might have
27: re-organized the BARs out from under us. */
28:
29: #include "protos.h"
30: #include "pci.h"
31: #include "pci_regs.h"
32:
33:
34: #define PCI_DEVFN(slot, func) ((((slot) & 0x1f) << 3) | ((func) & 0x07))
35: #define PCI_BUS(devfn) ((devfn) >> 8)
36: #define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
37: #define PCI_FUNC(devfn) ((devfn) & 0x07)
38: #define PCI_SLOT_MAX 32
39: #define PCI_FUNC_MAX 8
40: #define PCI_REGION_ROM 6
41: #define PCI_REGIONS_MAX 7
42:
43:
44: void
45: pci_config_maskw(int bdf, int addr, uint16_t off, uint16_t on)
46: {
47: uint16_t val = pci_config_readw(bdf, addr);
48: val = (val & ~off) | on;
49: pci_config_writew(bdf, addr, val);
50: }
51:
52: int
53: pci_next(int bdf, int *pmax)
54: {
55: int max;
56:
57: if (PCI_FUNC(bdf) == 1)
58: {
59: /* If the last device was not a multi-function device, skip to next. */
60: if ((pci_config_readb(bdf-1, PCI_HEADER_TYPE) & 0x80) == 0)
61: bdf += 7;
62: }
63:
64: max = *pmax;
65: while (1)
66: {
67: uint16_t vendor;
68:
69: /* ??? Support multiple PCI busses here at some point. */
70: if (bdf >= max)
71: return -1;
72:
73: /* Check if there is a device present at the location. */
74: vendor = pci_config_readw(bdf, PCI_VENDOR_ID);
75: if (vendor != 0x0000 && vendor != 0xffff)
76: return bdf;
77:
78: bdf += (PCI_FUNC(bdf) == 0 ? 8 : 1);
79: }
80: }
81:
82: static void
83: pci_setup_device(int bdf, uint32_t *p_io_base, uint32_t *p_mem_base)
84: {
85: int vendor_id, device_id, class_id, region;
86:
87: vendor_id = pci_config_readw(bdf, PCI_VENDOR_ID);
88: device_id = pci_config_readw(bdf, PCI_DEVICE_ID);
89: class_id = pci_config_readw(bdf, PCI_CLASS_DEVICE);
90:
91: printf("PCI: %02x:%02x:%x class %04x id %04x:%04x\r\n",
92: PCI_BUS(bdf), PCI_SLOT(bdf), PCI_FUNC(bdf),
93: class_id, vendor_id, device_id);
94:
95: for (region = 0; region < PCI_REGION_ROM; region++)
96: {
97: int ofs = PCI_BASE_ADDRESS_0 + region * 4;
98: uint32_t old, mask, val, size, align;
99: uint32_t *p_base;
100:
101: old = pci_config_readl(bdf, ofs);
102: if (old & PCI_BASE_ADDRESS_SPACE_IO)
103: {
104: mask = PCI_BASE_ADDRESS_IO_MASK;
105: p_base = p_io_base;
106: }
107: else
108: {
109: mask = PCI_BASE_ADDRESS_MEM_MASK;
110: p_base = p_mem_base;
111: }
112:
113: pci_config_writel(bdf, ofs, -1);
114: val = pci_config_readl(bdf, ofs);
115: pci_config_writel(bdf, ofs, old);
116:
117: align = size = ~(val & mask) + 1;
118: if (val != 0)
119: {
120: uint32_t addr = *p_base;
121: addr = (addr + align - 1) & ~(align - 1);
122: *p_base = addr + size;
123: pci_config_writel(bdf, ofs, addr);
124:
125: printf("PCI: region %d: %08x\r\n", region, addr);
126:
127: if ((val & PCI_BASE_ADDRESS_MEM_TYPE_MASK)
128: == PCI_BASE_ADDRESS_MEM_TYPE_64)
129: {
130: pci_config_writel(bdf, ofs + 4, 0);
131: region++;
132: }
133: }
134: }
135:
136: pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
137:
138: /* Map the interrupt. */
139: }
140:
141: void
142: pci_setup(void)
143: {
144: uint32_t io_base = 0xc000;
145: uint32_t mem_base = 256 * 1024 * 1024;
146: int bdf, max;
147:
148: foreachpci (bdf, max)
149: pci_setup_device(bdf, &io_base, &mem_base);
150: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.