- O2, enums, and switch statements work in romcc
[coreboot.git] / src / devices / chip.c
1 /* chips are arbitrary chips (superio, southbridge, etc.)
2  * They have private structures that define chip resources and default 
3  * settings. They have four externally visible functions for control. 
4  * They have a generic component which applies to all chips for 
5  * path, etc. 
6  */
7
8 #include <console/console.h>
9 #include <device/chip.h>
10 #include <device/pci.h>
11
12 void
13 chip_configure(struct chip *root, enum chip_pass pass)
14 {
15         struct chip *c;
16
17         for (c = root; c; c = c->next) {
18                 if (c->control && c->control->enable)
19                         c->control->enable(c, pass);
20         }
21
22         for (c = root; c; c = c->next) {
23                 if (c->children)
24                         chip_configure(c->children, pass);
25         }
26 }
27
28 /** Convert a static struct chip structure to a set of dynamic device structures.
29  * @param chip Static chip structure to start with.
30  */
31
32 void chip_enumerate(struct chip *chip)
33 {
34         struct chip *child;
35         device_t dev;
36         int link;
37         int i;
38         dev = 0;
39         link = 0;
40 #if 1
41         if (chip->control && chip->control->name) {
42                 printk_debug("Enumerating: %s\n", chip->control->name);
43         }
44 #endif
45         for(i = 0; i < MAX_CHIP_PATHS; i++) {
46                 int identical_paths;
47                 identical_paths = 
48                         (i > 0) &&
49                         (path_eq(&chip->path[i - 1].path, &chip->path[i].path));
50                 if (!identical_paths) {
51                         struct bus *parent;
52                         int bus;
53                         link = 0;
54                         dev = 0;
55                         parent = chip->bus;
56                         switch(chip->path[i].path.type) {
57                         case DEVICE_PATH_NONE:
58                                 break;
59                         case DEVICE_PATH_PCI:
60                                 bus = chip->path[i].path.u.pci.bus;
61                                 if (bus != 0) {
62                                         device_t dev;
63                                         int i = 1;
64                                         dev = chip->dev;
65                                         while(dev && (i != bus)) {
66                                                 dev = dev->next;
67                                                 i++;
68                                         }
69                                         if ((i == bus) && dev) {
70                                                 parent = &dev->link[0];
71                                         }
72                                 }
73                                 /* Fall through */
74                         default:
75                                 dev = alloc_dev(parent, &chip->path[i].path);
76                                 break;
77                         }
78                 }
79                 else {
80                         link += 1;
81                 }
82                 if (dev) {
83                         printk_spew("path (%p) %s %s", dev, dev_path(dev), identical_paths?"identical":"");
84                         printk_spew(" parent: (%p) %s\n",dev->bus->dev,  dev_path(dev->bus->dev));
85                         dev->chip = chip;
86                         dev->enable = chip->path[i].enable;
87                         dev->links = link + 1;
88                         for(child = chip->children; child; child = child->next) {
89                                 if (!child->bus && child->link == i) {
90                                         child->bus = &dev->link[link];
91                                 }
92                         }
93                 }
94                 if (dev && !chip->dev) {
95                         chip->dev = dev;
96                 }
97         }
98         for(child = chip->children; child; child = child->next) {
99                 if (!child->bus) {
100                         child->bus = &chip->dev->link[0];
101                 }
102         }
103 }
104
105 static void enumerate_static_device_chain(struct chip *root)
106 {
107         struct chip *chip;
108         for(chip = root; chip; chip = chip->next) {
109                 void (*enumerate)(struct chip *chip);
110                 enumerate = chip_enumerate;
111                 if (chip->control && chip->control->enumerate) {
112                         enumerate = chip->control->enumerate;
113                 }
114                 enumerate(chip);
115         }
116
117         for(chip = root; chip; chip = chip->next) {
118                 if (chip->children) {
119                         enumerate_static_device_chain(chip->children);
120                 }
121         }
122 }
123
124 void enumerate_static_devices(void)
125 {
126         enumerate_static_device_chain(&static_root);
127 }