mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-16 23:18:51 +09:00
![Bin Meng](/assets/img/avatar_default.png)
On x86 boards, platform chipset receives up to four different interrupt signals from PCI devices (INTA/B/C/D), which in turn will be routed to chipset internal PIRQ lines then routed to 8259 PIC finally if configuring the whole system to work under the so-called PIC mode (in contrast to symmetric IO mode which uses IOAPIC). We add two major APIs to aid this, one for routing PIRQ and the other one for generating a PIRQ routing table. Signed-off-by: Bin Meng <bmeng.cn@gmail.com> Acked-by: Simon Glass <sjg@chromium.org>
140 lines
4.6 KiB
C
140 lines
4.6 KiB
C
/*
|
|
* Copyright (C) 2015, Bin Meng <bmeng.cn@gmail.com>
|
|
*
|
|
* Ported from coreboot src/arch/x86/include/arch/pirq_routing.h
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0+
|
|
*/
|
|
|
|
#ifndef _PIRQ_ROUTING_H_
|
|
#define _PIRQ_ROUTING_H_
|
|
|
|
/*
|
|
* This is the maximum number on interrupt entries that a PCI device may have.
|
|
* This is NOT the number of slots or devices in the system
|
|
* This is NOT the number of entries in the PIRQ table
|
|
*
|
|
* This tells us that in the PIRQ table, we are going to have 4 link-bitmap
|
|
* entries per PCI device which is fixed at 4: INTA, INTB, INTC, and INTD.
|
|
*
|
|
* CAUTION: If you change this, PIRQ routing will not work correctly.
|
|
*/
|
|
#define MAX_INTX_ENTRIES 4
|
|
|
|
#define PIRQ_SIGNATURE \
|
|
(('$' << 0) + ('P' << 8) + ('I' << 16) + ('R' << 24))
|
|
#define PIRQ_VERSION 0x0100
|
|
|
|
struct __packed irq_info {
|
|
u8 bus; /* Bus number */
|
|
u8 devfn; /* Device and function number */
|
|
struct __packed {
|
|
u8 link; /* IRQ line ID, 0=not routed */
|
|
u16 bitmap; /* Available IRQs */
|
|
} irq[MAX_INTX_ENTRIES];
|
|
u8 slot; /* Slot number, 0=onboard */
|
|
u8 rfu;
|
|
};
|
|
|
|
struct __packed irq_routing_table {
|
|
u32 signature; /* PIRQ_SIGNATURE */
|
|
u16 version; /* PIRQ_VERSION */
|
|
u16 size; /* Table size in bytes */
|
|
u8 rtr_bus; /* busno of the interrupt router */
|
|
u8 rtr_devfn; /* devfn of the interrupt router */
|
|
u16 exclusive_irqs; /* IRQs devoted exclusively to PCI usage */
|
|
u16 rtr_vendor; /* Vendor ID of the interrupt router */
|
|
u16 rtr_device; /* Device ID of the interrupt router */
|
|
u32 miniport_data;
|
|
u8 rfu[11];
|
|
u8 checksum; /* Modulo 256 checksum must give zero */
|
|
struct irq_info slots[CONFIG_IRQ_SLOT_COUNT];
|
|
};
|
|
|
|
/**
|
|
* get_irq_slot_count() - Get the number of entries in the irq_info table
|
|
*
|
|
* This calculates the number of entries for the irq_info table.
|
|
*
|
|
* @rt: pointer to the base address of the struct irq_info
|
|
* @return: number of entries
|
|
*/
|
|
static inline int get_irq_slot_count(struct irq_routing_table *rt)
|
|
{
|
|
return (rt->size - 32) / sizeof(struct irq_info);
|
|
}
|
|
|
|
/**
|
|
* pirq_check_irq_routed() - Check whether an IRQ is routed to 8259 PIC
|
|
*
|
|
* This function checks whether an IRQ is routed to 8259 PIC for a given link.
|
|
*
|
|
* Note: this function should be provided by the platform codes, as the
|
|
* implementation of interrupt router may be different.
|
|
*
|
|
* @link: link number which represents a PIRQ
|
|
* @irq: the 8259 IRQ number
|
|
* @return: true if the irq is already routed to 8259 for a given link,
|
|
* false elsewise
|
|
*/
|
|
bool pirq_check_irq_routed(int link, u8 irq);
|
|
|
|
/**
|
|
* pirq_translate_link() - Translate a link value
|
|
*
|
|
* This function translates a platform-specific link value to a link number.
|
|
* On Intel platforms, the link value is normally a offset into the PCI
|
|
* configuration space into the legacy bridge.
|
|
*
|
|
* Note: this function should be provided by the platform codes, as the
|
|
* implementation of interrupt router may be different.
|
|
*
|
|
* @link: platform-specific link value
|
|
* @return: link number which represents a PIRQ
|
|
*/
|
|
int pirq_translate_link(int link);
|
|
|
|
/**
|
|
* pirq_assign_irq() - Assign an IRQ to a PIRQ link
|
|
*
|
|
* This function assigns the IRQ to a PIRQ link so that the PIRQ is routed to
|
|
* the 8259 PIC.
|
|
*
|
|
* Note: this function should be provided by the platform codes, as the
|
|
* implementation of interrupt router may be different.
|
|
*
|
|
* @link: link number which represents a PIRQ
|
|
* @irq: IRQ to which the PIRQ is routed
|
|
*/
|
|
void pirq_assign_irq(int link, u8 irq);
|
|
|
|
/**
|
|
* pirq_route_irqs() - Route PIRQs to 8259 PIC
|
|
*
|
|
* This function configures all PCI devices' interrupt pins and maps them to
|
|
* PIRQs and finally 8259 PIC. The routed irq number is written to interrupt
|
|
* line register in the configuration space of the PCI device for OS to use.
|
|
* The configuration source is taken from a struct irq_info table, the format
|
|
* of which is defined in PIRQ routing table spec and PCI BIOS spec.
|
|
*
|
|
* @irq: pointer to the base address of the struct irq_info
|
|
* @num: number of entries in the struct irq_info
|
|
*/
|
|
void pirq_route_irqs(struct irq_info *irq, int num);
|
|
|
|
/**
|
|
* copy_pirq_routing_table() - Copy a PIRQ routing table
|
|
*
|
|
* This helper function copies the given PIRQ routing table to a given address.
|
|
* Before copying, it does several sanity tests against the PIRQ routing table.
|
|
* It also fixes up the table checksum and align the given address to a 16 byte
|
|
* boundary to meet the PIRQ routing table spec requirements.
|
|
*
|
|
* @addr: address to store the copied PIRQ routing table
|
|
* @rt: pointer to the PIRQ routing table to copy from
|
|
* @return: end address of the copied PIRQ routing table
|
|
*/
|
|
u32 copy_pirq_routing_table(u32 addr, struct irq_routing_table *rt);
|
|
|
|
#endif /* _PIRQ_ROUTING_H_ */
|