blob: 7b2e22efb2587768de336cba93918f57bc042352 [file] [log] [blame]
Marc Jones2ce8bfd2007-12-19 01:49:44 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Marc Jones2ce8bfd2007-12-19 01:49:44 +00003 *
4 * Copyright (C) 2007 Advanced Micro Devices, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Marc Jones2ce8bfd2007-12-19 01:49:44 +000014 */
15
16#include <console/console.h>
17#include <arch/smp/mpspec.h>
Uwe Hermann74d1a6e2010-10-12 17:34:08 +000018#include <arch/ioapic.h>
Marc Jones2ce8bfd2007-12-19 01:49:44 +000019#include <device/pci.h>
20#include <string.h>
21#include <stdint.h>
Patrick Georgie1667822012-05-05 15:29:32 +020022#if CONFIG_LOGICAL_CPUS
Stefan Reinauer9a16e3e2010-03-29 14:45:36 +000023#include <cpu/amd/multicore.h>
Marc Jones2ce8bfd2007-12-19 01:49:44 +000024#endif
Marc Jones2ce8bfd2007-12-19 01:49:44 +000025#include <cpu/amd/amdfam10_sysconf.h>
26#include "mb_sysconf.h"
27
Myles Watson08e0fb82010-03-22 16:33:25 +000028static void *smp_write_config_table(void *v)
Marc Jones2ce8bfd2007-12-19 01:49:44 +000029{
Patrick Georgi7411eab2010-11-22 14:14:56 +000030 int i, j, bus_isa;
Marc Jones2ce8bfd2007-12-19 01:49:44 +000031 struct mp_config_table *mc;
Marc Jones2ce8bfd2007-12-19 01:49:44 +000032 struct mb_sysconf_t *m;
33
34 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
Marc Jones2ce8bfd2007-12-19 01:49:44 +000035
Patrick Georgic8feedd2012-02-16 18:43:25 +010036 mptable_init(mc, LOCAL_APIC_ADDR);
Marc Jones2ce8bfd2007-12-19 01:49:44 +000037
38 smp_write_processors(mc);
39
40 get_bus_conf();
41
42 m = sysconf.mb;
43
Patrick Georgi7411eab2010-11-22 14:14:56 +000044 mptable_write_buses(mc, NULL, &bus_isa);
Marc Jones2ce8bfd2007-12-19 01:49:44 +000045
46 /*I/O APICs: APIC ID Version State Address*/
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080047 smp_write_ioapic(mc, m->apicid_8111, 0x11, VIO_APIC_VADDR); //8111
Marc Jones2ce8bfd2007-12-19 01:49:44 +000048 {
49 device_t dev;
50 struct resource *res;
51 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3, 1));
52 if (dev) {
53 res = find_resource(dev, PCI_BASE_ADDRESS_0);
54 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080055 smp_write_ioapic(mc, m->apicid_8132_1, 0x11,
56 res2mmio(res, 0, 0));
Marc Jones2ce8bfd2007-12-19 01:49:44 +000057 }
58 }
59 dev = dev_find_slot(m->bus_8132_0, PCI_DEVFN(m->sbdn3+1, 1));
60 if (dev) {
61 res = find_resource(dev, PCI_BASE_ADDRESS_0);
62 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080063 smp_write_ioapic(mc, m->apicid_8132_2, 0x11,
64 res2mmio(res, 0, 0));
Marc Jones2ce8bfd2007-12-19 01:49:44 +000065 }
66 }
67
68 j = 0;
69
70 for(i=1; i< sysconf.hc_possible_num; i++) {
71 if(!(sysconf.pci1234[i] & 0x1) ) continue;
72
73 switch(sysconf.hcid[i]) {
74 case 1:
75 case 3:
76 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
77 if (dev) {
78 res = find_resource(dev, PCI_BASE_ADDRESS_0);
79 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080080 smp_write_ioapic(mc, m->apicid_8132a[j][0], 0x11,
81 res2mmio(res, 0, 0));
Marc Jones2ce8bfd2007-12-19 01:49:44 +000082 }
83 }
84 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
85 if (dev) {
86 res = find_resource(dev, PCI_BASE_ADDRESS_0);
87 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080088 smp_write_ioapic(mc, m->apicid_8132a[j][1], 0x11,
89 res2mmio(res, 0, 0));
Marc Jones2ce8bfd2007-12-19 01:49:44 +000090 }
91 }
92 break;
93 }
94 j++;
95 }
96
97 }
98
Patrick Georgi7411eab2010-11-22 14:14:56 +000099 mptable_add_isa_interrupts(mc, bus_isa, m->apicid_8111, 0);
Patrick Georgic5b87c82010-05-20 15:28:19 +0000100
Marc Jones2ce8bfd2007-12-19 01:49:44 +0000101 /* I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Marc Jones2ce8bfd2007-12-19 01:49:44 +0000102//??? What
103 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);
104
105 // Onboard AMD USB
106 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);
107
108 //Slot 3 PCI 32
109 for(i=0;i<4;i++) {
110 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
111 }
112
113
114 // Slot 4 PCI 32
115 for(i=0;i<4;i++) {
116 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
117 }
118
119
120 // Slot 1 PCI-X 133/100/66
121 for(i=0;i<4;i++) {
122 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); //
123 }
124
125
126 //Slot 2 PCI-X 133/100/66
127 for(i=0;i<4;i++) {
128 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
129 }
130
131 j = 0;
132
133 for(i=1; i< sysconf.hc_possible_num; i++) {
134 if(!(sysconf.pci1234[i] & 0x1) ) continue;
135 int ii;
136 int jj;
137 device_t dev;
138 struct resource *res;
139 switch(sysconf.hcid[i]) {
140 case 1:
141 case 3:
142 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j], 1));
143 if (dev) {
144 res = find_resource(dev, PCI_BASE_ADDRESS_0);
145 if (res) {
146 for(jj=0; jj<4; jj++) {
147 //Slot 1 PCI-X 133/100/66
148 for(ii=0;ii<4;ii++) {
149 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132a[j][1], (jj<<2)|ii, m->apicid_8132a[j][0], (jj+ii)%4); //
150 }
151 }
152 }
153 }
154
155 dev = dev_find_slot(m->bus_8132a[j][0], PCI_DEVFN(m->sbdn3a[j]+1, 1));
156 if (dev) {
157 res = find_resource(dev, PCI_BASE_ADDRESS_0);
158 if (res) {
159 for(jj=0; jj<4; jj++) {
160 //Slot 2 PCI-X 133/100/66
161 for(ii=0;ii<4;ii++) {
162 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8132a[j][2], (jj<<2)|ii, m->apicid_8132a[j][1], (jj+ii)%4); //25
163 }
164 }
165 }
166 }
167
168 break;
169 case 2:
170
171 // Slot AGP
172 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_8151[j][1], 0x0, m->apicid_8111, 0x11);
173 break;
174 }
175
176 j++;
177 }
178
179
180
181 /* Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Patrick Georgi6eb7a532011-10-07 21:42:52 +0200182 mptable_lintsrc(mc, bus_isa);
Marc Jones2ce8bfd2007-12-19 01:49:44 +0000183 /* There is no extension information... */
184
185 /* Compute the checksums */
Patrick Georgib0a9c5c2011-10-07 23:01:55 +0200186 return mptable_finalize(mc);
Marc Jones2ce8bfd2007-12-19 01:49:44 +0000187}
188
189unsigned long write_smp_table(unsigned long addr)
190{
191 void *v;
Patrick Georgic75c79b2011-10-07 22:41:07 +0200192 v = smp_write_floating_table(addr, 0);
Marc Jones2ce8bfd2007-12-19 01:49:44 +0000193 return (unsigned long)smp_write_config_table(v);
194}