Factor out common mptable code to mptable_init().
[coreboot.git] / src / mainboard / tyan / s2895 / mptable.c
1 #include <console/console.h>
2 #include <arch/smp/mpspec.h>
3 #include <device/pci.h>
4 #include <string.h>
5 #include <stdint.h>
6 #include <cpu/amd/amdk8_sysconf.h>
7
8 extern  unsigned char bus_isa;
9 extern  unsigned char bus_ck804_0; //1
10 extern  unsigned char bus_ck804_1; //2
11 extern  unsigned char bus_ck804_2; //3
12 extern  unsigned char bus_ck804_3; //4
13 extern  unsigned char bus_ck804_4; //5
14 extern  unsigned char bus_ck804_5; //6
15 extern  unsigned char bus_8131_0;  //7
16 extern  unsigned char bus_8131_1;  //8
17 extern  unsigned char bus_8131_2;  //9
18 extern  unsigned char bus_ck804b_0;//a
19 extern  unsigned char bus_ck804b_1;//b
20 extern  unsigned char bus_ck804b_2;//c
21 extern  unsigned char bus_ck804b_3;//d
22 extern  unsigned char bus_ck804b_4;//e
23 extern  unsigned char bus_ck804b_5;//f
24 extern  unsigned apicid_ck804;
25 extern  unsigned apicid_8131_1;
26 extern  unsigned apicid_8131_2;
27 extern  unsigned apicid_ck804b;
28
29 extern  unsigned sbdn3;
30 extern  unsigned sbdnb;
31
32 static void *smp_write_config_table(void *v)
33 {
34         struct mp_config_table *mc;
35         unsigned sbdn;
36         unsigned char bus_num;
37         int i;
38
39         mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
40
41         mptable_init(mc, "S2895       ", LAPIC_ADDR);
42
43         smp_write_processors(mc);
44
45         get_bus_conf();
46         sbdn = sysconf.sbdn;
47
48 /*Bus:          Bus ID  Type*/
49        /* define bus and isa numbers */
50         for(bus_num = 0; bus_num < bus_isa; bus_num++) {
51                 smp_write_bus(mc, bus_num, "PCI   ");
52         }
53         smp_write_bus(mc, bus_isa, "ISA   ");
54
55 /*I/O APICs:    APIC ID Version State           Address*/
56         {
57                 device_t dev;
58                 struct resource *res;
59                 uint32_t dword;
60
61                 dev = dev_find_slot(bus_ck804_0, PCI_DEVFN(sbdn+ 0x1,0));
62                 if (dev) {
63                         res = find_resource(dev, PCI_BASE_ADDRESS_1);
64                         if (res) {
65                                 smp_write_ioapic(mc, apicid_ck804, 0x11, res->base);
66                         }
67
68         /* Initialize interrupt mapping*/
69
70                         dword = 0x0120d218;
71                         pci_write_config32(dev, 0x7c, dword);
72
73                         dword = 0x12008a00;
74                         pci_write_config32(dev, 0x80, dword);
75
76                         dword = 0x00080d7d;
77                         pci_write_config32(dev, 0x84, dword);
78
79                 }
80
81                 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(sbdn3,1));
82                 if (dev) {
83                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
84                         if (res) {
85                                 smp_write_ioapic(mc, apicid_8131_1, 0x11, res->base);
86                         }
87                 }
88                 dev = dev_find_slot(bus_8131_0, PCI_DEVFN(sbdn3+1,1));
89                 if (dev) {
90                         res = find_resource(dev, PCI_BASE_ADDRESS_0);
91                         if (res) {
92                                 smp_write_ioapic(mc, apicid_8131_2, 0x11, res->base);
93                         }
94                 }
95
96             if(sysconf.pci1234[2] & 0xf) {
97                 dev = dev_find_slot(bus_ck804b_0, PCI_DEVFN(sbdnb + 0x1,0));
98                 if (dev) {
99                         res = find_resource(dev, PCI_BASE_ADDRESS_1);
100                         if (res) {
101                                 smp_write_ioapic(mc, apicid_ck804b, 0x11, res->base);
102                         }
103
104                         dword = 0x0000d218; // Why does the factory BIOS have 0?
105                         pci_write_config32(dev, 0x7c, dword);
106
107                         dword = 0x00000000;
108                         pci_write_config32(dev, 0x80, dword);
109
110                         dword = 0x00000d00; // Same here.
111                         pci_write_config32(dev, 0x84, dword);
112
113                 }
114             }
115
116         }
117
118         mptable_add_isa_interrupts(mc, bus_isa, apicid_ck804, 1);
119
120 /*I/O Ints:     Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN# */
121 // Onboard ck804 smbus
122         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn+1)<<2)|1, apicid_ck804, 0xa);
123 // 10
124
125 // Onboard ck804 USB 1.1
126         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn+2)<<2)|0, apicid_ck804, 0x15); // 21
127
128 // Onboard ck804 USB 2
129         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn+2)<<2)|1, apicid_ck804, 0x14); // 20
130
131 // Onboard ck804 Audio
132         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn+4)<<2)|0, apicid_ck804, 0x14); // 20
133
134 // Onboard ck804 SATA 0
135         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn +7)<<2)|0, apicid_ck804, 0x17); // 23
136
137 // Onboard ck804 SATA 1
138         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn +8)<<2)|0, apicid_ck804, 0x16); // 22
139
140 // Onboard ck804 NIC
141         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_0, ((sbdn +0x0a)<<2)|0, apicid_ck804, 0x15); // 21
142
143 //Slot PCIE x16
144         for(i=0;i<4;i++) {
145                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_5, (0x00<<2)|i, apicid_ck804, 0x10 + (2+i+4-sbdn%4)%4);
146         }
147
148 //Onboard Firewire
149         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x05<<2)|0, apicid_ck804, 0x13); // 19
150
151 //Slot 2 PCI 32
152         for(i=0;i<4;i++) {
153                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804_1, (0x04<<2)|i, apicid_ck804, 0x10 + (0+i)%4); //16
154         }
155
156         if(sysconf.pci1234[2] & 0xf) {
157 //Onboard ck804b NIC
158         smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_0, ((sbdnb+0x0a)<<2)|0, apicid_ck804b, 0x15);//24+4+4+21=53
159
160 //Slot 3 PCIE x16
161         for(i=0;i<4;i++) {
162                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_ck804b_5, (0x00<<2)|i, apicid_ck804b, 0x10 + (2+i+4-sbdnb%4)%4);
163         }
164         }
165
166 //Channel B of 8131
167
168 //Slot 4 PCI-X 100/66
169         for(i=0;i<4;i++) {
170                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (4<<2)|i, apicid_8131_2, (0+i)%4);
171         }
172
173 //Slot 5 PCIX 100/66
174         for(i=0;i<4;i++) {
175                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (9<<2)|i, apicid_8131_2, (1+i)%4); // 29
176         }
177
178 //OnBoard LSI SCSI
179         for(i=0;i<2;i++) {
180                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_2, (6<<2)|i, apicid_8131_2, (2+i)%4); //30
181         }
182
183 //Channel A of 8131
184
185 //Slot 6 PCIX 133/100/66
186         for(i=0;i<4;i++) {
187                 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, bus_8131_1, (4<<2)|i, apicid_8131_1, (0+i)%4); //24
188         }
189
190 /*Local Ints:   Type    Polarity    Trigger     Bus ID   IRQ    APIC ID PIN#*/
191         smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x0);
192         smp_write_intsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, bus_isa, 0x0, MP_APIC_ALL, 0x1);
193         /* There is no extension information... */
194
195         /* Compute the checksums */
196         mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
197         mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
198         printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
199                 mc, smp_next_mpe_entry(mc));
200         return smp_next_mpe_entry(mc);
201 }
202
203 unsigned long write_smp_table(unsigned long addr)
204 {
205         void *v;
206         v = smp_write_floating_table(addr);
207         return (unsigned long)smp_write_config_table(v);
208 }