blob: 775fdc6c2d580122f8b13d3939fd08f2dc7afaab [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.
bxshifaea4c52006-11-02 16:02:33 +000021 */
22
23#include <console/console.h>
24#include <arch/smp/mpspec.h>
25#include <arch/io.h>
26#include <device/pci.h>
27#include <string.h>
28#include <stdint.h>
Patrick Georgie1667822012-05-05 15:29:32 +020029#if CONFIG_LOGICAL_CPUS
Stefan Reinauer9a16e3e2010-03-29 14:45:36 +000030#include <cpu/amd/multicore.h>
bxshifaea4c52006-11-02 16:02:33 +000031#endif
bxshifaea4c52006-11-02 16:02:33 +000032#include <cpu/amd/amdk8_sysconf.h>
bxshifaea4c52006-11-02 16:02:33 +000033#include "mb_sysconf.h"
34
Myles Watson08e0fb82010-03-22 16:33:25 +000035static void *smp_write_config_table(void *v)
bxshifaea4c52006-11-02 16:02:33 +000036{
bxshifaea4c52006-11-02 16:02:33 +000037 struct mp_config_table *mc;
38
Patrick Georgi5244e1b2010-11-21 14:41:07 +000039 int i, bus_isa;
40 struct mb_sysconf_t *m;
bxshifaea4c52006-11-02 16:02:33 +000041
42 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
bxshifaea4c52006-11-02 16:02:33 +000043
Patrick Georgic8feedd2012-02-16 18:43:25 +010044 mptable_init(mc, LOCAL_APIC_ADDR);
bxshifaea4c52006-11-02 16:02:33 +000045
46 smp_write_processors(mc);
47
Patrick Georgi5244e1b2010-11-21 14:41:07 +000048 get_bus_conf();
49 m = sysconf.mb;
bxshifaea4c52006-11-02 16:02:33 +000050
Patrick Georgi5244e1b2010-11-21 14:41:07 +000051 mptable_write_buses(mc, NULL, &bus_isa);
bxshifaea4c52006-11-02 16:02:33 +000052
53/*I/O APICs: APIC ID Version State Address*/
54 {
Stefan Reinauerc51dc442010-04-07 01:44:04 +000055 device_t dev = 0;
bxshifaea4c52006-11-02 16:02:33 +000056 struct resource *res;
57 for(i=0; i<3; i++) {
58 dev = dev_find_device(0x1166, 0x0235, dev);
59 if (dev) {
60 res = find_resource(dev, PCI_BASE_ADDRESS_0);
61 if (res) {
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080062 smp_write_ioapic(mc, m->apicid_bcm5785[i], 0x11,
63 res2mmio(res, 0, 0));
bxshifaea4c52006-11-02 16:02:33 +000064 }
65 }
66 }
67
68 }
69
Patrick Georgi5244e1b2010-11-21 14:41:07 +000070 mptable_add_isa_interrupts(mc, bus_isa, m->apicid_bcm5785[0], 0);
bxshifaea4c52006-11-02 16:02:33 +000071
72//IDE
73 outb(0x02, 0xc00); outb(0x0e, 0xc01);
74
75 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
76
77//SATA
78 outb(0x07, 0xc00); outb(0x0f, 0xc01);
79 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);
80
81//USB
82 outb(0x01, 0xc00); outb(0x0a, 0xc01);
83 for(i=0;i<3;i++) {
84 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); //
85 }
86
87
88
89 /* enable int */
90 /* why here? must get the BAR and PCI command bit 1 set before enable it ....*/
91 {
92 device_t dev;
93 dev = dev_find_device(0x1166, 0x0205, 0);
94 if(dev) {
95 uint32_t dword;
96 dword = pci_read_config32(dev, 0x6c);
97 dword |= (1<<4); // enable interrupts
98 pci_write_config32(dev, 0x6c, dword);
99 }
100 }
101
102//First pci-x slot (on bcm5785) under bus_bcm5785_1:d.0
103 // AIC 8130 Galileo Technology...
104 for(i=0;i<4;i++) {
105 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); //
106 }
107
108
109//pci slot (on bcm5785)
110 for(i=0;i<4;i++) {
111 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); //
112 }
113
114
115//onboard ati
116 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);
117
118//PCI-X on bcm5780
119 for(i=0;i<4;i++) {
120 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); //
121 }
122
123//onboard Broadcom
124 for(i=0;i<2;i++) {
125 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); //
126 }
127
128
129// First PCI-E x8
130 for(i=0;i<4;i++) {
131 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); //
132 }
133
134
135// Second PCI-E x8
136 for(i=0;i<4;i++) {
137 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); //
138 }
139
140// Third PCI-E x1
141 for(i=0;i<4;i++) {
142 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); //
143 }
144
145/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Patrick Georgi6eb7a532011-10-07 21:42:52 +0200146 mptable_lintsrc(mc, bus_isa);
bxshifaea4c52006-11-02 16:02:33 +0000147 /* There is no extension information... */
148
149 /* Compute the checksums */
Patrick Georgib0a9c5c2011-10-07 23:01:55 +0200150 return mptable_finalize(mc);
bxshifaea4c52006-11-02 16:02:33 +0000151}
152
153unsigned long write_smp_table(unsigned long addr)
154{
155 void *v;
Patrick Georgic75c79b2011-10-07 22:41:07 +0200156 v = smp_write_floating_table(addr, 0);
bxshifaea4c52006-11-02 16:02:33 +0000157 return (unsigned long)smp_write_config_table(v);
158}