blob: dccbe12243001ef80d70dfc09c6b85b3da146b95 [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#include <console/console.h>
17#include <device/pci.h>
18#include <string.h>
19#include <stdint.h>
20#include <arch/pirq_routing.h>
21
22#include <cpu/amd/amdk8_sysconf.h>
23
24/* Platform IRQs */
25#define PIRQA 10
26#define PIRQB 11
27#define PIRQC 5
28#define PIRQD 15
29
30/* Map */
31#define M_PIRQA (1 << PIRQA) /* Bitmap of supported IRQs */
32#define M_PIRQB (1 << PIRQB) /* Bitmap of supported IRQs */
33#define M_PIRQC (1 << PIRQC) /* Bitmap of supported IRQs */
34#define M_PIRQD (1 << PIRQD) /* Bitmap of supported IRQs */
35
36/* Link */
37#define L_PIRQA 1 /* Means Slot INTx# Connects To Chipset INTA# */
38#define L_PIRQB 2 /* Means Slot INTx# Connects To Chipset INTB# */
39#define L_PIRQC 3 /* Means Slot INTx# Connects To Chipset INTC# */
40#define L_PIRQD 4 /* Means Slot INTx# Connects To Chipset INTD# */
41
42static void write_pirq_info(struct irq_info *pirq_info, u8 bus, u8 devfn,
43 u8 link0, u16 bitmap0, u8 link1, u16 bitmap1,
44 u8 link2, u16 bitmap2, u8 link3, u16 bitmap3,
45 u8 slot, u8 rfu)
46{
47 pirq_info->bus = bus;
48 pirq_info->devfn = devfn;
49 pirq_info->irq[0].link = link0;
50 pirq_info->irq[0].bitmap = bitmap0;
51 pirq_info->irq[1].link = link1;
52 pirq_info->irq[1].bitmap = bitmap1;
53 pirq_info->irq[2].link = link2;
54 pirq_info->irq[2].bitmap = bitmap2;
55 pirq_info->irq[3].link = link3;
56 pirq_info->irq[3].bitmap = bitmap3;
57 pirq_info->slot = slot;
58 pirq_info->rfu = rfu;
59}
Paul Menzel95fe8fb2016-07-28 17:20:20 +020060
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 */
Paul Menzel95fe8fb2016-07-28 17:20:20 +0200106 write_pirq_info(pirq_info, bus_sb600[0], ((sbdn_sb600 + 0x14) << 3) | 4,
107 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 1,
108 0);
Josef Kellermannbfa7ee52011-05-11 07:47:43 +0000109 pirq_info++;
110 slot_num++;
111
Patrick Georgi5ed8cc02011-10-06 14:36:08 +0200112 /* ide */
Paul Menzel95fe8fb2016-07-28 17:20:20 +0200113 write_pirq_info(pirq_info, bus_sb600[0], ((sbdn_sb600 + 0x14) << 3) | 1,
114 0x1, 0xdef8, 0x2, 0xdef8, 0x3, 0xdef8, 0x4, 0xdef8, 1,
115 0);
Patrick Georgi5ed8cc02011-10-06 14:36:08 +0200116 pirq_info++;
117 slot_num++;
118
Josef Kellermannbfa7ee52011-05-11 07:47:43 +0000119 pirq->size = 32 + 16 * slot_num;
120
121 for (i = 0; i < pirq->size; i++)
122 sum += v[i];
123
124 sum = pirq->checksum - sum;
125 if (sum != pirq->checksum) {
126 pirq->checksum = sum;
127 }
128
129 printk(BIOS_INFO, "write_pirq_routing_table done.\n");
130
131 return (unsigned long)pirq_info;
132}