blob: 123d22a971e5d98f6202277564c8972bd6cd06dc [file] [log] [blame]
Eric Biederman8ca8d762003-04-22 19:02:15 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Uwe Hermannb80dbf02007-04-22 19:08:13 +00003 *
4 * It was originally based on the Linux kernel (arch/i386/kernel/pci-pc.c).
5 *
6 * Modifications are:
7 * Copyright (C) 2003 Eric Biederman <ebiederm@xmission.com>
8 * Copyright (C) 2003-2004 Linux Networx
9 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
10 * Copyright (C) 2003 Ronald G. Minnich <rminnich@gmail.com>
11 * Copyright (C) 2004-2005 Li-Ta Lo <ollie@lanl.gov>
12 * Copyright (C) 2005-2006 Tyan
13 * (Written by Yinghai Lu <yhlu@tyan.com> for Tyan)
14 * Copyright (C) 2005-2006 Stefan Reinauer <stepan@openbios.org>
Myles Watson29cc9ed2009-07-02 18:56:24 +000015 * Copyright (C) 2009 Myles Watson <mylesgw@gmail.com>
Uwe Hermannb80dbf02007-04-22 19:08:13 +000016 */
17
18/*
Eric Biederman8ca8d762003-04-22 19:02:15 +000019 * (c) 1999--2000 Martin Mares <mj@suse.cz>
Eric Biederman8ca8d762003-04-22 19:02:15 +000020 */
Myles Watson032a9652009-05-11 22:24:53 +000021/* lots of mods by ron minnich (rminnich@lanl.gov), with
Eric Biederman8ca8d762003-04-22 19:02:15 +000022 * the final architecture guidance from Tom Merritt (tjm@codegen.com)
Myles Watson032a9652009-05-11 22:24:53 +000023 * In particular, we changed from the one-pass original version to
24 * Tom's recommended multiple-pass version. I wasn't sure about doing
Eric Biederman8ca8d762003-04-22 19:02:15 +000025 * it with multiple passes, until I actually started doing it and saw
26 * the wisdom of Tom's recommendations ...
27 *
28 * Lots of cleanups by Eric Biederman to handle bridges, and to
29 * handle resource allocation for non-pci devices.
30 */
31
32#include <console/console.h>
33#include <bitops.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000034#include <arch/io.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000035#include <device/device.h>
36#include <device/pci.h>
Li-Ta Lo54f05f62004-05-14 17:20:29 +000037#include <device/pci_ids.h>
Eric Biedermane9a271e32003-09-02 03:36:25 +000038#include <stdlib.h>
39#include <string.h>
Eric Biederman03acab62004-10-14 21:25:53 +000040#include <smp/spinlock.h>
Eric Biederman8ca8d762003-04-22 19:02:15 +000041
Li-Ta Loe5266692004-03-23 21:28:05 +000042/** Linked list of ALL devices */
Eric Biederman5cd81732004-03-11 15:01:31 +000043struct device *all_devices = &dev_root;
Li-Ta Loe5266692004-03-23 21:28:05 +000044/** Pointer to the last device */
Eric Biederman7003ba42004-10-16 06:20:29 +000045extern struct device **last_dev_p;
Eric Biederman8ca8d762003-04-22 19:02:15 +000046
Eric Biederman8ca8d762003-04-22 19:02:15 +000047
Li-Ta Loe5266692004-03-23 21:28:05 +000048/**
49 * @brief Allocate a new device structure.
Myles Watson032a9652009-05-11 22:24:53 +000050 *
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +000051 * Allocte a new device structure and attached it to the device tree as a
52 * child of the parent bus.
Li-Ta Loe5266692004-03-23 21:28:05 +000053 *
54 * @param parent parent bus the newly created device attached to.
55 * @param path path to the device to be created.
56 *
57 * @return pointer to the newly created device structure.
58 *
59 * @see device_path
Eric Biederman8ca8d762003-04-22 19:02:15 +000060 */
Eric Biederman448bd632004-10-14 22:52:15 +000061static spinlock_t dev_lock = SPIN_LOCK_UNLOCKED;
Eric Biedermane9a271e32003-09-02 03:36:25 +000062device_t alloc_dev(struct bus *parent, struct device_path *path)
Eric Biederman8ca8d762003-04-22 19:02:15 +000063{
Eric Biedermane9a271e32003-09-02 03:36:25 +000064 device_t dev, child;
65 int link;
Li-Ta Loe5266692004-03-23 21:28:05 +000066
Myles Watson032a9652009-05-11 22:24:53 +000067 spin_lock(&dev_lock);
Li-Ta Lo3a812852004-12-03 22:39:34 +000068
Myles Watson29cc9ed2009-07-02 18:56:24 +000069 /* Find the last child of our parent. */
70 for (child = parent->children; child && child->sibling; /* */ ) {
Eric Biedermane9a271e32003-09-02 03:36:25 +000071 child = child->sibling;
72 }
Li-Ta Lo3a812852004-12-03 22:39:34 +000073
Eric Biedermane9a271e32003-09-02 03:36:25 +000074 dev = malloc(sizeof(*dev));
Myles Watson29cc9ed2009-07-02 18:56:24 +000075 if (dev == 0)
Eric Biedermane9a271e32003-09-02 03:36:25 +000076 die("DEV: out of memory.\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +000077
Eric Biedermane9a271e32003-09-02 03:36:25 +000078 memset(dev, 0, sizeof(*dev));
79 memcpy(&dev->path, path, sizeof(*path));
80
Myles Watson29cc9ed2009-07-02 18:56:24 +000081 /* Initialize the back pointers in the link fields. */
82 for (link = 0; link < MAX_LINKS; link++) {
83 dev->link[link].dev = dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +000084 dev->link[link].link = link;
85 }
Li-Ta Lo3a812852004-12-03 22:39:34 +000086
Myles Watson29cc9ed2009-07-02 18:56:24 +000087 /* By default devices are enabled. */
Eric Biederman03acab62004-10-14 21:25:53 +000088 dev->enabled = 1;
Eric Biedermane9a271e32003-09-02 03:36:25 +000089
Eric Biedermanb78c1972004-10-14 20:54:17 +000090 /* Add the new device to the list of children of the bus. */
Eric Biedermane9a271e32003-09-02 03:36:25 +000091 dev->bus = parent;
92 if (child) {
93 child->sibling = dev;
94 } else {
95 parent->children = dev;
96 }
Li-Ta Loe5266692004-03-23 21:28:05 +000097
Eric Biederman03acab62004-10-14 21:25:53 +000098 /* Append a new device to the global device list.
99 * The list is used to find devices once everything is set up.
100 */
101 *last_dev_p = dev;
102 last_dev_p = &dev->next;
103
104 spin_unlock(&dev_lock);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000105 return dev;
106}
Eric Biederman8ca8d762003-04-22 19:02:15 +0000107
Li-Ta Loe5266692004-03-23 21:28:05 +0000108/**
Myles Watson032a9652009-05-11 22:24:53 +0000109 * @brief round a number up to an alignment.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000110 * @param val the starting value
111 * @param roundup Alignment as a power of two
112 * @returns rounded up number
113 */
Eric Biederman448bd632004-10-14 22:52:15 +0000114static resource_t round(resource_t val, unsigned long pow)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000115{
Eric Biederman448bd632004-10-14 22:52:15 +0000116 resource_t mask;
117 mask = (1ULL << pow) - 1ULL;
118 val += mask;
119 val &= ~mask;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000120 return val;
121}
122
Eric Biederman8ca8d762003-04-22 19:02:15 +0000123/** Read the resources on all devices of a given bus.
124 * @param bus bus to read the resources on.
125 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000126static void read_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000127{
128 struct device *curdev;
129
Myles Watson29cc9ed2009-07-02 18:56:24 +0000130 printk_spew("%s %s bus %x link: %d\n", dev_path(bus->dev), __func__,
131 bus->secondary, bus->link);
Eric Biederman448bd632004-10-14 22:52:15 +0000132
Myles Watson29cc9ed2009-07-02 18:56:24 +0000133 /* Walk through all devices and find which resources they need. */
134 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000135 int i;
Eric Biederman448bd632004-10-14 22:52:15 +0000136 if (!curdev->enabled) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000137 continue;
138 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000139 if (!curdev->ops || !curdev->ops->read_resources) {
140 printk_err("%s missing read_resources\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000141 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000142 continue;
143 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000144 curdev->ops->read_resources(curdev);
Myles Watson29cc9ed2009-07-02 18:56:24 +0000145
146 /* Read in the resources behind the current device's links. */
147 for (i = 0; i < curdev->links; i++)
148 read_resources(&curdev->link[i]);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000149 }
Eric Biederman448bd632004-10-14 22:52:15 +0000150 printk_spew("%s read_resources bus %d link: %d done\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000151 dev_path(bus->dev), bus->secondary, bus->link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000152}
153
Eric Biedermane9a271e32003-09-02 03:36:25 +0000154struct pick_largest_state {
155 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000156 struct device *result_dev;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000157 struct resource *result;
158 int seen_last;
159};
160
Myles Watson29cc9ed2009-07-02 18:56:24 +0000161static void pick_largest_resource(void *gp, struct device *dev,
162 struct resource *resource)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000163{
Eric Biedermanf8a2ddd2004-10-30 08:05:41 +0000164 struct pick_largest_state *state = gp;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000165 struct resource *last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000166
Eric Biedermane9a271e32003-09-02 03:36:25 +0000167 last = state->last;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000168
169 /* Be certain to pick the successor to last. */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000170 if (resource == last) {
171 state->seen_last = 1;
172 return;
173 }
Myles Watson032a9652009-05-11 22:24:53 +0000174 if (resource->flags & IORESOURCE_FIXED)
175 return; // Skip it.
176 if (last && ((last->align < resource->align) ||
177 ((last->align == resource->align) &&
178 (last->size < resource->size)) ||
179 ((last->align == resource->align) &&
180 (last->size == resource->size) && (!state->seen_last)))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000181 return;
182 }
Myles Watson032a9652009-05-11 22:24:53 +0000183 if (!state->result ||
184 (state->result->align < resource->align) ||
185 ((state->result->align == resource->align) &&
Myles Watson29cc9ed2009-07-02 18:56:24 +0000186 (state->result->size < resource->size))) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000187 state->result_dev = dev;
188 state->result = resource;
Myles Watson032a9652009-05-11 22:24:53 +0000189 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000190}
191
Myles Watson29cc9ed2009-07-02 18:56:24 +0000192static struct device *largest_resource(struct bus *bus,
193 struct resource **result_res,
194 unsigned long type_mask,
195 unsigned long type)
Eric Biedermane9a271e32003-09-02 03:36:25 +0000196{
197 struct pick_largest_state state;
198
199 state.last = *result_res;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000200 state.result_dev = NULL;
201 state.result = NULL;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000202 state.seen_last = 0;
203
Myles Watson032a9652009-05-11 22:24:53 +0000204 search_bus_resources(bus, type_mask, type, pick_largest_resource,
205 &state);
Eric Biedermane9a271e32003-09-02 03:36:25 +0000206
207 *result_res = state.result;
208 return state.result_dev;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000209}
210
211/* Compute allocate resources is the guts of the resource allocator.
Myles Watson032a9652009-05-11 22:24:53 +0000212 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000213 * The problem.
Myles Watson29cc9ed2009-07-02 18:56:24 +0000214 * - Allocate resource locations for every device.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000215 * - Don't overlap, and follow the rules of bridges.
216 * - Don't overlap with resources in fixed locations.
217 * - Be efficient so we don't have ugly strategies.
218 *
219 * The strategy.
220 * - Devices that have fixed addresses are the minority so don't
Myles Watson29cc9ed2009-07-02 18:56:24 +0000221 * worry about them too much. Instead only use part of the address
222 * space for devices with programmable addresses. This easily handles
Eric Biederman8ca8d762003-04-22 19:02:15 +0000223 * everything except bridges.
224 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000225 * - PCI devices are required to have their sizes and their alignments
226 * equal. In this case an optimal solution to the packing problem
227 * exists. Allocate all devices from highest alignment to least
228 * alignment or vice versa. Use this.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000229 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000230 * - So we can handle more than PCI run two allocation passes on bridges. The
231 * first to see how large the resources are behind the bridge, and what
232 * their alignment requirements are. The second to assign a safe address to
233 * the devices behind the bridge. This allows us to treat a bridge as just
234 * a device with a couple of resources, and not need to special case it in
235 * the allocator. Also this allows handling of other types of bridges.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000236 *
237 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000238void compute_resources(struct bus *bus, struct resource *bridge,
239 unsigned long type_mask, unsigned long type)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000240{
241 struct device *dev;
242 struct resource *resource;
Eric Biederman03acab62004-10-14 21:25:53 +0000243 resource_t base;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000244 base = round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000245
Myles Watson29cc9ed2009-07-02 18:56:24 +0000246 printk_spew( "%s %s_%s: base: %llx size: %llx align: %d gran: %d limit: %llx\n",
247 dev_path(bus->dev), __func__,
248 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
249 "prefmem" : "mem",
250 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
Ronald G. Minnich99dcf232003-09-30 02:16:47 +0000251
Myles Watson29cc9ed2009-07-02 18:56:24 +0000252 /* For each child which is a bridge, compute_resource_needs. */
253 for (dev = bus->children; dev; dev = dev->sibling) {
254 unsigned i;
255 struct resource *child_bridge;
256
257 if (!dev->links)
258 continue;
259
260 /* Find the resources with matching type flags. */
261 for (i = 0; i < dev->resources; i++) {
262 unsigned link;
263 child_bridge = &dev->resource[i];
264
265 if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
266 (child_bridge->flags & type_mask) != type)
267 continue;
268
269 /* Split prefetchable memory if combined. Many domains
270 * use the same address space for prefetchable memory
271 * and non-prefetchable memory. Bridges below them
272 * need it separated. Add the PREFETCH flag to the
273 * type_mask and type.
274 */
275 link = IOINDEX_LINK(child_bridge->index);
276 compute_resources(&dev->link[link], child_bridge,
277 type_mask | IORESOURCE_PREFETCH,
278 type | (child_bridge->flags &
279 IORESOURCE_PREFETCH));
280 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000281 }
282
Myles Watson29cc9ed2009-07-02 18:56:24 +0000283 /* Remember we haven't found anything yet. */
284 resource = NULL;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000285
Myles Watson29cc9ed2009-07-02 18:56:24 +0000286 /* Walk through all the resources on the current bus and compute the
287 * amount of address space taken by them. Take granularity and
288 * alignment into account.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000289 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000290 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000291
Myles Watson29cc9ed2009-07-02 18:56:24 +0000292 /* Size 0 resources can be skipped. */
293 if (!resource->size) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000294 continue;
295 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000296
Myles Watson29cc9ed2009-07-02 18:56:24 +0000297 /* Propagate the resource alignment to the bridge resource. */
298 if (resource->align > bridge->align) {
299 bridge->align = resource->align;
300 }
301
302 /* Propagate the resource limit to the bridge register. */
Eric Biedermandbec2d42004-10-21 10:44:08 +0000303 if (bridge->limit > resource->limit) {
304 bridge->limit = resource->limit;
305 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000306
307 /* Warn if it looks like APICs aren't declared. */
308 if ((resource->limit == 0xffffffff) &&
309 (resource->flags & IORESOURCE_ASSIGNED)) {
310 printk_err("Resource limit looks wrong! (no APIC?)\n");
311 printk_err("%s %02lx limit %08Lx\n", dev_path(dev),
312 resource->index, resource->limit);
Eric Biedermandbec2d42004-10-21 10:44:08 +0000313 }
Stefan Reinauer51754a32008-08-01 12:28:38 +0000314
Eric Biederman8ca8d762003-04-22 19:02:15 +0000315 if (resource->flags & IORESOURCE_IO) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000316 /* Don't allow potential aliases over the legacy PCI
317 * expansion card addresses. The legacy PCI decodes
318 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
319 * 0x00 - 0xff can be used out of each 0x400 block of
320 * I/O space.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000321 */
Eric Biedermanbbb6d102003-08-04 19:54:48 +0000322 if ((base & 0x300) != 0) {
Eric Biederman8ca8d762003-04-22 19:02:15 +0000323 base = (base & ~0x3ff) + 0x400;
324 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000325 /* Don't allow allocations in the VGA I/O range.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000326 * PCI has special cases for that.
327 */
328 else if ((base >= 0x3b0) && (base <= 0x3df)) {
329 base = 0x3e0;
330 }
331 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000332 /* Base must be aligned. */
333 base = round(base, resource->align);
334 resource->base = base;
335 base += resource->size;
Myles Watson032a9652009-05-11 22:24:53 +0000336
Myles Watson29cc9ed2009-07-02 18:56:24 +0000337 printk_spew("%s %02lx * [0x%llx - 0x%llx] %s\n",
338 dev_path(dev), resource->index,
339 resource->base,
340 resource->base + resource->size - 1,
341 (resource->flags & IORESOURCE_IO) ? "io" :
342 (resource->flags & IORESOURCE_PREFETCH) ?
343 "prefmem" : "mem");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000344 }
345 /* A pci bridge resource does not need to be a power
346 * of two size, but it does have a minimum granularity.
347 * Round the size up to that minimum granularity so we
348 * know not to place something else at an address postitively
349 * decoded by the bridge.
350 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000351 bridge->size = round(base, bridge->gran) -
352 round(bridge->base, bridge->align);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000353
Myles Watson29cc9ed2009-07-02 18:56:24 +0000354 printk_spew("%s %s_%s: base: %llx size: %llx align: %d gran: %d limit: %llx done\n",
355 dev_path(bus->dev), __func__,
356 (bridge->flags & IORESOURCE_IO) ? "io" :
357 (bridge->flags & IORESOURCE_PREFETCH) ? "prefmem" : "mem",
358 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
359}
360
361/**
362 * This function is the second part of the resource allocator.
363 *
364 * The problem.
365 * - Allocate resource locations for every device.
366 * - Don't overlap, and follow the rules of bridges.
367 * - Don't overlap with resources in fixed locations.
368 * - Be efficient so we don't have ugly strategies.
369 *
370 * The strategy.
371 * - Devices that have fixed addresses are the minority so don't
372 * worry about them too much. Instead only use part of the address
373 * space for devices with programmable addresses. This easily handles
374 * everything except bridges.
375 *
376 * - PCI devices are required to have their sizes and their alignments
377 * equal. In this case an optimal solution to the packing problem
378 * exists. Allocate all devices from highest alignment to least
379 * alignment or vice versa. Use this.
380 *
381 * - So we can handle more than PCI run two allocation passes on bridges. The
382 * first to see how large the resources are behind the bridge, and what
383 * their alignment requirements are. The second to assign a safe address to
384 * the devices behind the bridge. This allows us to treat a bridge as just
385 * a device with a couple of resources, and not need to special case it in
386 * the allocator. Also this allows handling of other types of bridges.
387 *
388 * - This function assigns the resources a value.
389 *
390 * @param bus The bus we are traversing.
391 * @param bridge The bridge resource which must contain the bus' resources.
392 * @param type_mask This value gets anded with the resource type.
393 * @param type This value must match the result of the and.
394 */
395void allocate_resources(struct bus *bus, struct resource *bridge,
396 unsigned long type_mask, unsigned long type)
397{
398 struct device *dev;
399 struct resource *resource;
400 resource_t base;
401 base = bridge->base;
402
403 printk_spew("%s %s_%s: base:%llx size:%llx align:%d gran:%d limit:%llx\n",
404 dev_path(bus->dev), __func__,
405 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
406 "prefmem" : "mem",
407 base, bridge->size, bridge->align, bridge->gran, bridge->limit);
408
409 /* Remember we haven't found anything yet. */
410 resource = NULL;
411
412 /* Walk through all the resources on the current bus and allocate them
413 * address space.
414 */
415 while ((dev = largest_resource(bus, &resource, type_mask, type))) {
416
417 /* Propagate the bridge limit to the resource register. */
418 if (resource->limit > bridge->limit) {
419 resource->limit = bridge->limit;
420 }
421
422 /* Size 0 resources can be skipped. */
423 if (!resource->size) {
424 /* Set the base to limit so it doesn't confuse tolm. */
425 resource->base = resource->limit;
426 resource->flags |= IORESOURCE_ASSIGNED;
427 continue;
428 }
429
430 if (resource->flags & IORESOURCE_IO) {
431 /* Don't allow potential aliases over the legacy PCI
432 * expansion card addresses. The legacy PCI decodes
433 * only 10 bits, uses 0x100 - 0x3ff. Therefore, only
434 * 0x00 - 0xff can be used out of each 0x400 block of
435 * I/O space.
436 */
437 if ((base & 0x300) != 0) {
438 base = (base & ~0x3ff) + 0x400;
439 }
440 /* Don't allow allocations in the VGA I/O range.
441 * PCI has special cases for that.
442 */
443 else if ((base >= 0x3b0) && (base <= 0x3df)) {
444 base = 0x3e0;
445 }
446 }
447
448 if ((round(base, resource->align) + resource->size - 1) <=
449 resource->limit) {
450 /* Base must be aligned. */
451 base = round(base, resource->align);
452 resource->base = base;
453 resource->flags |= IORESOURCE_ASSIGNED;
454 resource->flags &= ~IORESOURCE_STORED;
455 base += resource->size;
456 } else {
457 printk_err("!! Resource didn't fit !!\n");
458 printk_err(" aligned base %llx size %llx limit %llx\n",
459 round(base, resource->align), resource->size,
460 resource->limit);
461 printk_err(" %llx needs to be <= %llx (limit)\n",
462 (round(base, resource->align) +
463 resource->size) - 1, resource->limit);
464 printk_err(" %s%s %02lx * [0x%llx - 0x%llx] %s\n",
465 (resource->
466 flags & IORESOURCE_ASSIGNED) ? "Assigned: " :
467 "", dev_path(dev), resource->index,
468 resource->base,
469 resource->base + resource->size - 1,
470 (resource->
471 flags & IORESOURCE_IO) ? "io" : (resource->
472 flags &
473 IORESOURCE_PREFETCH)
474 ? "prefmem" : "mem");
475 }
476
477 printk_spew("%s%s %02lx * [0x%llx - 0x%llx] %s\n",
478 (resource->flags & IORESOURCE_ASSIGNED) ? "Assigned: "
479 : "",
480 dev_path(dev), resource->index, resource->base,
481 resource->size ? resource->base + resource->size - 1 :
482 resource->base,
483 (resource->flags & IORESOURCE_IO) ? "io" :
484 (resource->flags & IORESOURCE_PREFETCH) ? "prefmem" :
485 "mem");
486 }
487 /* A PCI bridge resource does not need to be a power of two size, but
488 * it does have a minimum granularity. Round the size up to that
489 * minimum granularity so we know not to place something else at an
490 * address positively decoded by the bridge.
491 */
492
493 bridge->flags |= IORESOURCE_ASSIGNED;
494
495 printk_spew("%s %s_%s: next_base: %llx size: %llx align: %d gran: %d done\n",
496 dev_path(bus->dev), __func__,
497 (type & IORESOURCE_IO) ? "io" : (type & IORESOURCE_PREFETCH) ?
498 "prefmem" : "mem",
499 base, bridge->size, bridge->align, bridge->gran);
500
501 /* For each child which is a bridge, allocate_resources. */
502 for (dev = bus->children; dev; dev = dev->sibling) {
503 unsigned i;
504 struct resource *child_bridge;
505
506 if (!dev->links)
507 continue;
508
509 /* Find the resources with matching type flags. */
510 for (i = 0; i < dev->resources; i++) {
511 unsigned link;
512 child_bridge = &dev->resource[i];
513
514 if (!(child_bridge->flags & IORESOURCE_BRIDGE) ||
515 (child_bridge->flags & type_mask) != type)
516 continue;
517
518 /* Split prefetchable memory if combined. Many domains
519 * use the same address space for prefetchable memory
520 * and non-prefetchable memory. Bridges below them
521 * need it separated. Add the PREFETCH flag to the
522 * type_mask and type.
523 */
524 link = IOINDEX_LINK(child_bridge->index);
525 allocate_resources(&dev->link[link], child_bridge,
526 type_mask | IORESOURCE_PREFETCH,
527 type | (child_bridge->flags &
528 IORESOURCE_PREFETCH));
529 }
530 }
531}
532
533#if CONFIG_PCI_64BIT_PREF_MEM == 1
534 #define MEM_MASK (IORESOURCE_PREFETCH | IORESOURCE_MEM)
535#else
536 #define MEM_MASK (IORESOURCE_MEM)
537#endif
538#define IO_MASK (IORESOURCE_IO)
539#define PREF_TYPE (IORESOURCE_PREFETCH | IORESOURCE_MEM)
540#define MEM_TYPE (IORESOURCE_MEM)
541#define IO_TYPE (IORESOURCE_IO)
542
543struct constraints {
544 struct resource pref, io, mem;
545};
546
547static void constrain_resources(struct device *dev, struct constraints* limits)
548{
549 struct device *child;
550 struct resource *res;
551 struct resource *lim;
552 int i;
553
554 printk_spew("%s: %s\n", __func__, dev_path(dev));
555
556 /* Constrain limits based on the fixed resources of this device. */
557 for (i = 0; i < dev->resources; i++) {
558 res = &dev->resource[i];
559 if (!(res->flags & IORESOURCE_FIXED))
560 continue;
561
562 /* PREFETCH, MEM, or I/O - skip any others. */
563 if ((res->flags & MEM_MASK) == PREF_TYPE)
564 lim = &limits->pref;
565 else if ((res->flags & MEM_MASK) == MEM_TYPE)
566 lim = &limits->mem;
567 else if ((res->flags & IO_MASK) == IO_TYPE)
568 lim = &limits->io;
569 else
570 continue;
571
572 /* Is it already outside the limits? */
573 if (res->size && (((res->base + res->size -1) < lim->base) ||
574 (res->base > lim->limit)))
575 continue;
576
577 /* Choose to be above or below fixed resources. This
578 * check is signed so that "negative" amounts of space
579 * are handled correctly.
580 */
581 if ((signed long long)(lim->limit - (res->base + res->size -1)) >
582 (signed long long)(res->base - lim->base))
583 lim->base = res->base + res->size;
584 else
585 lim->limit = res->base -1;
586 }
587
588 /* Descend into every enabled child and look for fixed resources. */
589 for (i = 0; i < dev->links; i++)
590 for (child = dev->link[i].children; child;
591 child = child->sibling)
592 if (child->enabled)
593 constrain_resources(child, limits);
594}
595
596static void avoid_fixed_resources(struct device *dev)
597{
598 struct constraints limits;
599 struct resource *res;
600 int i;
601
602 printk_spew("%s: %s\n", __func__, dev_path(dev));
603 /* Initialize constraints to maximum size. */
604
605 limits.pref.base = 0;
606 limits.pref.limit = 0xffffffffffffffffULL;
607 limits.io.base = 0;
608 limits.io.limit = 0xffffffffffffffffULL;
609 limits.mem.base = 0;
610 limits.mem.limit = 0xffffffffffffffffULL;
611
612 /* Constrain the limits to dev's initial resources. */
613 for (i = 0; i < dev->resources; i++) {
614 res = &dev->resource[i];
615 if ((res->flags & IORESOURCE_FIXED))
616 continue;
617 printk_spew("%s:@%s %02lx limit %08Lx\n", __func__,
618 dev_path(dev), res->index, res->limit);
619 if ((res->flags & MEM_MASK) == PREF_TYPE &&
620 (res->limit < limits.pref.limit))
621 limits.pref.limit = res->limit;
622 if ((res->flags & MEM_MASK) == MEM_TYPE &&
623 (res->limit < limits.mem.limit))
624 limits.mem.limit = res->limit;
625 if ((res->flags & IO_MASK) == IO_TYPE &&
626 (res->limit < limits.io.limit))
627 limits.io.limit = res->limit;
628 }
629
630 /* Look through the tree for fixed resources and update the limits. */
631 constrain_resources(dev, &limits);
632
633 /* Update dev's resources with new limits. */
634 for (i = 0; i < dev->resources; i++) {
635 struct resource *lim;
636 res = &dev->resource[i];
637
638 if ((res->flags & IORESOURCE_FIXED))
639 continue;
640
641 /* PREFETCH, MEM, or I/O - skip any others. */
642 if ((res->flags & MEM_MASK) == PREF_TYPE)
643 lim = &limits.pref;
644 else if ((res->flags & MEM_MASK) == MEM_TYPE)
645 lim = &limits.mem;
646 else if ((res->flags & IO_MASK) == IO_TYPE)
647 lim = &limits.io;
648 else
649 continue;
650
651 printk_spew("%s2: %s@%02lx limit %08Lx\n", __func__,
652 dev_path(dev), res->index, res->limit);
653 printk_spew("\tlim->base %08Lx lim->limit %08Lx\n",
654 lim->base, lim->limit);
655
656 /* Is the resource outside the limits? */
657 if (lim->base > res->base)
658 res->base = lim->base;
659 if (res->limit > lim->limit)
660 res->limit = lim->limit;
661 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000662}
arch import user (historical)dc811182005-07-06 17:16:09 +0000663
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000664#if CONFIG_CONSOLE_VGA == 1
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000665device_t vga_pri = 0;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000666static void allocate_vga_resource(void)
667{
Eric Biedermane9a271e32003-09-02 03:36:25 +0000668#warning "FIXME modify allocate_vga_resource so it is less pci centric!"
Myles Watson29cc9ed2009-07-02 18:56:24 +0000669#warning "This function knows too much about PCI stuff, it should be just a iterator/visitor."
Li-Ta Loe5266692004-03-23 21:28:05 +0000670
Myles Watson29cc9ed2009-07-02 18:56:24 +0000671 /* FIXME: Handle the VGA palette snooping. */
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000672 struct device *dev, *vga, *vga_onboard, *vga_first, *vga_last;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000673 struct bus *bus;
674 bus = 0;
675 vga = 0;
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000676 vga_onboard = 0;
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000677 vga_first = 0;
678 vga_last = 0;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000679 for (dev = all_devices; dev; dev = dev->next) {
680 if (!dev->enabled)
681 continue;
Li-Ta Lo54f05f62004-05-14 17:20:29 +0000682 if (((dev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
Myles Watson29cc9ed2009-07-02 18:56:24 +0000683 ((dev->class >> 8) != PCI_CLASS_DISPLAY_OTHER)) {
684 if (!vga_first) {
685 if (dev->on_mainboard) {
686 vga_onboard = dev;
687 } else {
688 vga_first = dev;
689 }
690 } else {
691 if (dev->on_mainboard) {
692 vga_onboard = dev;
693 } else {
694 vga_last = dev;
695 }
696 }
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000697
Myles Watson29cc9ed2009-07-02 18:56:24 +0000698 /* It isn't safe to enable other VGA cards. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000699 dev->command &= ~(PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000700 }
701 }
Myles Watson032a9652009-05-11 22:24:53 +0000702
Myles Watson29cc9ed2009-07-02 18:56:24 +0000703 vga = vga_last;
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000704
Myles Watson29cc9ed2009-07-02 18:56:24 +0000705 if (!vga) {
706 vga = vga_first;
707 }
Yinghai Lu2b396cd2006-05-18 16:54:30 +0000708#if CONFIG_CONSOLE_VGA_ONBOARD_AT_FIRST == 1
Myles Watson29cc9ed2009-07-02 18:56:24 +0000709 if (vga_onboard) // Will use on board VGA as pri.
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000710#else
Myles Watson29cc9ed2009-07-02 18:56:24 +0000711 if (!vga) // Will use last add on adapter as pri.
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000712#endif
Myles Watson29cc9ed2009-07-02 18:56:24 +0000713 {
714 vga = vga_onboard;
715 }
Myles Watson032a9652009-05-11 22:24:53 +0000716
arch import user (historical)dc811182005-07-06 17:16:09 +0000717 if (vga) {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000718 /* VGA is first add on card or the only onboard VGA. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000719 printk_debug("Allocating VGA resource %s\n", dev_path(vga));
Myles Watson29cc9ed2009-07-02 18:56:24 +0000720 /* All legacy VGA cards have MEM & I/O space registers. */
Yinghai Lu1f1085b2005-01-17 21:37:12 +0000721 vga->command |= (PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
722 vga_pri = vga;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000723 bus = vga->bus;
724 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000725 /* Now walk up the bridges setting the VGA enable. */
726 while (bus) {
Li-Ta Lo515f6c72005-01-11 22:48:54 +0000727 printk_debug("Setting PCI_BRIDGE_CTL_VGA for bridge %s\n",
728 dev_path(bus->dev));
Li-Ta Lodb7f47c2004-01-08 21:15:49 +0000729 bus->bridge_ctrl |= PCI_BRIDGE_CTL_VGA;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000730 bus = (bus == bus->dev->bus) ? 0 : bus->dev->bus;
Myles Watson032a9652009-05-11 22:24:53 +0000731 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000732}
Stefan Reinauer7ce8c542005-12-02 21:52:30 +0000733
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000734#endif
Eric Biederman8ca8d762003-04-22 19:02:15 +0000735
Li-Ta Lo04930692004-11-25 17:37:19 +0000736/**
737 * @brief Assign the computed resources to the devices on the bus.
738 *
Eric Biederman8ca8d762003-04-22 19:02:15 +0000739 * @param bus Pointer to the structure for this bus
Li-Ta Lo04930692004-11-25 17:37:19 +0000740 *
741 * Use the device specific set_resources method to store the computed
742 * resources to hardware. For bridge devices, the set_resources() method
743 * has to recurse into every down stream buses.
744 *
745 * Mutual recursion:
746 * assign_resources() -> device_operation::set_resources()
747 * device_operation::set_resources() -> assign_resources()
748 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000749void assign_resources(struct bus *bus)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000750{
751 struct device *curdev;
752
Myles Watson032a9652009-05-11 22:24:53 +0000753 printk_spew("%s assign_resources, bus %d link: %d\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000754 dev_path(bus->dev), bus->secondary, bus->link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000755
Myles Watson29cc9ed2009-07-02 18:56:24 +0000756 for (curdev = bus->children; curdev; curdev = curdev->sibling) {
Eric Biederman03acab62004-10-14 21:25:53 +0000757 if (!curdev->enabled || !curdev->resources) {
758 continue;
759 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000760 if (!curdev->ops || !curdev->ops->set_resources) {
761 printk_err("%s missing set_resources\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000762 dev_path(curdev));
Eric Biedermane9a271e32003-09-02 03:36:25 +0000763 continue;
764 }
Eric Biederman8ca8d762003-04-22 19:02:15 +0000765 curdev->ops->set_resources(curdev);
766 }
Myles Watson032a9652009-05-11 22:24:53 +0000767 printk_spew("%s assign_resources, bus %d link: %d\n",
Myles Watson29cc9ed2009-07-02 18:56:24 +0000768 dev_path(bus->dev), bus->secondary, bus->link);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000769}
770
Li-Ta Lo5782d272004-04-26 17:51:20 +0000771/**
772 * @brief Enable the resources for a specific device
773 *
774 * @param dev the device whose resources are to be enabled
775 *
776 * Enable resources of the device by calling the device specific
777 * enable_resources() method.
778 *
779 * The parent's resources should be enabled first to avoid having enabling
780 * order problem. This is done by calling the parent's enable_resources()
Li-Ta Lo04930692004-11-25 17:37:19 +0000781 * method and let that method to call it's children's enable_resoruces()
782 * method via the (global) enable_childrens_resources().
Li-Ta Lo9f0d0f92004-05-10 16:05:16 +0000783 *
784 * Indirect mutual recursion:
Li-Ta Lo04930692004-11-25 17:37:19 +0000785 * enable_resources() -> device_operations::enable_resource()
786 * device_operations::enable_resource() -> enable_children_resources()
787 * enable_children_resources() -> enable_resources()
Li-Ta Lo5782d272004-04-26 17:51:20 +0000788 */
Eric Biedermane9a271e32003-09-02 03:36:25 +0000789void enable_resources(struct device *dev)
Eric Biederman8ca8d762003-04-22 19:02:15 +0000790{
Eric Biederman03acab62004-10-14 21:25:53 +0000791 if (!dev->enabled) {
Eric Biedermane9a271e32003-09-02 03:36:25 +0000792 return;
Eric Biederman8ca8d762003-04-22 19:02:15 +0000793 }
Eric Biederman03acab62004-10-14 21:25:53 +0000794 if (!dev->ops || !dev->ops->enable_resources) {
795 printk_err("%s missing enable_resources\n", dev_path(dev));
Eric Biederman83b991a2003-10-11 06:20:25 +0000796 return;
797 }
Eric Biedermane9a271e32003-09-02 03:36:25 +0000798 dev->ops->enable_resources(dev);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000799}
800
Myles Watson032a9652009-05-11 22:24:53 +0000801/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000802 * @brief Reset all of the devices a bus
803 *
804 * Reset all of the devices on a bus and clear the bus's reset_needed flag.
805 *
806 * @param bus pointer to the bus structure
807 *
808 * @return 1 if the bus was successfully reset, 0 otherwise.
809 *
810 */
811int reset_bus(struct bus *bus)
812{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000813 if (bus && bus->dev && bus->dev->ops && bus->dev->ops->reset_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000814 bus->dev->ops->reset_bus(bus);
815 bus->reset_needed = 0;
816 return 1;
817 }
818 return 0;
819}
820
Myles Watson032a9652009-05-11 22:24:53 +0000821/**
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000822 * @brief Scan for devices on a bus.
823 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000824 * If there are bridges on the bus, recursively scan the buses behind the
825 * bridges. If the setting up and tuning of the bus causes a reset to be
826 * required, reset the bus and scan it again.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000827 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000828 * @param busdev Pointer to the bus device.
829 * @param max Current bus number.
830 * @return The maximum bus number found, after scanning all subordinate buses.
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000831 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000832unsigned int scan_bus(struct device *busdev, unsigned int max)
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000833{
834 unsigned int new_max;
835 int do_scan_bus;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000836 if (!busdev || !busdev->enabled || !busdev->ops ||
837 !busdev->ops->scan_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000838 return max;
839 }
Myles Watson29cc9ed2009-07-02 18:56:24 +0000840
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000841 do_scan_bus = 1;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000842 while (do_scan_bus) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000843 int link;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000844 new_max = busdev->ops->scan_bus(busdev, max);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000845 do_scan_bus = 0;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000846 for (link = 0; link < busdev->links; link++) {
847 if (busdev->link[link].reset_needed) {
848 if (reset_bus(&busdev->link[link])) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000849 do_scan_bus = 1;
850 } else {
Myles Watson29cc9ed2009-07-02 18:56:24 +0000851 busdev->bus->reset_needed = 1;
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000852 }
853 }
854 }
855 }
856 return new_max;
857}
858
Li-Ta Loe5266692004-03-23 21:28:05 +0000859/**
Li-Ta Lo04930692004-11-25 17:37:19 +0000860 * @brief Determine the existence of devices and extend the device tree.
861 *
862 * Most of the devices in the system are listed in the mainboard Config.lb
863 * file. The device structures for these devices are generated at compile
864 * time by the config tool and are organized into the device tree. This
865 * function determines if the devices created at compile time actually exist
866 * in the physical system.
867 *
868 * For devices in the physical system but not listed in the Config.lb file,
869 * the device structures have to be created at run time and attached to the
Li-Ta Loe5266692004-03-23 21:28:05 +0000870 * device tree.
871 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000872 * This function starts from the root device 'dev_root', scan the buses in
873 * the system recursively, modify the device tree according to the result of
874 * the probe.
Li-Ta Loe5266692004-03-23 21:28:05 +0000875 *
Li-Ta Lo5782d272004-04-26 17:51:20 +0000876 * This function has no idea how to scan and probe buses and devices at all.
877 * It depends on the bus/device specific scan_bus() method to do it. The
Li-Ta Lo04930692004-11-25 17:37:19 +0000878 * scan_bus() method also has to create the device structure and attach
Myles Watson032a9652009-05-11 22:24:53 +0000879 * it to the device tree.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000880 */
881void dev_enumerate(void)
882{
883 struct device *root;
Eric Biedermane9a271e32003-09-02 03:36:25 +0000884 unsigned subordinate;
Li-Ta Loe5266692004-03-23 21:28:05 +0000885 printk_info("Enumerating buses...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000886 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000887
Myles Watson29cc9ed2009-07-02 18:56:24 +0000888 show_all_devs(BIOS_DEBUG, "Before Device Enumeration.");
Myles Watsoncd5d7562009-05-12 13:43:34 +0000889 printk_debug("Compare with tree...\n");
890
891 show_devs_tree(root, BIOS_DEBUG, 0, 0);
892
Eric Biederman7003ba42004-10-16 06:20:29 +0000893 if (root->chip_ops && root->chip_ops->enable_dev) {
894 root->chip_ops->enable_dev(root);
895 }
Eric Biedermanb78c1972004-10-14 20:54:17 +0000896 if (!root->ops || !root->ops->scan_bus) {
897 printk_err("dev_root missing scan_bus operation");
898 return;
899 }
Yinghai Lu13f1c2a2005-07-08 02:49:49 +0000900 subordinate = scan_bus(root, 0);
Eric Biederman8ca8d762003-04-22 19:02:15 +0000901 printk_info("done\n");
902}
903
Li-Ta Loe5266692004-03-23 21:28:05 +0000904/**
905 * @brief Configure devices on the devices tree.
Myles Watson032a9652009-05-11 22:24:53 +0000906 *
Li-Ta Lo04930692004-11-25 17:37:19 +0000907 * Starting at the root of the device tree, travel it recursively in two
908 * passes. In the first pass, we compute and allocate resources (ranges)
909 * requried by each device. In the second pass, the resources ranges are
910 * relocated to their final position and stored to the hardware.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000911 *
Myles Watson29cc9ed2009-07-02 18:56:24 +0000912 * I/O resources grow upward. MEM resources grow downward.
Li-Ta Lo5782d272004-04-26 17:51:20 +0000913 *
914 * Since the assignment is hierarchical we set the values into the dev_root
Myles Watson032a9652009-05-11 22:24:53 +0000915 * struct.
Eric Biederman8ca8d762003-04-22 19:02:15 +0000916 */
917void dev_configure(void)
918{
Myles Watson29cc9ed2009-07-02 18:56:24 +0000919 struct resource *res;
Eric Biedermanb78c1972004-10-14 20:54:17 +0000920 struct device *root;
Myles Watson29cc9ed2009-07-02 18:56:24 +0000921 struct device *child;
922 int i;
Li-Ta Loe5266692004-03-23 21:28:05 +0000923
Li-Ta Lo54f05f62004-05-14 17:20:29 +0000924 printk_info("Allocating resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000925
Eric Biedermanb78c1972004-10-14 20:54:17 +0000926 root = &dev_root;
Myles Watsoncd5d7562009-05-12 13:43:34 +0000927
Myles Watson29cc9ed2009-07-02 18:56:24 +0000928 /* Each domain should create resources which contain the entire address
929 * space for IO, MEM, and PREFMEM resources in the domain. The
930 * allocation of device resources will be done from this address space.
931 */
Myles Watsoncd5d7562009-05-12 13:43:34 +0000932
Myles Watson29cc9ed2009-07-02 18:56:24 +0000933 /* Read the resources for the entire tree. */
Li-Ta Lo04930692004-11-25 17:37:19 +0000934
935 printk_info("Reading resources...\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000936 read_resources(&root->link[0]);
Li-Ta Lo3a812852004-12-03 22:39:34 +0000937 printk_info("Done reading resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +0000938
Myles Watsoncd5d7562009-05-12 13:43:34 +0000939 print_resource_tree(root, BIOS_DEBUG, "After reading.");
940
Myles Watson29cc9ed2009-07-02 18:56:24 +0000941 /* Compute resources for all domains. */
942 for (child = root->link[0].children; child; child = child->sibling) {
943 if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN))
944 continue;
945 for (i = 0; i < child->resources; i++) {
946 res = &child->resource[i];
947 if (res->flags & IORESOURCE_FIXED)
948 continue;
949 if (res->flags & IORESOURCE_PREFETCH) {
950 compute_resources(&child->link[0],
951 res, MEM_MASK, PREF_TYPE);
952 continue;
953 }
954 if (res->flags & IORESOURCE_MEM) {
955 compute_resources(&child->link[0],
956 res, MEM_MASK, MEM_TYPE);
957 continue;
958 }
959 if (res->flags & IORESOURCE_IO) {
960 compute_resources(&child->link[0],
961 res, IO_MASK, IO_TYPE);
962 continue;
963 }
964 }
965 }
966
967 /* For all domains. */
968 for (child = root->link[0].children; child; child=child->sibling)
969 if (child->path.type == DEVICE_PATH_PCI_DOMAIN)
970 avoid_fixed_resources(child);
971
972 /* Now we need to adjust the resources. MEM resources need to start at
973 * the highest address managable.
Eric Biedermanb78c1972004-10-14 20:54:17 +0000974 */
Myles Watson29cc9ed2009-07-02 18:56:24 +0000975 for (child = root->link[0].children; child; child = child->sibling) {
976 if (child->path.type != DEVICE_PATH_PCI_DOMAIN)
977 continue;
978 for (i = 0; i < child->resources; i++) {
979 res = &child->resource[i];
980 if (!(res->flags & IORESOURCE_MEM) ||
981 res->flags & IORESOURCE_FIXED)
982 continue;
983 res->base = resource_max(res);
984 }
985 }
Eric Biederman5cd81732004-03-11 15:01:31 +0000986
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000987#if CONFIG_CONSOLE_VGA == 1
Myles Watson29cc9ed2009-07-02 18:56:24 +0000988 /* Allocate the VGA I/O resource. */
Myles Watson032a9652009-05-11 22:24:53 +0000989 allocate_vga_resource();
Myles Watsoncd5d7562009-05-12 13:43:34 +0000990 print_resource_tree(root, BIOS_DEBUG, "After VGA.");
Yinghai Lu9e4faef2005-01-14 22:04:49 +0000991#endif
Eric Biederman5cd81732004-03-11 15:01:31 +0000992
Eric Biedermanb78c1972004-10-14 20:54:17 +0000993 /* Store the computed resource allocations into device registers ... */
Li-Ta Lo04930692004-11-25 17:37:19 +0000994 printk_info("Setting resources...\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +0000995 for (child = root->link[0].children; child; child = child->sibling) {
996 if (!(child->path.type == DEVICE_PATH_PCI_DOMAIN))
997 continue;
998 for (i = 0; i < child->resources; i++) {
999 res = &child->resource[i];
1000 if (res->flags & IORESOURCE_FIXED)
1001 continue;
1002 if (res->flags & IORESOURCE_PREFETCH) {
1003 allocate_resources(&child->link[0],
1004 res, MEM_MASK, PREF_TYPE);
1005 continue;
1006 }
1007 if (res->flags & IORESOURCE_MEM) {
1008 allocate_resources(&child->link[0],
1009 res, MEM_MASK, MEM_TYPE);
1010 continue;
1011 }
1012 if (res->flags & IORESOURCE_IO) {
1013 allocate_resources(&child->link[0],
1014 res, IO_MASK, IO_TYPE);
1015 continue;
1016 }
1017 }
1018 }
1019 assign_resources(&root->link[0]);
Li-Ta Lo3a812852004-12-03 22:39:34 +00001020 printk_info("Done setting resources.\n");
Myles Watsoncd5d7562009-05-12 13:43:34 +00001021 print_resource_tree(root, BIOS_DEBUG, "After assigning values.");
Eric Biederman03acab62004-10-14 21:25:53 +00001022
Li-Ta Lo3a812852004-12-03 22:39:34 +00001023 printk_info("Done allocating resources.\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001024}
1025
Li-Ta Loe5266692004-03-23 21:28:05 +00001026/**
1027 * @brief Enable devices on the device tree.
1028 *
1029 * Starting at the root, walk the tree and enable all devices/bridges by
1030 * calling the device's enable_resources() method.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001031 */
1032void dev_enable(void)
1033{
Stefan Reinauerdba3f842006-03-17 22:48:23 +00001034 printk_info("Enabling resources...\n");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001035
1036 /* now enable everything. */
1037 enable_resources(&dev_root);
Li-Ta Loe5266692004-03-23 21:28:05 +00001038
Eric Biederman8ca8d762003-04-22 19:02:15 +00001039 printk_info("done.\n");
1040}
1041
Li-Ta Loe5266692004-03-23 21:28:05 +00001042/**
1043 * @brief Initialize all devices in the global device list.
1044 *
1045 * Starting at the first device on the global device link list,
Li-Ta Lo04930692004-11-25 17:37:19 +00001046 * walk the list and call the device's init() method to do deivce
1047 * specific setup.
Eric Biederman8ca8d762003-04-22 19:02:15 +00001048 */
1049void dev_initialize(void)
1050{
1051 struct device *dev;
1052
1053 printk_info("Initializing devices...\n");
Myles Watson29cc9ed2009-07-02 18:56:24 +00001054 for (dev = all_devices; dev; dev = dev->next) {
Myles Watson032a9652009-05-11 22:24:53 +00001055 if (dev->enabled && !dev->initialized &&
Myles Watson29cc9ed2009-07-02 18:56:24 +00001056 dev->ops && dev->ops->init) {
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001057 if (dev->path.type == DEVICE_PATH_I2C) {
Myles Watson29cc9ed2009-07-02 18:56:24 +00001058 printk_debug("smbus: %s[%d]->",
1059 dev_path(dev->bus->dev),
1060 dev->bus->link);
Yinghai Lu13f1c2a2005-07-08 02:49:49 +00001061 }
1062 printk_debug("%s init\n", dev_path(dev));
1063 dev->initialized = 1;
1064 dev->ops->init(dev);
1065 }
1066 }
Eric Biederman8ca8d762003-04-22 19:02:15 +00001067 printk_info("Devices initialized\n");
Myles Watsoncd5d7562009-05-12 13:43:34 +00001068 show_all_devs(BIOS_DEBUG, "After init.");
Eric Biederman8ca8d762003-04-22 19:02:15 +00001069}