Unify Local APIC address definitions
[coreboot.git] / src / mainboard / emulation / qemu-x86 / northbridge.c
1 #include <console/console.h>
2 #include <cpu/x86/lapic_def.h>
3 #include <arch/io.h>
4 #include <arch/ioapic.h>
5 #include <stdint.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <bitops.h>
11 #include "chip.h"
12 #include <delay.h>
13 #include <smbios.h>
14
15 #if CONFIG_WRITE_HIGH_TABLES==1
16 #include <cbmem.h>
17 #endif
18
19 #define CMOS_ADDR_PORT 0x70
20 #define CMOS_DATA_PORT 0x71
21 #define HIGH_RAM_ADDR 0x35
22 #define LOW_RAM_ADDR 0x34
23
24 static unsigned long qemu_get_memory_size(void)
25 {
26         unsigned long tomk;
27         outb (HIGH_RAM_ADDR, CMOS_ADDR_PORT);
28         tomk = ((unsigned long) inb(CMOS_DATA_PORT)) << 14;
29         outb (LOW_RAM_ADDR, CMOS_ADDR_PORT);
30         tomk |= ((unsigned long) inb(CMOS_DATA_PORT)) << 6;
31         tomk += 16 * 1024;
32         return tomk;
33 }
34
35 static void cpu_pci_domain_set_resources(device_t dev)
36 {
37         u32 pci_tolm = find_pci_tolm(dev->link_list);
38         unsigned long tomk = 0, tolmk;
39         int idx;
40
41         tomk = qemu_get_memory_size();
42         printk(BIOS_DEBUG, "Detected %lu Kbytes (%lu MiB) RAM.\n",
43                tomk, tomk / 1024);
44
45         /* Compute the top of Low memory */
46         tolmk = pci_tolm >> 10;
47         if (tolmk >= tomk) {
48                 /* The PCI hole does not overlap the memory. */
49                 tolmk = tomk;
50         }
51
52         /* Report the memory regions. */
53         idx = 10;
54         ram_resource(dev, idx++, 0, 640);
55         ram_resource(dev, idx++, 768, tolmk - 768);
56
57 #if CONFIG_WRITE_HIGH_TABLES==1
58         /* Leave some space for ACPI, PIRQ and MP tables */
59         high_tables_base = (tomk * 1024) - HIGH_MEMORY_SIZE;
60         high_tables_size = HIGH_MEMORY_SIZE;
61 #endif
62
63         assign_resources(dev->link_list);
64 }
65
66 static void cpu_pci_domain_read_resources(struct device *dev)
67 {
68         struct resource *res;
69
70         pci_domain_read_resources(dev);
71
72         /* Reserve space for the IOAPIC.  This should be in the Southbridge,
73          * but I couldn't tell which device to put it in. */
74         res = new_resource(dev, 2);
75         res->base = IO_APIC_ADDR;
76         res->size = 0x100000UL;
77         res->limit = 0xffffffffUL;
78         res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |
79                      IORESOURCE_ASSIGNED;
80
81         /* Reserve space for the LAPIC.  There's one in every processor, but
82          * the space only needs to be reserved once, so we do it here. */
83         res = new_resource(dev, 3);
84         res->base = LOCAL_APIC_ADDR;
85         res->size = 0x10000UL;
86         res->limit = 0xffffffffUL;
87         res->flags = IORESOURCE_MEM | IORESOURCE_FIXED | IORESOURCE_STORED |
88                      IORESOURCE_ASSIGNED;
89 }
90
91 #if CONFIG_GENERATE_SMBIOS_TABLES
92 static int qemu_get_smbios_data16(int handle, unsigned long *current)
93 {
94         struct smbios_type16 *t = (struct smbios_type16 *)*current;
95         int len = sizeof(struct smbios_type16);
96
97         memset(t, 0, sizeof(struct smbios_type16));
98         t->type = SMBIOS_PHYS_MEMORY_ARRAY;
99         t->handle = handle;
100         t->length = len - 2;
101         t->location = 3; /* Location: System Board */
102         t->use = 3; /* System memory */
103         t->memory_error_correction = 3; /* No error correction */
104         t->maximum_capacity = qemu_get_memory_size();
105         *current += len;
106         return len;
107 }
108
109 static int qemu_get_smbios_data17(int handle, int parent_handle, unsigned long *current)
110 {
111         struct smbios_type17 *t = (struct smbios_type17 *)*current;
112         int len;
113
114         memset(t, 0, sizeof(struct smbios_type17));
115         t->type = SMBIOS_MEMORY_DEVICE;
116         t->handle = handle;
117         t->phys_memory_array_handle = parent_handle;
118         t->length = sizeof(struct smbios_type17) - 2;
119         t->size = qemu_get_memory_size() / 1024;
120         t->data_width = 64;
121         t->total_width = 64;
122         t->form_factor = 9; /* DIMM */
123         t->device_locator = smbios_add_string(t->eos, "Virtual");
124         t->memory_type = 0x12; /* DDR */
125         t->type_detail = 0x80; /* Synchronous */
126         t->speed = 200;
127         t->clock_speed = 200;
128         t->manufacturer = smbios_add_string(t->eos, CONFIG_MAINBOARD_VENDOR);
129         len = t->length + smbios_string_table_len(t->eos);
130         *current += len;
131         return len;
132 }
133
134 static int qemu_get_smbios_data(device_t dev, int *handle, unsigned long *current)
135 {
136         int len;
137         len = qemu_get_smbios_data16(*handle, current);
138         len += qemu_get_smbios_data17(*handle+1, *handle, current);
139         *handle += 2;
140         return len;
141 }
142 #endif
143 static struct device_operations pci_domain_ops = {
144         .read_resources         = cpu_pci_domain_read_resources,
145         .set_resources          = cpu_pci_domain_set_resources,
146         .enable_resources       = NULL,
147         .init                   = NULL,
148         .scan_bus               = pci_domain_scan_bus,
149 #if CONFIG_GENERATE_SMBIOS_TABLES
150         .get_smbios_data        = qemu_get_smbios_data,
151 #endif
152 };
153
154 static void enable_dev(struct device *dev)
155 {
156         /* Set the operations if it is a special bus type */
157         if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
158                 dev->ops = &pci_domain_ops;
159                 pci_set_method(dev);
160         }
161 }
162
163 struct chip_operations mainboard_emulation_qemu_x86_ops = {
164         CHIP_NAME("QEMU Northbridge")
165         .enable_dev = enable_dev,
166 };