Factor out common mptable code to mptable_init().
[coreboot.git] / src / mainboard / amd / serengeti_cheetah / mptable.c
1 #include <console/console.h>
2 #include <arch/smp/mpspec.h>
3 #include <arch/ioapic.h>
4 #include <device/pci.h>
5 #include <string.h>
6 #include <stdint.h>
7 #if CONFIG_LOGICAL_CPUS==1
8 #include <cpu/amd/multicore.h>
9 #endif
10 #include <cpu/amd/amdk8_sysconf.h>
11 #include "mb_sysconf.h"
12
13 static void *smp_write_config_table(void *v)
14 {
15         struct mp_config_table *mc;
16         unsigned char bus_num;
17         int i, j;
18         struct mb_sysconf_t *m;
19
20         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
21
22         mptable_init(mc, "SERENGETI   ", LAPIC_ADDR);
23
24         smp_write_processors(mc);
25
26         get_bus_conf();
27
28         m = sysconf.mb;
29
30 /*Bus:          Bus ID  Type*/
31        /* define bus and isa numbers */
32         for(bus_num = 0; bus_num < m->bus_isa; bus_num++) {
33                 smp_write_bus(mc, bus_num, "PCI   ");
34         }
35         smp_write_bus(mc, m->bus_isa, "ISA   ");
36
37 /*I/O APICs:    APIC ID Version State           Address*/
38         smp_write_ioapic(mc, m->apicid_8111, 0x11, IO_APIC_ADDR); //8111
39         {
40                 device_t dev;
41                 struct resource *res;
42                 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3, 1));
43                 if (dev) {
44                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
45                         if (res) {
46                                 smp_write_ioapic(mc, m->apicid_8132_1, 0x11, res->base);
47                         }
48                 }
49                 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3+1, 1));
50                 if (dev) {
51                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
52                         if (res) {
53                                 smp_write_ioapic(mc, m->apicid_8132_2, 0x11, res->base);
54                         }
55                 }
56
57                 j = 0;
58
59                 for(i=1; i< sysconf.hc_possible_num; i++) {
60                         if(!(sysconf.pci1234[i] & 0x1) ) continue;
61
62                         switch(sysconf.hcid[i]) {
63                         case 1: // 8132
64                         case 3: // 8131
65                                 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
66                                 if (dev) {
67                                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
68                                         if (res) {
69                                                 smp_write_ioapic(mc, m->apicid_8132a[j][0], 0x11, res->base);
70                                         }
71                                 }
72                                 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
73                                 if (dev) {
74                                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
75                                         if (res) {
76                                                 smp_write_ioapic(mc, m->apicid_8132a[j][1], 0x11, res->base);
77                                         }
78                                 }
79                                 break;
80                         }
81                         j++;
82                 }
83
84         }
85
86         mptable_add_isa_interrupts(mc, m->bus_isa, m->apicid_8111, 0);
87
88 /*I/O Ints:     Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN# */
89 //??? What
90         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_0, ((sysconf.sbdn+1)<<2)|3, m->apicid_8111, 0x13);
91
92 // Onboard AMD USB
93         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (0<<2)|3, m->apicid_8111, 0x13);
94
95 //Slot 3  PCI 32
96         for(i=0;i<4;i++) {
97                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (5<<2)|i, m->apicid_8111, 0x10 + (1+i)%4); //16
98         }
99
100
101 //Slot 4 PCI 32
102         for(i=0;i<4;i++) {
103                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8111_1, (4<<2)|i, m->apicid_8111, 0x10 + (0+i)%4); //16
104         }
105
106
107 //Slot 1 PCI-X 133/100/66
108         for(i=0;i<4;i++) {
109                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_2, (1<<2)|i, m->apicid_8132_2, (0+i)%4); //
110         }
111
112
113 //Slot 2 PCI-X 133/100/66
114         for(i=0;i<4;i++) {
115                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132_1, (1<<2)|i, m->apicid_8132_1, (1+i)%4); //25
116         }
117
118         j = 0;
119
120         for(i=1; i< sysconf.hc_possible_num; i++) {
121                 if(!(sysconf.pci1234[i] & 0x1) ) continue;
122                 int ii;
123                 device_t dev;
124                 struct resource *res;
125                 switch(sysconf.hcid[i]) {
126                 case 1:
127                 case 3:
128                         dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
129                         if (dev) {
130                                 res = find_resource(dev, PCI_BASE_ADDRESS_0);
131                                 if (res) {
132                                         //Slot 1 PCI-X 133/100/66
133                                         for(ii=0;ii<4;ii++) {
134                                                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132a[j][1], (0<<2)|ii, m->apicid_8132a[j][0], (0+ii)%4); //
135                                         }
136                                 }
137                         }
138
139                         dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
140                         if (dev) {
141                                 res = find_resource(dev, PCI_BASE_ADDRESS_0);
142                                 if (res) {
143                                         //Slot 2 PCI-X 133/100/66
144                                         for(ii=0;ii<4;ii++) {
145                                                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132a[j][2], (0<<2)|ii, m->apicid_8132a[j][1], (0+ii)%4); //25
146                                         }
147                                 }
148                         }
149
150                         break;
151                 case 2:
152
153                 //  Slot AGP
154                         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8151[j][1], 0x0, m->apicid_8111, 0x11);
155                         break;
156                 }
157
158                 j++;
159         }
160
161
162
163 /*Local Ints:   Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN#*/
164         smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x0);
165         smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x1);
166         /* There is no extension information... */
167
168         /* Compute the checksums */
169         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
170         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
171         printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
172                 mc, smp_next_mpe_entry(mc));
173         return smp_next_mpe_entry(mc);
174 }
175
176 unsigned long write_smp_table(unsigned long addr)
177 {
178         void *v;
179         v = smp_write_floating_table(addr);
180         return (unsigned long)smp_write_config_table(v);
181 }