blob: bd4518461803973e9216daa5fd4c89f9c783955c [file] [log] [blame]
bxshifaea4c52006-11-02 16:02:33 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
bxshifaea4c52006-11-02 16:02:33 +00003 *
4 * Copyright (C) 2001 Eric W.Biederman<ebiderman@lnxi.com>
5 *
6 * Copyright (C) 2006 AMD
7 * Written by Yinghai Lu <yinghailu@gmail.com> for AMD.
8 *
9 * Copyright (C) 2006 MSI
10 * Written by bxshi <bingxunshi@gmail.com> for MSI.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27#include <console/console.h>
28#include <arch/smp/mpspec.h>
29#include <arch/io.h>
30#include <device/pci.h>
31#include <string.h>
32#include <stdint.h>
33#if CONFIG_LOGICAL_CPUS==1
Stefan Reinauer9a16e3e2010-03-29 14:45:36 +000034#include <cpu/amd/multicore.h>
bxshifaea4c52006-11-02 16:02:33 +000035#endif
bxshifaea4c52006-11-02 16:02:33 +000036#include <cpu/amd/amdk8_sysconf.h>
bxshifaea4c52006-11-02 16:02:33 +000037#include "mb_sysconf.h"
38
Myles Watson08e0fb82010-03-22 16:33:25 +000039static void *smp_write_config_table(void *v)
bxshifaea4c52006-11-02 16:02:33 +000040{
bxshifaea4c52006-11-02 16:02:33 +000041 struct mp_config_table *mc;
42
43 unsigned char bus_num;
44 int i;
45 struct mb_sysconf_t *m;
46
47 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
bxshifaea4c52006-11-02 16:02:33 +000048
Uwe Hermann55dc2232010-10-25 15:32:07 +000049 mptable_init(mc, "MS-9185 ", LAPIC_ADDR);
bxshifaea4c52006-11-02 16:02:33 +000050
51 smp_write_processors(mc);
52
53 get_bus_conf();
54 m = sysconf.mb;
55
56/*Bus: Bus ID Type*/
57 /* define bus and isa numbers */
58 for(bus_num = 0; bus_num < m->bus_isa; bus_num++) {
59 smp_write_bus(mc, bus_num, "PCI ");
60 }
61 smp_write_bus(mc, m->bus_isa, "ISA ");
62
63/*I/O APICs: APIC ID Version State Address*/
64 {
Stefan Reinauerc51dc442010-04-07 01:44:04 +000065 device_t dev = 0;
bxshifaea4c52006-11-02 16:02:33 +000066 struct resource *res;
67 for(i=0; i<3; i++) {
68 dev = dev_find_device(0x1166, 0x0235, dev);
69 if (dev) {
70 res = find_resource(dev, PCI_BASE_ADDRESS_0);
71 if (res) {
72 smp_write_ioapic(mc, m->apicid_bcm5785[i], 0x11, res->base);
73 }
74 }
75 }
76
77 }
78
Patrick Georgic5b87c82010-05-20 15:28:19 +000079 mptable_add_isa_interrupts(mc, m->bus_isa, m->apicid_bcm5785[0], 0);
bxshifaea4c52006-11-02 16:02:33 +000080
81//IDE
82 outb(0x02, 0xc00); outb(0x0e, 0xc01);
83
84 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_bcm5785_0, ((1+sysconf.sbdn)<<2)|1, m->apicid_bcm5785[0], 0xe); // IDE
85
86//SATA
87 outb(0x07, 0xc00); outb(0x0f, 0xc01);
88 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_1, (0x0e<<2)|0, m->apicid_bcm5785[0], 0xf);
89
90//USB
91 outb(0x01, 0xc00); outb(0x0a, 0xc01);
92 for(i=0;i<3;i++) {
93 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, ((2+sysconf.sbdn)<<2)|i, m->apicid_bcm5785[0], 0xa); //
94 }
95
96
97
98 /* enable int */
99 /* why here? must get the BAR and PCI command bit 1 set before enable it ....*/
100 {
101 device_t dev;
102 dev = dev_find_device(0x1166, 0x0205, 0);
103 if(dev) {
104 uint32_t dword;
105 dword = pci_read_config32(dev, 0x6c);
106 dword |= (1<<4); // enable interrupts
107 pci_write_config32(dev, 0x6c, dword);
108 }
109 }
110
111//First pci-x slot (on bcm5785) under bus_bcm5785_1:d.0
112 // AIC 8130 Galileo Technology...
113 for(i=0;i<4;i++) {
114 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_1_1, (6<<2)|i, m->apicid_bcm5785[1], 2 + (1+i)%4); //
115 }
116
117
118//pci slot (on bcm5785)
119 for(i=0;i<4;i++) {
120 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (5<<2)|i, m->apicid_bcm5785[1], 8+i%4); //
121 }
122
123
124//onboard ati
125 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5785_0, (4<<2)|0, m->apicid_bcm5785[1], 0x1);
126
127//PCI-X on bcm5780
128 for(i=0;i<4;i++) {
129 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5780[1], (4<<2)|i, m->apicid_bcm5785[1], 2 + (0+i)%4); //
130 }
131
132//onboard Broadcom
133 for(i=0;i<2;i++) {
134 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5780[2], (4<<2)|i, m->apicid_bcm5785[1], 0xa + (0+i)%4); //
135 }
136
137
138// First PCI-E x8
139 for(i=0;i<4;i++) {
140 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5780[5], (0<<2)|i, m->apicid_bcm5785[1], 0xe); //
141 }
142
143
144// Second PCI-E x8
145 for(i=0;i<4;i++) {
146 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5780[3], (0<<2)|i, m->apicid_bcm5785[1], 0xc); //
147 }
148
149// Third PCI-E x1
150 for(i=0;i<4;i++) {
151 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, m->bus_bcm5780[4], (0<<2)|i, m->apicid_bcm5785[1], 0xd); //
152 }
153
154/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Tobias Diedrichb907d322010-10-26 22:40:16 +0000155 smp_write_lintsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x0);
156 smp_write_lintsrc(mc, mp_NMI, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, m->bus_isa, 0x0, MP_APIC_ALL, 0x1);
bxshifaea4c52006-11-02 16:02:33 +0000157 /* There is no extension information... */
158
159 /* Compute the checksums */
160 mc->mpe_checksum = smp_compute_checksum(smp_next_mpc_entry(mc), mc->mpe_length);
161 mc->mpc_checksum = smp_compute_checksum(mc, mc->mpc_length);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000162 printk(BIOS_DEBUG, "Wrote the mp table end at: %p - %p\n",
bxshifaea4c52006-11-02 16:02:33 +0000163 mc, smp_next_mpe_entry(mc));
164 return smp_next_mpe_entry(mc);
165}
166
167unsigned long write_smp_table(unsigned long addr)
168{
169 void *v;
170 v = smp_write_floating_table(addr);
171 return (unsigned long)smp_write_config_table(v);
172}