blob: 0afcb4615e9c9fd37845b03d61e3693cbecbca9a [file] [log] [blame]
Bin Mengb5b6b012015-04-24 18:10:05 +08001/*
2 * Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
3 *
4 * Ported from coreboot src/arch/x86/include/arch/pirq_routing.h
5 *
6 * SPDX-License-Identifier: GPL-2.0+
7 */
8
9#ifndef _PIRQ_ROUTING_H_
10#define _PIRQ_ROUTING_H_
11
12/*
13 * This is the maximum number on interrupt entries that a PCI device may have.
14 * This is NOT the number of slots or devices in the system
15 * This is NOT the number of entries in the PIRQ table
16 *
17 * This tells us that in the PIRQ table, we are going to have 4 link-bitmap
18 * entries per PCI device which is fixed at 4: INTA, INTB, INTC, and INTD.
19 *
20 * CAUTION: If you change this, PIRQ routing will not work correctly.
21 */
22#define MAX_INTX_ENTRIES 4
23
24#define PIRQ_SIGNATURE \
25 (('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
26#define PIRQ_VERSION 0x0100
27
28struct __packed irq_info {
29 u8 bus; /* Bus number */
30 u8 devfn; /* Device and function number */
31 struct __packed {
32 u8 link; /* IRQ line ID, 0=not routed */
33 u16 bitmap; /* Available IRQs */
34 } irq[MAX_INTX_ENTRIES];
35 u8 slot; /* Slot number, 0=onboard */
36 u8 rfu;
37};
38
39struct __packed irq_routing_table {
40 u32 signature; /* PIRQ_SIGNATURE */
41 u16 version; /* PIRQ_VERSION */
42 u16 size; /* Table size in bytes */
43 u8 rtr_bus; /* busno of the interrupt router */
44 u8 rtr_devfn; /* devfn of the interrupt router */
45 u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
46 u16 rtr_vendor; /* Vendor ID of the interrupt router */
47 u16 rtr_device; /* Device ID of the interrupt router */
48 u32 miniport_data;
49 u8 rfu[11];
50 u8 checksum; /* Modulo 256 checksum must give zero */
51 struct irq_info slots[CONFIG_IRQ_SLOT_COUNT];
52};
53
54/**
55 * get_irq_slot_count() - Get the number of entries in the irq_info table
56 *
57 * This calculates the number of entries for the irq_info table.
58 *
59 * @rt: pointer to the base address of the struct irq_info
60 * @return: number of entries
61 */
62static inline int get_irq_slot_count(struct irq_routing_table *rt)
63{
64 return (rt->size - 32) / sizeof(struct irq_info);
65}
66
67/**
68 * pirq_check_irq_routed() - Check whether an IRQ is routed to 8259 PIC
69 *
70 * This function checks whether an IRQ is routed to 8259 PIC for a given link.
71 *
72 * Note: this function should be provided by the platform codes, as the
73 * implementation of interrupt router may be different.
74 *
Bin Mengb46c2082016-02-01 01:40:51 -080075 * @dev: irq router's udevice
Bin Mengb5b6b012015-04-24 18:10:05 +080076 * @link: link number which represents a PIRQ
77 * @irq: the 8259 IRQ number
78 * @return: true if the irq is already routed to 8259 for a given link,
79 * false elsewise
80 */
Bin Mengb46c2082016-02-01 01:40:51 -080081bool pirq_check_irq_routed(struct udevice *dev, int link, u8 irq);
Bin Mengb5b6b012015-04-24 18:10:05 +080082
83/**
84 * pirq_translate_link() - Translate a link value
85 *
86 * This function translates a platform-specific link value to a link number.
87 * On Intel platforms, the link value is normally a offset into the PCI
88 * configuration space into the legacy bridge.
89 *
90 * Note: this function should be provided by the platform codes, as the
91 * implementation of interrupt router may be different.
92 *
Bin Mengb46c2082016-02-01 01:40:51 -080093 * @dev: irq router's udevice
Bin Mengb5b6b012015-04-24 18:10:05 +080094 * @link: platform-specific link value
95 * @return: link number which represents a PIRQ
96 */
Bin Mengb46c2082016-02-01 01:40:51 -080097int pirq_translate_link(struct udevice *dev, int link);
Bin Mengb5b6b012015-04-24 18:10:05 +080098
99/**
100 * pirq_assign_irq() - Assign an IRQ to a PIRQ link
101 *
102 * This function assigns the IRQ to a PIRQ link so that the PIRQ is routed to
103 * the 8259 PIC.
104 *
105 * Note: this function should be provided by the platform codes, as the
106 * implementation of interrupt router may be different.
107 *
Bin Mengb46c2082016-02-01 01:40:51 -0800108 * @dev: irq router's udevice
Bin Mengb5b6b012015-04-24 18:10:05 +0800109 * @link: link number which represents a PIRQ
110 * @irq: IRQ to which the PIRQ is routed
111 */
Bin Mengb46c2082016-02-01 01:40:51 -0800112void pirq_assign_irq(struct udevice *dev, int link, u8 irq);
Bin Mengb5b6b012015-04-24 18:10:05 +0800113
114/**
115 * pirq_route_irqs() - Route PIRQs to 8259 PIC
116 *
117 * This function configures all PCI devices' interrupt pins and maps them to
118 * PIRQs and finally 8259 PIC. The routed irq number is written to interrupt
119 * line register in the configuration space of the PCI device for OS to use.
120 * The configuration source is taken from a struct irq_info table, the format
121 * of which is defined in PIRQ routing table spec and PCI BIOS spec.
122 *
Bin Mengb46c2082016-02-01 01:40:51 -0800123 * @dev: irq router's udevice
Bin Mengb5b6b012015-04-24 18:10:05 +0800124 * @irq: pointer to the base address of the struct irq_info
125 * @num: number of entries in the struct irq_info
126 */
Bin Mengb46c2082016-02-01 01:40:51 -0800127void pirq_route_irqs(struct udevice *dev, struct irq_info *irq, int num);
Bin Mengb5b6b012015-04-24 18:10:05 +0800128
129/**
130 * copy_pirq_routing_table() - Copy a PIRQ routing table
131 *
132 * This helper function copies the given PIRQ routing table to a given address.
133 * Before copying, it does several sanity tests against the PIRQ routing table.
134 * It also fixes up the table checksum and align the given address to a 16 byte
135 * boundary to meet the PIRQ routing table spec requirements.
136 *
137 * @addr: address to store the copied PIRQ routing table
138 * @rt: pointer to the PIRQ routing table to copy from
139 * @return: end address of the copied PIRQ routing table
140 */
141u32 copy_pirq_routing_table(u32 addr, struct irq_routing_table *rt);
142
143#endif /* _PIRQ_ROUTING_H_ */