1
2
3
4
5
6#include <common.h>
7#include <cpu_func.h>
8#include <init.h>
9#include <pci.h>
10#include <qfw.h>
11#include <asm/irq.h>
12#include <asm/post.h>
13#include <asm/processor.h>
14#include <asm/arch/device.h>
15#include <asm/arch/qemu.h>
16
17static bool i440fx;
18
19#ifdef CONFIG_QFW
20
21
22#define FW_CONTROL_PORT 0x510
23#define FW_DATA_PORT 0x511
24#define FW_DMA_PORT_LOW 0x514
25#define FW_DMA_PORT_HIGH 0x518
26
27static void qemu_x86_fwcfg_read_entry_pio(uint16_t entry,
28 uint32_t size, void *address)
29{
30 uint32_t i = 0;
31 uint8_t *data = address;
32
33
34
35
36
37
38
39
40 if (entry != FW_CFG_INVALID)
41 outw(cpu_to_le16(entry), FW_CONTROL_PORT);
42
43
44 while (size--)
45 data[i++] = inb(FW_DATA_PORT);
46}
47
48static void qemu_x86_fwcfg_read_entry_dma(struct fw_cfg_dma_access *dma)
49{
50
51 outl(cpu_to_be32((uintptr_t)dma), FW_DMA_PORT_HIGH);
52
53 while (be32_to_cpu(dma->control) & ~FW_CFG_DMA_ERROR)
54 __asm__ __volatile__ ("pause");
55}
56
57static struct fw_cfg_arch_ops fwcfg_x86_ops = {
58 .arch_read_pio = qemu_x86_fwcfg_read_entry_pio,
59 .arch_read_dma = qemu_x86_fwcfg_read_entry_dma
60};
61#endif
62
63static void enable_pm_piix(void)
64{
65 u8 en;
66 u16 cmd;
67
68
69 pci_write_config32(PIIX_PM, PMBA, CONFIG_ACPI_PM1_BASE | 1);
70
71
72 pci_read_config16(PIIX_PM, PCI_COMMAND, &cmd);
73 cmd |= PCI_COMMAND_IO;
74 pci_write_config16(PIIX_PM, PCI_COMMAND, cmd);
75
76
77 pci_read_config8(PIIX_PM, PMREGMISC, &en);
78 en |= PMIOSE;
79 pci_write_config8(PIIX_PM, PMREGMISC, en);
80}
81
82static void enable_pm_ich9(void)
83{
84
85 pci_write_config32(ICH9_PM, PMBA, CONFIG_ACPI_PM1_BASE | 1);
86}
87
88static void qemu_chipset_init(void)
89{
90 u16 device, xbcs;
91 int pam, i;
92
93
94
95
96
97
98 pci_read_config16(PCI_BDF(0, 0, 0), PCI_DEVICE_ID, &device);
99 i440fx = (device == PCI_DEVICE_ID_INTEL_82441);
100 pam = i440fx ? I440FX_PAM : Q35_PAM;
101
102
103
104
105
106
107 for (i = 0; i < PAM_NUM; i++)
108 pci_write_config8(PCI_BDF(0, 0, 0), pam + i, PAM_RW);
109
110 if (i440fx) {
111
112
113
114
115
116
117
118
119 pci_write_config16(PIIX_IDE, IDE0_TIM, IDE_DECODE_EN);
120 pci_write_config16(PIIX_IDE, IDE1_TIM, IDE_DECODE_EN);
121
122
123 pci_read_config16(PIIX_ISA, XBCS, &xbcs);
124 xbcs |= APIC_EN;
125 pci_write_config16(PIIX_ISA, XBCS, xbcs);
126
127 enable_pm_piix();
128 } else {
129
130 pci_write_config32(PCI_BDF(0, 0, 0), PCIEX_BAR,
131 CONFIG_PCIE_ECAM_BASE | BAR_EN);
132
133 enable_pm_ich9();
134 }
135
136#ifdef CONFIG_QFW
137 qemu_fwcfg_init(&fwcfg_x86_ops);
138#endif
139}
140
141#if !CONFIG_IS_ENABLED(SPL_X86_32BIT_INIT)
142int arch_cpu_init(void)
143{
144 post_code(POST_CPU_INIT);
145
146 return x86_cpu_init_f();
147}
148
149int checkcpu(void)
150{
151 return 0;
152}
153
154int print_cpuinfo(void)
155{
156 post_code(POST_CPU_INFO);
157 return default_print_cpuinfo();
158}
159#endif
160
161int arch_early_init_r(void)
162{
163 qemu_chipset_init();
164
165 return 0;
166}
167
168#ifdef CONFIG_GENERATE_MP_TABLE
169int mp_determine_pci_dstirq(int bus, int dev, int func, int pirq)
170{
171 u8 irq;
172
173 if (i440fx) {
174
175
176
177
178
179 pci_read_config8(PCI_BDF(bus, dev, func),
180 PCI_INTERRUPT_LINE, &irq);
181 } else {
182
183
184
185
186 irq = pirq < 8 ? pirq + 16 : pirq + 12;
187 }
188
189 return irq;
190}
191#endif
192