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