blob: 721e73ec5ef215ec0efa9bf5491adefe1f0aa89b [file] [log] [blame]
Josef Kellermannbfa7ee52011-05-11 07:47:43 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008 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.
Josef Kellermannbfa7ee52011-05-11 07:47:43 +000014 */
15
Josef Kellermannbfa7ee52011-05-11 07:47:43 +000016
17#include <console/console.h>
18#include <device/pci.h>
19#include <string.h>
20#include <stdint.h>
21#include <arch/pirq_routing.h>
22
23#include <cpu/amd/amdk8_sysconf.h>
24
25/* Platform IRQs */
26#define PIRQA 10
27#define PIRQB 11
28#define PIRQC 5
29#define PIRQD 15
30
31/* Map */
32#define M_PIRQA (1 << PIRQA) /* Bitmap of supported IRQs */
33#define M_PIRQB (1 << PIRQB) /* Bitmap of supported IRQs */
34#define M_PIRQC (1 << PIRQC) /* Bitmap of supported IRQs */
35#define M_PIRQD (1 << PIRQD) /* Bitmap of supported IRQs */
36
37/* Link */
38#define L_PIRQA 1 /* Means Slot INTx# Connects To Chipset INTA# */
39#define L_PIRQB 2 /* Means Slot INTx# Connects To Chipset INTB# */
40#define L_PIRQC 3 /* Means Slot INTx# Connects To Chipset INTC# */
41#define L_PIRQD 4 /* Means Slot INTx# Connects To Chipset INTD# */
42
43static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn,
44 u8 link0, u16 bitmap0, u8 link1, u16 bitmap1,
45 u8 link2, u16 bitmap2, u8 link3, u16 bitmap3,
46 u8 slot, u8 rfu)
47{
48 pirq_info->bus = bus;
49 pirq_info->devfn = devfn;
50 pirq_info->irq[0].link = link0;
51 pirq_info->irq[0].bitmap = bitmap0;
52 pirq_info->irq[1].link = link1;
53 pirq_info->irq[1].bitmap = bitmap1;
54 pirq_info->irq[2].link = link2;
55 pirq_info->irq[2].bitmap = bitmap2;
56 pirq_info->irq[3].link = link3;
57 pirq_info->irq[3].bitmap = bitmap3;
58 pirq_info->slot = slot;
59 pirq_info->rfu = rfu;
60}
Josef Kellermannbfa7ee52011-05-11 07:47:43 +000061extern u8 bus_rs690[8];
62extern u8 bus_sb600[2];
63extern unsigned long sbdn_sb600;
64
65unsigned long write_pirq_routing_table(unsigned long addr)
66{
67 struct irq_routing_table *pirq;
68 struct irq_info *pirq_info;
69 u32 slot_num;
70 u8 *v;
71
72 u8 sum = 0;
73 int i;
74
75 get_bus_conf(); /* it will find out all bus num and apic that share with mptable.c and mptable.c and acpi_tables.c */
76
77 /* Align the table to be 16 byte aligned. */
78 addr += 15;
79 addr &= ~15;
80
Kyösti Mälkki9533d832014-06-26 05:30:54 +030081 /* This table must be between 0xf0000 & 0x100000 */
Josef Kellermannbfa7ee52011-05-11 07:47:43 +000082 printk(BIOS_INFO, "Writing IRQ routing tables to 0x%lx...", addr);
83
84 pirq = (void *)(addr);
85 v = (u8 *) (addr);
86
87 pirq->signature = PIRQ_SIGNATURE;
88 pirq->version = PIRQ_VERSION;
89
90 pirq->rtr_bus = bus_sb600[0];
91 pirq->rtr_devfn = ((sbdn_sb600 + 0x14) << 3) | 4;
92
93 pirq->exclusive_irqs = 0;
94
95 pirq->rtr_vendor = 0x1002;
96 pirq->rtr_device = 0x4384;
97
98 pirq->miniport_data = 0;
99
100 memset(pirq->rfu, 0, sizeof(pirq->rfu));
101
102 pirq_info = (void *)(&pirq->checksum + 1);
103 slot_num = 0;
104
105 /* pci bridge */
106 write_pirq_info(pirq_info, bus_sb600[0], ((sbdn_sb600 + 0x14) << 3) | 4, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 1, 0);
107 pirq_info++;
108 slot_num++;
109
Patrick Georgi5ed8cc02011-10-06 14:36:08 +0200110 /* ide */
111 write_pirq_info(pirq_info, bus_sb600[0], ((sbdn_sb600 + 0x14) << 3) | 1, 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 1, 0);
112 pirq_info++;
113 slot_num++;
114
Josef Kellermannbfa7ee52011-05-11 07:47:43 +0000115 pirq->size = 32 + 16 * slot_num;
116
117 for (i = 0; i < pirq->size; i++)
118 sum += v[i];
119
120 sum = pirq->checksum - sum;
121 if (sum != pirq->checksum) {
122 pirq->checksum = sum;
123 }
124
125 printk(BIOS_INFO, "write_pirq_routing_table done.\n");
126
127 return (unsigned long)pirq_info;
128}