1 /* This should be done by Eric
2 2004.12 yhlu add dual core support
3 2005.01 yhlu add support move apic before pci_domain in MB Config.lb
4 2005.02 yhlu add e0 memory hole support
7 #include <console/console.h>
10 #include <device/device.h>
11 #include <device/pci.h>
12 #include <device/pci_ids.h>
13 #include <device/hypertransport.h>
19 #include <cpu/x86/lapic.h>
21 #if CONFIG_LOGICAL_CPUS==1
22 #include <cpu/amd/dualcore.h>
23 #include <pc80/mc146818rtc.h>
27 #include "root_complex/chip.h"
28 #include "northbridge.h"
31 #if K8_E0_MEM_HOLE_SIZEK != 0
32 #include "./cpu_rev.c"
36 static device_t __f0_dev[FX_DEVS];
37 static device_t __f1_dev[FX_DEVS];
40 static void debug_fx_devs(void)
43 for(i = 0; i < FX_DEVS; i++) {
47 printk_debug("__f0_dev[%d]: %s bus: %p\n",
48 i, dev_path(dev), dev->bus);
52 printk_debug("__f1_dev[%d]: %s bus: %p\n",
53 i, dev_path(dev), dev->bus);
59 static void get_fx_devs(void)
65 for(i = 0; i < FX_DEVS; i++) {
66 __f0_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 0));
67 __f1_dev[i] = dev_find_slot(0, PCI_DEVFN(0x18 + i, 1));
70 die("Cannot find 0:0x18.1\n");
74 static uint32_t f1_read_config32(unsigned reg)
77 return pci_read_config32(__f1_dev[0], reg);
80 static void f1_write_config32(unsigned reg, uint32_t value)
84 for(i = 0; i < FX_DEVS; i++) {
87 if (dev && dev->enabled) {
88 pci_write_config32(dev, reg, value);
93 static unsigned int amdk8_nodeid(device_t dev)
95 return (dev->path.u.pci.devfn >> 3) - 0x18;
98 static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
102 nodeid = amdk8_nodeid(dev);
104 printk_debug("%s amdk8_scan_chains max: %d starting...\n",
107 for(link = 0; link < dev->links; link++) {
109 uint32_t busses, config_busses;
110 unsigned free_reg, config_reg;
111 dev->link[link].cap = 0x80 + (link *0x20);
113 link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
114 } while(link_type & ConnectionPending);
115 if (!(link_type & LinkConnected)) {
119 link_type = pci_read_config32(dev, dev->link[link].cap + 0x18);
120 } while(!(link_type & InitComplete));
121 if (!(link_type & NonCoherent)) {
124 /* See if there is an available configuration space mapping
125 * register in function 1.
128 for(config_reg = 0xe0; config_reg <= 0xec; config_reg += 4) {
130 config = f1_read_config32(config_reg);
131 if (!free_reg && ((config & 3) == 0)) {
132 free_reg = config_reg;
135 if (((config & 3) == 3) &&
136 (((config >> 4) & 7) == nodeid) &&
137 (((config >> 8) & 3) == link)) {
141 if (free_reg && (config_reg > 0xec)) {
142 config_reg = free_reg;
144 /* If we can't find an available configuration space mapping
145 * register skip this bus
147 if (config_reg > 0xec) {
151 /* Set up the primary, secondary and subordinate bus numbers.
152 * We have no idea how many busses are behind this bridge yet,
153 * so we set the subordinate bus number to 0xff for the moment.
155 dev->link[link].secondary = ++max;
156 dev->link[link].subordinate = 0xff;
158 /* Read the existing primary/secondary/subordinate bus
159 * number configuration.
161 busses = pci_read_config32(dev, dev->link[link].cap + 0x14);
162 config_busses = f1_read_config32(config_reg);
164 /* Configure the bus numbers for this bridge: the configuration
165 * transactions will not be propagates by the bridge if it is
166 * not correctly configured
168 busses &= 0xff000000;
169 busses |= (((unsigned int)(dev->bus->secondary) << 0) |
170 ((unsigned int)(dev->link[link].secondary) << 8) |
171 ((unsigned int)(dev->link[link].subordinate) << 16));
172 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
174 config_busses &= 0x000fc88;
176 (3 << 0) | /* rw enable, no device compare */
177 (( nodeid & 7) << 4) |
178 (( link & 3 ) << 8) |
179 ((dev->link[link].secondary) << 16) |
180 ((dev->link[link].subordinate) << 24);
181 f1_write_config32(config_reg, config_busses);
184 printk_debug("%s Hyper transport scan link: %d max: %d\n",
185 dev_path(dev), link, max);
187 /* Now we can scan all of the subordinate busses i.e. the
188 * chain on the hypertranport link
190 max = hypertransport_scan_chain(&dev->link[link], 0, 0xbf, max);
193 printk_debug("%s Hyper transport scan link: %d new max: %d\n",
194 dev_path(dev), link, max);
197 /* We know the number of busses behind this bridge. Set the
198 * subordinate bus number to it's real value
200 dev->link[link].subordinate = max;
201 busses = (busses & 0xff00ffff) |
202 ((unsigned int) (dev->link[link].subordinate) << 16);
203 pci_write_config32(dev, dev->link[link].cap + 0x14, busses);
205 config_busses = (config_busses & 0x00ffffff) |
206 (dev->link[link].subordinate << 24);
207 f1_write_config32(config_reg, config_busses);
210 printk_debug("%s Hypertransport scan link: %d done\n",
211 dev_path(dev), link);
215 printk_debug("%s amdk8_scan_chains max: %d done\n",
221 static int reg_useable(unsigned reg,
222 device_t goal_dev, unsigned goal_nodeid, unsigned goal_link)
224 struct resource *res;
225 unsigned nodeid, link;
228 for(nodeid = 0; !res && (nodeid < 8); nodeid++) {
230 dev = __f0_dev[nodeid];
231 for(link = 0; !res && (link < 3); link++) {
232 res = probe_resource(dev, 0x100 + (reg | link));
238 if ( (goal_link == (link - 1)) &&
239 (goal_nodeid == (nodeid - 1)) &&
245 printk_debug("reg: %02x result: %d gnodeid: %u glink: %u nodeid: %u link: %u\n",
247 goal_nodeid, goal_link,
253 static struct resource *amdk8_find_iopair(device_t dev, unsigned nodeid, unsigned link)
255 struct resource *resource;
256 unsigned free_reg, reg;
259 for(reg = 0xc0; reg <= 0xd8; reg += 0x8) {
261 result = reg_useable(reg, dev, nodeid, link);
263 /* I have been allocated this one */
266 else if (result > 1) {
267 /* I have a free register pair */
275 resource = new_resource(dev, 0x100 + (reg | link));
280 static struct resource *amdk8_find_mempair(device_t dev, unsigned nodeid, unsigned link)
282 struct resource *resource;
283 unsigned free_reg, reg;
286 for(reg = 0x80; reg <= 0xb8; reg += 0x8) {
288 result = reg_useable(reg, dev, nodeid, link);
290 /* I have been allocated this one */
293 else if (result > 1) {
294 /* I have a free register pair */
302 resource = new_resource(dev, 0x100 + (reg | link));
307 static void amdk8_link_read_bases(device_t dev, unsigned nodeid, unsigned link)
309 struct resource *resource;
311 /* Initialize the io space constraints on the current bus */
312 resource = amdk8_find_iopair(dev, nodeid, link);
316 resource->align = log2(HT_IO_HOST_ALIGN);
317 resource->gran = log2(HT_IO_HOST_ALIGN);
318 resource->limit = 0xffffUL;
319 resource->flags = IORESOURCE_IO;
320 compute_allocate_resource(&dev->link[link], resource,
321 IORESOURCE_IO, IORESOURCE_IO);
324 /* Initialize the prefetchable memory constraints on the current bus */
325 resource = amdk8_find_mempair(dev, nodeid, link);
329 resource->align = log2(HT_MEM_HOST_ALIGN);
330 resource->gran = log2(HT_MEM_HOST_ALIGN);
331 resource->limit = 0xffffffffffULL;
332 resource->flags = IORESOURCE_MEM | IORESOURCE_PREFETCH;
333 compute_allocate_resource(&dev->link[link], resource,
334 IORESOURCE_MEM | IORESOURCE_PREFETCH,
335 IORESOURCE_MEM | IORESOURCE_PREFETCH);
338 /* Initialize the memory constraints on the current bus */
339 resource = amdk8_find_mempair(dev, nodeid, link);
343 resource->align = log2(HT_MEM_HOST_ALIGN);
344 resource->gran = log2(HT_MEM_HOST_ALIGN);
345 resource->limit = 0xffffffffffULL;
346 resource->flags = IORESOURCE_MEM;
347 compute_allocate_resource(&dev->link[link], resource,
348 IORESOURCE_MEM | IORESOURCE_PREFETCH,
353 static void amdk8_read_resources(device_t dev)
355 unsigned nodeid, link;
356 nodeid = amdk8_nodeid(dev);
357 for(link = 0; link < dev->links; link++) {
358 if (dev->link[link].children) {
359 amdk8_link_read_bases(dev, nodeid, link);
364 static void amdk8_set_resource(device_t dev, struct resource *resource, unsigned nodeid)
366 resource_t rbase, rend;
370 /* Make certain the resource has actually been set */
371 if (!(resource->flags & IORESOURCE_ASSIGNED)) {
375 /* If I have already stored this resource don't worry about it */
376 if (resource->flags & IORESOURCE_STORED) {
380 /* Only handle PCI memory and IO resources */
381 if (!(resource->flags & (IORESOURCE_MEM | IORESOURCE_IO)))
384 /* Ensure I am actually looking at a resource of function 1 */
385 if (resource->index < 0x100) {
388 /* Get the base address */
389 rbase = resource->base;
391 /* Get the limit (rounded up) */
392 rend = resource_end(resource);
394 /* Get the register and link */
395 reg = resource->index & 0xfc;
396 link = resource->index & 3;
398 if (resource->flags & IORESOURCE_IO) {
399 uint32_t base, limit;
400 compute_allocate_resource(&dev->link[link], resource,
401 IORESOURCE_IO, IORESOURCE_IO);
402 base = f1_read_config32(reg);
403 limit = f1_read_config32(reg + 0x4);
405 base |= rbase & 0x01fff000;
408 limit |= rend & 0x01fff000;
409 limit |= (link & 3) << 4;
410 limit |= (nodeid & 7);
412 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
413 printk_spew("%s, enabling legacy VGA IO forwarding for %s link %s\n",
414 __func__, dev_path(dev), link);
415 base |= PCI_IO_BASE_VGA_EN;
417 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
418 base |= PCI_IO_BASE_NO_ISA;
421 f1_write_config32(reg + 0x4, limit);
422 f1_write_config32(reg, base);
424 else if (resource->flags & IORESOURCE_MEM) {
425 uint32_t base, limit;
426 compute_allocate_resource(&dev->link[link], resource,
427 IORESOURCE_MEM | IORESOURCE_PREFETCH,
428 resource->flags & (IORESOURCE_MEM | IORESOURCE_PREFETCH));
429 base = f1_read_config32(reg);
430 limit = f1_read_config32(reg + 0x4);
432 base |= (rbase >> 8) & 0xffffff00;
435 limit |= (rend >> 8) & 0xffffff00;
436 limit |= (link & 3) << 4;
437 limit |= (nodeid & 7);
438 f1_write_config32(reg + 0x4, limit);
439 f1_write_config32(reg, base);
441 resource->flags |= IORESOURCE_STORED;
442 sprintf(buf, " <node %d link %d>",
444 report_resource_stored(dev, resource, buf);
449 * I tried to reuse the resource allocation code in amdk8_set_resource()
450 * but it is too diffcult to deal with the resource allocation magic.
452 static void amdk8_create_vga_resource(device_t dev, unsigned nodeid)
454 struct resource *resource;
456 uint32_t base, limit;
459 /* find out which link the VGA card is connected,
460 * we only deal with the 'first' vga card */
461 for (link = 0; link < dev->links; link++) {
462 if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_VGA) {
467 printk_spew("%s: link %d has VGA device\n", __func__, link);
469 /* no VGA card installed */
470 if (link == dev->links)
473 /* allocate a temp resrouce for legacy VGA buffer */
474 resource = amdk8_find_mempair(dev, nodeid, link);
475 resource->base = 0xa0000;
476 resource->size = 0x20000;
478 /* write the resource to the hardware */
479 reg = resource->index & 0xfc;
480 base = f1_read_config32(reg);
481 limit = f1_read_config32(reg + 0x4);
483 base |= (resource->base >> 8) & 0xffffff00;
486 limit |= ((resource->base + resource->size) >> 8) & 0xffffff00;
487 limit |= (resource->index & 3) << 4;
488 limit |= (nodeid & 7);
489 f1_write_config32(reg + 0x4, limit);
490 f1_write_config32(reg, base);
492 /* release the temp resource */
497 static void amdk8_set_resources(device_t dev)
499 unsigned nodeid, link;
502 /* Find the nodeid */
503 nodeid = amdk8_nodeid(dev);
505 amdk8_create_vga_resource(dev, nodeid);
507 /* Set each resource we have found */
508 for(i = 0; i < dev->resources; i++) {
509 amdk8_set_resource(dev, &dev->resource[i], nodeid);
512 for(link = 0; link < dev->links; link++) {
514 bus = &dev->link[link];
516 assign_resources(bus);
521 static void amdk8_enable_resources(device_t dev)
523 pci_dev_enable_resources(dev);
524 enable_childrens_resources(dev);
527 static void mcf0_control_init(struct device *dev)
530 printk_debug("NB: Function 0 Misc Control.. ");
533 printk_debug("done.\n");
537 static struct device_operations northbridge_operations = {
538 .read_resources = amdk8_read_resources,
539 .set_resources = amdk8_set_resources,
540 .enable_resources = amdk8_enable_resources,
541 .init = mcf0_control_init,
542 .scan_bus = amdk8_scan_chains,
548 static struct pci_driver mcf0_driver __pci_driver = {
549 .ops = &northbridge_operations,
550 .vendor = PCI_VENDOR_ID_AMD,
554 #if CONFIG_CHIP_NAME == 1
556 struct chip_operations northbridge_amd_amdk8_ops = {
557 CHIP_NAME("AMD K8 Northbridge")
563 static void pci_domain_read_resources(device_t dev)
565 struct resource *resource;
568 /* Find the already assigned resource pairs */
570 for(reg = 0x80; reg <= 0xd8; reg+= 0x08) {
571 uint32_t base, limit;
572 base = f1_read_config32(reg);
573 limit = f1_read_config32(reg + 0x04);
574 /* Is this register allocated? */
575 if ((base & 3) != 0) {
576 unsigned nodeid, link;
579 link = (limit >> 4) & 3;
580 dev = __f0_dev[nodeid];
582 /* Reserve the resource */
583 struct resource *resource;
584 resource = new_resource(dev, 0x100 + (reg | link));
592 /* Initialize the system wide io space constraints */
593 resource = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
594 resource->base = 0x400;
595 resource->limit = 0xffffUL;
596 resource->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
598 /* Initialize the system wide memory resources constraints */
599 resource = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
600 resource->limit = 0xfcffffffffULL;
601 resource->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
604 static void ram_resource(device_t dev, unsigned long index,
605 unsigned long basek, unsigned long sizek)
607 struct resource *resource;
612 resource = new_resource(dev, index);
613 resource->base = ((resource_t)basek) << 10;
614 resource->size = ((resource_t)sizek) << 10;
615 resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \
616 IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED;
619 static void tolm_test(void *gp, struct device *dev, struct resource *new)
621 struct resource **best_p = gp;
622 struct resource *best;
624 if (!best || (best->base > new->base)) {
630 static uint32_t find_pci_tolm(struct bus *bus)
632 struct resource *min;
635 search_bus_resources(bus, IORESOURCE_MEM, IORESOURCE_MEM, tolm_test, &min);
637 if (min && tolm > min->base) {
643 static void pci_domain_set_resources(device_t dev)
645 unsigned long mmio_basek;
649 pci_tolm = find_pci_tolm(&dev->link[0]);
651 #warning "FIXME handle interleaved nodes"
652 mmio_basek = pci_tolm >> 10;
653 /* Round mmio_basek to something the processor can support */
654 mmio_basek &= ~((1 << 6) -1);
657 #warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole"
658 /* Round the mmio hold to 64M */
659 mmio_basek &= ~((64*1024) - 1);
662 #if K8_E0_MEM_HOLE_SIZEK != 0
663 if (!is_cpu_pre_e0())
664 for (i = 0; i < 8; i++) {
666 base = f1_read_config32(0x40 + (i << 3));
667 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
671 base = pci_read_config32(__f1_dev[i], 0xf0);
672 if((base & 1)==0) continue;
675 if (mmio_basek > base) {
678 break; // only one hole
683 for(i = 0; i < 8; i++) {
684 uint32_t base, limit;
685 unsigned basek, limitk, sizek;
686 base = f1_read_config32(0x40 + (i << 3));
687 limit = f1_read_config32(0x44 + (i << 3));
688 if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) {
691 basek = (base & 0xffff0000) >> 2;
692 limitk = ((limit + 0x00010000) & 0xffff0000) >> 2;
693 sizek = limitk - basek;
695 /* see if we need a hole from 0xa0000 to 0xbffff */
696 if ((basek < ((8*64)+(8*16))) && (sizek > ((8*64)+(16*16)))) {
697 ram_resource(dev, idx++, basek, ((8*64)+(8*16)) - basek);
698 basek = (8*64)+(16*16);
699 sizek = limitk - ((8*64)+(16*16));
704 /* See if I need to split the region to accomodate pci memory space */
705 if ((basek < mmio_basek) && (limitk > mmio_basek)) {
706 if (basek < mmio_basek) {
708 pre_sizek = mmio_basek - basek;
709 ram_resource(dev, idx++, basek, pre_sizek);
713 if ((basek + sizek) <= 4*1024*1024) {
718 sizek -= (4*1024*1024 - mmio_basek);
721 ram_resource(dev, idx++, basek, sizek);
723 assign_resources(&dev->link[0]);
726 static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max)
730 /* Unmap all of the HT chains */
731 for(reg = 0xe0; reg <= 0xec; reg += 4) {
732 f1_write_config32(reg, 0);
734 max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
736 /* Tune the hypertransport transaction for best performance.
737 * Including enabling relaxed ordering if it is safe.
740 for(i = 0; i < FX_DEVS; i++) {
742 f0_dev = __f0_dev[i];
743 if (f0_dev && f0_dev->enabled) {
746 httc = pci_read_config32(f0_dev, HT_TRANSACTION_CONTROL);
747 httc &= ~HTTC_RSP_PASS_PW;
748 if (!dev->link[0].disable_relaxed_ordering) {
749 httc |= HTTC_RSP_PASS_PW;
751 printk_spew("%s passpw: %s\n",
753 (!dev->link[0].disable_relaxed_ordering)?
754 "enabled":"disabled");
755 pci_write_config32(f0_dev, HT_TRANSACTION_CONTROL, httc);
761 static struct device_operations pci_domain_ops = {
762 .read_resources = pci_domain_read_resources,
763 .set_resources = pci_domain_set_resources,
764 .enable_resources = enable_childrens_resources,
766 .scan_bus = pci_domain_scan_bus,
767 .ops_pci_bus = &pci_cf8_conf1,
770 #define APIC_ID_OFFSET 0x10
772 static unsigned int cpu_bus_scan(device_t dev, unsigned int max)
780 int enable_apic_ext_id;
782 #if CONFIG_LOGICAL_CPUS == 1
783 int e0_later_single_core;
784 int disable_siblings;
788 enable_apic_ext_id = 0;
791 /* Find the bootstrap processors apicid */
792 bsp_apic_id = lapicid();
794 /* See if I will enable extended ids' */
795 apic_id_offset = bsp_apic_id;
797 #if CONFIG_LOGICAL_CPUS == 1
798 disable_siblings = !CONFIG_LOGICAL_CPUS;
799 get_option(&disable_siblings, "dual_core");
801 // for pre_e0, nb_cfg_54 can not be set, ( even set, when you read it still be 0)
802 // How can I get the nb_cfg_54 of every node' nb_cfg_54 in bsp??? and differ d0 and e0 single core
804 nb_cfg_54 = read_nb_cfg_54();
806 dev_mc = dev_find_slot(0, PCI_DEVFN(0x18, 0));
808 die("0:18.0 not found?");
810 if (pci_read_config32(dev_mc, 0x68) & (HTTC_APIC_EXT_ID|HTTC_APIC_EXT_BRD_CST))
812 enable_apic_ext_id = 1;
813 if (apic_id_offset == 0) {
814 /* bsp apic id is not changed */
815 apic_id_offset = APIC_ID_OFFSET;
819 /* Find which cpus are present */
820 cpu_bus = &dev->link[0];
821 for(i = 0; i < 8; i++) {
823 struct device_path cpu_path;
825 /* Find the cpu's pci device */
826 dev = dev_find_slot(0, PCI_DEVFN(0x18 + i, 3));
828 /* If I am probing things in a weird order
829 * ensure all of the cpu's pci devices are found.
832 for(j = 0; j <= 3; j++) {
833 dev = pci_probe_dev(NULL, dev_mc->bus,
834 PCI_DEVFN(0x18 + i, j));
838 #if CONFIG_LOGICAL_CPUS == 1
839 e0_later_single_core = 0;
840 if ((!disable_siblings) && dev && dev->enabled) {
841 j = (pci_read_config32(dev, 0xe8) >> 12) & 3; // dev is func 3
842 printk_debug(" %s siblings=%d\r\n", dev_path(dev), j);
845 // For e0 single core if nb_cfg_54 is set, apicid will be 0, 2, 4....
846 // ----> you can mixed single core e0 and dual core e0 at any sequence
847 // That is the typical case
850 e0_later_single_core = is_e0_later_in_bsp(i); // single core
852 e0_later_single_core = 0;
854 if(e0_later_single_core) {
855 printk_debug("\tFound e0 single core\r\n");
860 //actually we can't be here, because d0 nb_cfg_54 can not be set
861 //even worse is_e0_later_in_bsp() can not find out if it is d0 or e0
863 die("When NB_CFG_54 is set, if you want to mix e0 (single core and dual core) and single core(pre e0) CPUs, you need to put all the single core (pre e0) CPUs before all the (e0 single or dual core) CPUs\r\n");
873 #if CONFIG_LOGICAL_CPUS==1
874 for (j = 0; j <= (e0_later_single_core?0:siblings); j++ ) {
876 for (j = 0; j <= siblings; j++ ) {
878 /* Build the cpu device path */
879 cpu_path.type = DEVICE_PATH_APIC;
880 cpu_path.u.apic.apic_id = i * (nb_cfg_54?(siblings+1):1) + j * (nb_cfg_54?1:8);
882 /* See if I can find the cpu */
883 cpu = find_dev_path(cpu_bus, &cpu_path);
885 /* Enable the cpu if I have the processor */
886 if (dev && dev->enabled) {
888 cpu = alloc_dev(cpu_bus, &cpu_path);
895 /* Disable the cpu if I don't have the processor */
896 if (cpu && (!dev || !dev->enabled)) {
900 /* Report what I have done */
902 if(enable_apic_ext_id) {
903 if(cpu->path.u.apic.apic_id<apic_id_offset) { //all add offset except bsp core0
904 if( (cpu->path.u.apic.apic_id > siblings) || (bsp_apic_id!=0) )
905 cpu->path.u.apic.apic_id += apic_id_offset;
908 printk_debug("CPU: %s %s\n",
909 dev_path(cpu), cpu->enabled?"enabled":"disabled");
916 static void cpu_bus_init(device_t dev)
918 initialize_cpus(&dev->link[0]);
921 static void cpu_bus_noop(device_t dev)
925 static struct device_operations cpu_bus_ops = {
926 .read_resources = cpu_bus_noop,
927 .set_resources = cpu_bus_noop,
928 .enable_resources = cpu_bus_noop,
929 .init = cpu_bus_init,
930 .scan_bus = cpu_bus_scan,
933 static void root_complex_enable_dev(struct device *dev)
935 /* Set the operations if it is a special bus type */
936 if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) {
937 dev->ops = &pci_domain_ops;
939 else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) {
940 dev->ops = &cpu_bus_ops;
944 struct chip_operations northbridge_amd_amdk8_root_complex_ops = {
945 CHIP_NAME("AMD K8 Root Complex")
946 .enable_dev = root_complex_enable_dev,