blob: 5ba63bc0cdfb0e8a7af722d5f7195188146a980d [file] [log] [blame]
Patrick Georgibe61a172010-12-18 07:48:43 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2007-2008 coresystems GmbH
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.
Patrick Georgibe61a172010-12-18 07:48:43 +000014 */
15
16#include <console/console.h>
17#include <arch/smp/mpspec.h>
18#include <device/pci.h>
19#include <string.h>
20#include <stdint.h>
21
22void *smp_write_config_table(void *v)
23{
24 struct mp_config_table *mc;
25 int isa_bus;
26
27 mc = (void *)(((char *)v) + SMP_FLOATING_TABLE_LEN);
Patrick Georgic8feedd2012-02-16 18:43:25 +010028 mptable_init(mc, LOCAL_APIC_ADDR);
Patrick Georgibe61a172010-12-18 07:48:43 +000029
30 smp_write_processors(mc);
31 mptable_write_buses(mc, NULL, &isa_bus);
32
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080033 smp_write_ioapic(mc, 2, 0x20, VIO_APIC_VADDR);
Patrick Georgibe61a172010-12-18 07:48:43 +000034 {
35 device_t dev;
36 struct resource *res;
37 dev = dev_find_slot(1, PCI_DEVFN(0x1e,0));
38 if (dev) {
39 res = find_resource(dev, PCI_BASE_ADDRESS_0);
40 if (res) {
41 smp_write_ioapic(mc, 3, 0x20, res->base);
42 }
43 }
44 dev = dev_find_slot(1, PCI_DEVFN(0x1c,0));
45 if (dev) {
46 res = find_resource(dev, PCI_BASE_ADDRESS_0);
47 if (res) {
48 smp_write_ioapic(mc, 4, 0x20, res->base);
49 }
50 }
51 dev = dev_find_slot(4, PCI_DEVFN(0x1e,0));
52 if (dev) {
53 res = find_resource(dev, PCI_BASE_ADDRESS_0);
54 if (res) {
55 smp_write_ioapic(mc, 5, 0x20, res->base);
56 }
57 }
58 dev = dev_find_slot(4, PCI_DEVFN(0x1c,0));
59 if (dev) {
60 res = find_resource(dev, PCI_BASE_ADDRESS_0);
61 if (res) {
62 smp_write_ioapic(mc, 8, 0x20, res->base);
63 }
64 }
65 }
66/*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#
67*/ smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x0, 0x1, 0x0);
68 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x1, 0x1, 0x1);
69 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x0, 0x1, 0x2);
70 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x3, 0x1, 0x3);
71 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x4, 0x1, 0x4);
72 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x6, 0x1, 0x6);
73 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x7, 0x1, 0x7);
74 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_EDGE|MP_IRQ_POLARITY_HIGH, 0x1, 0x8, 0x1, 0x8);
75 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0x9, 0x1, 0x9);
76 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0xc, 0x1, 0xc);
77 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0xd, 0x1, 0xd);
78 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT, 0x1, 0xe, 0x1, 0xe);
79 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x8, 0x1, 0x10);
80 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x74, 0x1, 0x10);
81 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x75, 0x1, 0x11);
82 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x76, 0x1, 0x12);
83 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x77, 0x1, 0x13);
84 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x6c, 0x1, 0x10);
85 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x78, 0x1, 0x10);
86 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x79, 0x1, 0x11);
87 smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW, 0x0, 0x7a, 0x1, 0x12);
88/*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
Patrick Georgi6eb7a532011-10-07 21:42:52 +020089 mptable_lintsrc(mc, isa_bus);
Patrick Georgibe61a172010-12-18 07:48:43 +000090 /* There is no extension information... */
91
92 /* Compute the checksums */
Patrick Georgib0a9c5c2011-10-07 23:01:55 +020093 return mptable_finalize(mc);
Patrick Georgibe61a172010-12-18 07:48:43 +000094}
95
96unsigned long write_smp_table(unsigned long addr)
97{
98 void *v;
Patrick Georgic75c79b2011-10-07 22:41:07 +020099 v = smp_write_floating_table(addr, 0);
Patrick Georgibe61a172010-12-18 07:48:43 +0000100 return (unsigned long)smp_write_config_table(v);
101}