Trivial white space fixes so that the next patches are easier to read.
[coreboot.git] / src / northbridge / intel / i440bx / northbridge.c
1 #include <console/console.h>
2 #include <arch/io.h>
3 #include <stdint.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ids.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <bitops.h>
10 #include <cpu/cpu.h>
11 #include <pc80/keyboard.h>
12 #include "chip.h"
13 #include "northbridge.h"
14 #include "i440bx.h"
15
16 static void northbridge_init(device_t dev)
17 {
18         printk_spew("Northbridge Init\n");
19 }
20
21 static struct device_operations northbridge_operations = {
22         .read_resources   = pci_dev_read_resources,
23         .set_resources    = pci_dev_set_resources,
24         .enable_resources = pci_dev_enable_resources,
25         .init             = northbridge_init,
26         .enable           = 0,
27         .ops_pci          = 0,
28 };
29
30 static const struct pci_driver northbridge_driver __pci_driver = {
31         .ops = &northbridge_operations,
32         .vendor = PCI_VENDOR_ID_INTEL,
33         .device = 0x7190,
34 };
35
36
37 #define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM)
38
39 static void pci_domain_read_resources(device_t dev)
40 {
41         struct resource *resource;
42
43         /* Initialize the system wide io space constraints */
44         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0,0));
45         resource->limit = 0xffffUL;
46         resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
47
48         /* Initialize the system wide memory resources constraints */
49         resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1,0));
50         resource->limit = 0xffffffffULL;
51         resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
52 }
53
54 static void ram_resource(device_t dev, unsigned long index,
55         unsigned long basek, unsigned long sizek)
56 {
57         struct resource *resource;
58
59         if (!sizek) {
60                 return;
61         }
62         resource = new_resource(dev, index);
63         resource->base  = ((resource_t)basek) << 10;
64         resource->size  = ((resource_t)sizek) << 10;
65         resource->flags =  IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
66                 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
67 }
68
69 static void tolm_test(void *gp, struct device *dev, struct resource *new)
70 {
71         struct resource **best_p = gp;
72         struct resource *best;
73         best = *best_p;
74         if (!best || (best->base > new->base)) {
75                 best = new;
76         }
77         *best_p = best;
78 }
79
80 static uint32_t find_pci_tolm(struct bus *bus)
81 {
82         struct resource *min;
83         uint32_t tolm;
84         min = 0;
85         search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
86         tolm = 0xffffffffUL;
87         if (min && tolm > min->base) {
88                 tolm = min->base;
89         }
90         return tolm;
91 }
92
93 #if HAVE_HIGH_TABLES==1
94 #define HIGH_TABLES_SIZE 64     // maximum size of high tables in KB
95 extern uint64_t high_tables_base, high_tables_size;
96 #endif
97
98 static void pci_domain_set_resources(device_t dev)
99 {
100         device_t mc_dev;
101         uint32_t pci_tolm;
102
103         pci_tolm = find_pci_tolm(&dev->link[0]);
104         mc_dev = dev->link[0].children;
105         if (mc_dev) {
106                 uint16_t tolm_r;
107                 unsigned long tomk, tolmk;
108                 int idx;
109
110                 /* Figure out which areas are/should be occupied by RAM. The
111                  * value of the highest DRB denotes the end of the physical
112                  * memory (in units of 8MB).
113                  */
114                 tomk = ((unsigned long)pci_read_config8(mc_dev, DRB7));
115
116                 /* Convert to KB. */
117                 tomk *= (8 * 1024);
118
119                 printk_debug("Setting RAM size to %d MB\n", tomk / 1024);
120
121                 /* Compute the top of low memory. */
122                 tolmk = pci_tolm / 1024;
123
124                 if (tolmk >= tomk) {
125                         /* The PCI hole does not overlap the memory. */
126                         tolmk = tomk;
127                 }
128
129                 /* Report the memory regions. */
130                 idx = 10;
131                 ram_resource(dev, idx++, 0, 640);
132                 ram_resource(dev, idx++, 768, tolmk - 768);
133
134 #if HAVE_HIGH_TABLES==1
135                 /* Leave some space for ACPI, PIRQ and MP tables */
136                 high_tables_base = (tomk - HIGH_TABLES_SIZE) * 1024;
137                 high_tables_size = HIGH_TABLES_SIZE * 1024;
138 #endif
139         }
140         assign_resources(&dev->link[0]);
141 }
142
143 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
144 {
145         max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max);
146         return max;
147 }
148
149 static struct device_operations pci_domain_ops = {
150         .read_resources         = pci_domain_read_resources,
151         .set_resources          = pci_domain_set_resources,
152         .enable_resources       = enable_childrens_resources,
153         .init                   = 0,
154         .scan_bus               = pci_domain_scan_bus,
155 };
156
157 static void cpu_bus_init(device_t dev)
158 {
159         initialize_cpus(&dev->link[0]);
160 }
161
162 static void cpu_bus_noop(device_t dev)
163 {
164 }
165
166 static struct device_operations cpu_bus_ops = {
167         .read_resources   = cpu_bus_noop,
168         .set_resources    = cpu_bus_noop,
169         .enable_resources = cpu_bus_noop,
170         .init             = cpu_bus_init,
171         .scan_bus         = 0,
172 };
173
174 static void enable_dev(struct device *dev)
175 {
176         /* Set the operations if it is a special bus type */
177         if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
178                 dev->ops = &pci_domain_ops;
179                 pci_set_method(dev);
180         }
181         else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
182                 dev->ops = &cpu_bus_ops;
183         }
184 }
185
186 struct chip_operations northbridge_intel_i440bx_ops = {
187         CHIP_NAME("Intel 82443BX (440BX) Northbridge")
188         .enable_dev = enable_dev,
189 };