blob: a8b4136ce5dbc122bbdb6fed4ae482da1d1b2579 [file] [log] [blame]
Yinghai Lud4b278c2006-10-04 20:46:15 +00001#include <console/console.h>
2#include <arch/smp/mpspec.h>
Uwe Hermann74d1a6e2010-10-12 17:34:08 +00003#include <arch/ioapic.h>
Yinghai Lud4b278c2006-10-04 20:46:15 +00004#include <device/pci.h>
5#include <string.h>
6#include <stdint.h>
7#if CONFIG_LOGICAL_CPUS==1
Stefan Reinauer9a16e3e2010-03-29 14:45:36 +00008#include <cpu/amd/multicore.h>
Yinghai Lud4b278c2006-10-04 20:46:15 +00009#endif
Yinghai Lud4b278c2006-10-04 20:46:15 +000010#include <cpu/amd/amdk8_sysconf.h>
11#include "mb_sysconf.h"
12
Myles Watson08e0fb82010-03-22 16:33:25 +000013static void *smp_write_config_table(void *v)
Yinghai Lud4b278c2006-10-04 20:46:15 +000014{
Yinghai Lud4b278c2006-10-04 20:46:15 +000015 struct mp_config_table *mc;
Yinghai Lud4b278c2006-10-04 20:46:15 +000016 unsigned char bus_num;
Yinghai Lu5f9624d2006-10-04 22:56:21 +000017 int i, j;
Yinghai Lud4b278c2006-10-04 20:46:15 +000018 struct mb_sysconf_t *m;
19
20 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
Yinghai Lud4b278c2006-10-04 20:46:15 +000021
Uwe Hermann55dc2232010-10-25 15:32:07 +000022 mptable_init(mc, "SERENGETI ", LAPIC_ADDR);
Yinghai Lud4b278c2006-10-04 20:46:15 +000023
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*/
Uwe Hermann74d1a6e2010-10-12 17:34:08 +000038 smp_write_ioapic(mc, m->apicid_8111, 0x11, IO_APIC_ADDR); //8111
Yinghai Lud4b278c2006-10-04 20:46:15 +000039 {
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 }
Yinghai Lu5f9624d2006-10-04 22:56:21 +000056
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
Yinghai Lud4b278c2006-10-04 20:46:15 +000084 }
Stefan Reinauer14e22772010-04-27 06:56:47 +000085
Patrick Georgic5b87c82010-05-20 15:28:19 +000086 mptable_add_isa_interrupts(mc, m->bus_isa, m->apicid_8111, 0);
87
Stefan Reinauer14e22772010-04-27 06:56:47 +000088/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
Yinghai Lud4b278c2006-10-04 20:46:15 +000089//??? 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
Yinghai Lud4b278c2006-10-04 20:46:15 +000095//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
Yinghai Lu5f9624d2006-10-04 22:56:21 +0000118 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
Yinghai Lud4b278c2006-10-04 20:46:15 +0000162
163/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Tobias Diedrichb907d322010-10-26 22:40:16 +0000164 smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x0);
165 smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x1);
Yinghai Lud4b278c2006-10-04 20:46:15 +0000166 /* 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);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000171 printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
Yinghai Lud4b278c2006-10-04 20:46:15 +0000172 mc, smp_next_mpe_entry(mc));
173 return smp_next_mpe_entry(mc);
174}
175
176unsigned 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}