2 * This file is part of the coreboot project.
4 * Copyright (C) 2007 AMD
5 * Written by Yinghai Lu <yinghailu@amd.com> for AMD.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
18 #include <console/console.h>
19 #include <arch/smp/mpspec.h>
20 #include <device/pci.h>
23 #include <cpu/amd/amdfam10_sysconf.h>
24 #include "mb_sysconf.h"
26 extern unsigned sbdn3
;
28 static void *smp_write_config_table(void *v
)
30 struct mp_config_table
*mc
;
31 struct mb_sysconf_t
*m
;
35 mc
= (void *)(((char *)v
) + SMP_FLOATING_TABLE_LEN
);
37 mptable_init(mc
, LOCAL_APIC_ADDR
);
39 smp_write_processors(mc
);
45 mptable_write_buses(mc
, NULL
, &bus_isa
);
47 /*I/O APICs: APIC ID Version State Address*/
53 dev
= dev_find_slot(m
->bus_mcp55
[0], PCI_DEVFN(sbdn
+ 0x1,0));
55 res
= find_resource(dev
, PCI_BASE_ADDRESS_1
);
57 smp_write_ioapic(mc
, m
->apicid_mcp55
, 0x11,
62 pci_write_config32(dev
, 0x7c, dword
);
65 pci_write_config32(dev
, 0x80, dword
);
68 pci_write_config32(dev
, 0x84, dword
);
75 mptable_add_isa_interrupts(mc
, bus_isa
, m
->apicid_mcp55
, 0);
77 /*I/O Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN# */
78 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[0], ((sbdn
+1)<<2)|1, m
->apicid_mcp55
, 0x5); /* 5 SMBus, OK */
79 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[0], ((sbdn
+2)<<2)|0, m
->apicid_mcp55
, 0xb); /* 11 USB, OK */
80 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[0], ((sbdn
+2)<<2)|1, m
->apicid_mcp55
, 0xa); /* 10 USB, OK */
81 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[0], ((sbdn
+5)<<2)|0, m
->apicid_mcp55
, 0x5); /* 5 IDE, OK*/
82 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[0], ((sbdn
+5)<<2)|1, m
->apicid_mcp55
, 0xa); /* 10 IDE, OK*/
83 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[0], ((sbdn
+5)<<2)|2, m
->apicid_mcp55
, 0xa); /* 10 IDE, OK*/
84 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[0], ((sbdn
+6)<<2)|1, m
->apicid_mcp55
, 0xa); /* 10 VGA, OK*/
86 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_8132_2
, ((3)<<2)|0, m
->apicid_mcp55
, 0x5); /* 5 eth0, OK*/
87 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_8132_2
, ((3)<<2)|1, m
->apicid_mcp55
, 0xb); /* 11 eth1, OK*/
90 if(!m
->bus_mcp55
[j
]) continue;
92 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[j
], (0x00<<2)|i
, m
->apicid_mcp55
, 0x10 + (2+j
+i
+4-sbdn
%4)%4);
98 smp_write_intsrc(mc
, mp_INT
, MP_IRQ_TRIGGER_LEVEL
|MP_IRQ_POLARITY_LOW
, m
->bus_mcp55
[1], ((0x04+j
)<<2)|i
, m
->apicid_mcp55
, 0x10 + (2+i
+j
)%4);
101 /*Local Ints: Type Polarity Trigger Bus ID IRQ APIC ID PIN#*/
102 mptable_lintsrc(mc
, bus_isa
);
103 /* There is no extension information... */
105 /* Compute the checksums */
106 return mptable_finalize(mc
);
109 unsigned long write_smp_table(unsigned long addr
)
112 v
= smp_write_floating_table(addr
, 0);
113 return (unsigned long)smp_write_config_table(v
);