blob: d283d85526a8513a8a0cf92bffdd6dc5a66c6e2e [file] [log] [blame]
Yinghai Luafd34e62006-02-16 17:22:19 +00001#include <console/console.h>
2#include <arch/smp/mpspec.h>
3#include <arch/io.h>
4#include <device/pci.h>
5#include <string.h>
6#include <stdint.h>
Patrick Georgie1667822012-05-05 15:29:32 +02007#if CONFIG_LOGICAL_CPUS
Stefan Reinauer9a16e3e2010-03-29 14:45:36 +00008#include <cpu/amd/multicore.h>
Yinghai Luafd34e62006-02-16 17:22:19 +00009#endif
Yinghai Lu6d74d762006-10-04 23:57:49 +000010#include <cpu/amd/amdk8_sysconf.h>
Yinghai Luafd34e62006-02-16 17:22:19 +000011
Yinghai Luafd34e62006-02-16 17:22:19 +000012extern unsigned char bus_bcm5780[7];
13extern unsigned char bus_bcm5785_0;
14extern unsigned char bus_bcm5785_1;
15extern unsigned char bus_bcm5785_1_1;
16extern unsigned apicid_bcm5785[3];
17
18extern unsigned sbdn2;
19
Myles Watson08e0fb82010-03-22 16:33:25 +000020static void *smp_write_config_table(void *v)
Yinghai Luafd34e62006-02-16 17:22:19 +000021{
Yinghai Luafd34e62006-02-16 17:22:19 +000022 struct mp_config_table *mc;
Patrick Georgi5244e1b2010-11-21 14:41:07 +000023 int i, bus_isa;
Yinghai Luafd34e62006-02-16 17:22:19 +000024
25 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
Yinghai Luafd34e62006-02-16 17:22:19 +000026
Patrick Georgic8feedd2012-02-16 18:43:25 +010027 mptable_init(mc, LOCAL_APIC_ADDR);
Yinghai Luafd34e62006-02-16 17:22:19 +000028
29 smp_write_processors(mc);
30
31 get_bus_conf();
32
Patrick Georgi5244e1b2010-11-21 14:41:07 +000033 mptable_write_buses(mc, NULL, &bus_isa);
Yinghai Luafd34e62006-02-16 17:22:19 +000034
35/*I/O APICs: APIC ID Version State Address*/
36 {
37 device_t dev = 0;
Yinghai Luafd34e62006-02-16 17:22:19 +000038 struct resource *res;
39 for(i=0; i<3; i++) {
40 dev = dev_find_device(0x1166, 0x0235, dev);
41 if (dev) {
42 res = find_resource(dev, PCI_BASE_ADDRESS_0);
43 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080044 smp_write_ioapic(mc, apicid_bcm5785[i],
45 0x11,
46 res2mmio(res, 0, 0));
Yinghai Luafd34e62006-02-16 17:22:19 +000047 }
48 }
49 }
Stefan Reinauer14e22772010-04-27 06:56:47 +000050
Yinghai Luafd34e62006-02-16 17:22:19 +000051 }
Stefan Reinauer14e22772010-04-27 06:56:47 +000052
Patrick Georgic5b87c82010-05-20 15:28:19 +000053 mptable_add_isa_interrupts(mc, bus_isa, apicid_bcm5785[0], 0);
Yinghai Luafd34e62006-02-16 17:22:19 +000054
Stefan Reinauer14e22772010-04-27 06:56:47 +000055//IDE
Yinghai Luafd34e62006-02-16 17:22:19 +000056 outb(0x02, 0xc00); outb(0x0e, 0xc01);
57
Yinghai Lu6d74d762006-10-04 23:57:49 +000058 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_bcm5785_0, ((1+sysconf.sbdn)<<2)|1, apicid_bcm5785[0], 0xe); // IDE
Yinghai Luafd34e62006-02-16 17:22:19 +000059
60//SATA
61 outb(0x07, 0xc00); outb(0x0f, 0xc01);
62 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_1, (0x0e<<2)|0, apicid_bcm5785[0], 0xf);
Stefan Reinauer14e22772010-04-27 06:56:47 +000063
Yinghai Luafd34e62006-02-16 17:22:19 +000064//USB
65 outb(0x01, 0xc00); outb(0x0a, 0xc01);
66 for(i=0;i<3;i++) {
Yinghai Lu6d74d762006-10-04 23:57:49 +000067 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_0, ((2+sysconf.sbdn)<<2)|i, apicid_bcm5785[0], 0xa); //
Yinghai Luafd34e62006-02-16 17:22:19 +000068 }
69
Stefan Reinauer14e22772010-04-27 06:56:47 +000070
Yinghai Luafd34e62006-02-16 17:22:19 +000071
72 /* enable int */
73 /* why here? must get the BAR and PCI command bit 1 set before enable it ....*/
74 {
75 device_t dev;
76 dev = dev_find_device(0x1166, 0x0205, 0);
77 if(dev) {
78 uint32_t dword;
79 dword = pci_read_config32(dev, 0x6c);
80 dword |= (1<<4); // enable interrupts
81 pci_write_config32(dev, 0x6c, dword);
82
83 }
84
85 }
86
87//First pci-x slot (on bcm5785) under bus_bcm5785_1:d.0
88 for(i=0;i<4;i++) {
89 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_1_1, (4<<2)|i, apicid_bcm5785[1], 2 + (0+i)%4); //
90 }
91
92
Stefan Reinauer14e22772010-04-27 06:56:47 +000093//pci slot (on bcm5785)
Yinghai Luafd34e62006-02-16 17:22:19 +000094 for(i=0;i<4;i++) {
95 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_0, (4<<2)|i, apicid_bcm5785[1], i%2); //
96 }
97
98
Stefan Reinauer14e22772010-04-27 06:56:47 +000099//onboard ati
Yinghai Luafd34e62006-02-16 17:22:19 +0000100 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5785_0, (5<<2)|0, apicid_bcm5785[1], 0x1);
101
102//PCI-X on bcm5780
103 for(i=0;i<4;i++) {
104 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[1], (4<<2)|i, apicid_bcm5785[1], 6 + (0+i)%4); //
105 }
106
107 for(i=0;i<4;i++) {
108 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[1], (5<<2)|i, apicid_bcm5785[1], 6 + (1+i)%4); //
109 }
110
111//onboard Broadcom
112 for(i=0;i<2;i++) {
113 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[2], (4<<2)|i, apicid_bcm5785[1], 0xa + (0+i)%4); //
114 }
115
116
117// First PCI-E x8
118 for(i=0;i<4;i++) {
119 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[5], (0<<2)|i, apicid_bcm5785[1], 0xe); //
120 }
121
122
Stefan Reinauer14e22772010-04-27 06:56:47 +0000123// Second PCI-E x8
Yinghai Luafd34e62006-02-16 17:22:19 +0000124 for(i=0;i<4;i++) {
125 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[3], (0<<2)|i, apicid_bcm5785[1], 0xc); //
126 }
127
128
129// Third PCI-E x1
130 for(i=0;i<4;i++) {
131 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_bcm5780[4], (0<<2)|i, apicid_bcm5785[1], 0xd); //
132 }
133
134/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Patrick Georgi6eb7a532011-10-07 21:42:52 +0200135 mptable_lintsrc(mc, bus_isa);
Yinghai Luafd34e62006-02-16 17:22:19 +0000136 /* There is no extension information... */
137
138 /* Compute the checksums */
Patrick Georgib0a9c5c2011-10-07 23:01:55 +0200139 return mptable_finalize(mc);
Yinghai Luafd34e62006-02-16 17:22:19 +0000140}
141
142unsigned long write_smp_table(unsigned long addr)
143{
144 void *v;
Patrick Georgic75c79b2011-10-07 22:41:07 +0200145 v = smp_write_floating_table(addr, 0);
Yinghai Luafd34e62006-02-16 17:22:19 +0000146 return (unsigned long)smp_write_config_table(v);
147}