cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

iosapic.c (29115B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3** I/O Sapic Driver - PCI interrupt line support
      4**
      5**      (c) Copyright 1999 Grant Grundler
      6**      (c) Copyright 1999 Hewlett-Packard Company
      7**
      8**
      9** The I/O sapic driver manages the Interrupt Redirection Table which is
     10** the control logic to convert PCI line based interrupts into a Message
     11** Signaled Interrupt (aka Transaction Based Interrupt, TBI).
     12**
     13** Acronyms
     14** --------
     15** HPA  Hard Physical Address (aka MMIO address)
     16** IRQ  Interrupt ReQuest. Implies Line based interrupt.
     17** IRT	Interrupt Routing Table (provided by PAT firmware)
     18** IRdT Interrupt Redirection Table. IRQ line to TXN ADDR/DATA
     19**      table which is implemented in I/O SAPIC.
     20** ISR  Interrupt Service Routine. aka Interrupt handler.
     21** MSI	Message Signaled Interrupt. PCI 2.2 functionality.
     22**      aka Transaction Based Interrupt (or TBI).
     23** PA   Precision Architecture. HP's RISC architecture.
     24** RISC Reduced Instruction Set Computer.
     25**
     26**
     27** What's a Message Signalled Interrupt?
     28** -------------------------------------
     29** MSI is a write transaction which targets a processor and is similar
     30** to a processor write to memory or MMIO. MSIs can be generated by I/O
     31** devices as well as processors and require *architecture* to work.
     32**
     33** PA only supports MSI. So I/O subsystems must either natively generate
     34** MSIs (e.g. GSC or HP-PB) or convert line based interrupts into MSIs
     35** (e.g. PCI and EISA).  IA64 supports MSIs via a "local SAPIC" which
     36** acts on behalf of a processor.
     37**
     38** MSI allows any I/O device to interrupt any processor. This makes
     39** load balancing of the interrupt processing possible on an SMP platform.
     40** Interrupts are also ordered WRT to DMA data.  It's possible on I/O
     41** coherent systems to completely eliminate PIO reads from the interrupt
     42** path. The device and driver must be designed and implemented to
     43** guarantee all DMA has been issued (issues about atomicity here)
     44** before the MSI is issued. I/O status can then safely be read from
     45** DMA'd data by the ISR.
     46**
     47**
     48** PA Firmware
     49** -----------
     50** PA-RISC platforms have two fundamentally different types of firmware.
     51** For PCI devices, "Legacy" PDC initializes the "INTERRUPT_LINE" register
     52** and BARs similar to a traditional PC BIOS.
     53** The newer "PAT" firmware supports PDC calls which return tables.
     54** PAT firmware only initializes the PCI Console and Boot interface.
     55** With these tables, the OS can program all other PCI devices.
     56**
     57** One such PAT PDC call returns the "Interrupt Routing Table" (IRT).
     58** The IRT maps each PCI slot's INTA-D "output" line to an I/O SAPIC
     59** input line.  If the IRT is not available, this driver assumes
     60** INTERRUPT_LINE register has been programmed by firmware. The latter
     61** case also means online addition of PCI cards can NOT be supported
     62** even if HW support is present.
     63**
     64** All platforms with PAT firmware to date (Oct 1999) use one Interrupt
     65** Routing Table for the entire platform.
     66**
     67** Where's the iosapic?
     68** --------------------
     69** I/O sapic is part of the "Core Electronics Complex". And on HP platforms
     70** it's integrated as part of the PCI bus adapter, "lba".  So no bus walk
     71** will discover I/O Sapic. I/O Sapic driver learns about each device
     72** when lba driver advertises the presence of the I/O sapic by calling
     73** iosapic_register().
     74**
     75**
     76** IRQ handling notes
     77** ------------------
     78** The IO-SAPIC can indicate to the CPU which interrupt was asserted.
     79** So, unlike the GSC-ASIC and Dino, we allocate one CPU interrupt per
     80** IO-SAPIC interrupt and call the device driver's handler directly.
     81** The IO-SAPIC driver hijacks the CPU interrupt handler so it can
     82** issue the End Of Interrupt command to the IO-SAPIC.
     83**
     84** Overview of exported iosapic functions
     85** --------------------------------------
     86** (caveat: code isn't finished yet - this is just the plan)
     87**
     88** iosapic_init:
     89**   o initialize globals (lock, etc)
     90**   o try to read IRT. Presence of IRT determines if this is
     91**     a PAT platform or not.
     92**
     93** iosapic_register():
     94**   o create iosapic_info instance data structure
     95**   o allocate vector_info array for this iosapic
     96**   o initialize vector_info - read corresponding IRdT?
     97**
     98** iosapic_xlate_pin: (only called by fixup_irq for PAT platform)
     99**   o intr_pin = read cfg (INTERRUPT_PIN);
    100**   o if (device under PCI-PCI bridge)
    101**               translate slot/pin
    102**
    103** iosapic_fixup_irq:
    104**   o if PAT platform (IRT present)
    105**	   intr_pin = iosapic_xlate_pin(isi,pcidev):
    106**         intr_line = find IRT entry(isi, PCI_SLOT(pcidev), intr_pin)
    107**         save IRT entry into vector_info later
    108**         write cfg INTERRUPT_LINE (with intr_line)?
    109**     else
    110**         intr_line = pcidev->irq
    111**         IRT pointer = NULL
    112**     endif
    113**   o locate vector_info (needs: isi, intr_line)
    114**   o allocate processor "irq" and get txn_addr/data
    115**   o request_irq(processor_irq,  iosapic_interrupt, vector_info,...)
    116**
    117** iosapic_enable_irq:
    118**   o clear any pending IRQ on that line
    119**   o enable IRdT - call enable_irq(vector[line]->processor_irq)
    120**   o write EOI in case line is already asserted.
    121**
    122** iosapic_disable_irq:
    123**   o disable IRdT - call disable_irq(vector[line]->processor_irq)
    124*/
    125
    126#include <linux/pci.h>
    127
    128#include <asm/pdc.h>
    129#include <asm/pdcpat.h>
    130#ifdef CONFIG_SUPERIO
    131#include <asm/superio.h>
    132#endif
    133
    134#include <asm/ropes.h>
    135#include "iosapic_private.h"
    136
    137#define MODULE_NAME "iosapic"
    138
    139/* "local" compile flags */
    140#undef PCI_BRIDGE_FUNCS
    141#undef DEBUG_IOSAPIC
    142#undef DEBUG_IOSAPIC_IRT
    143
    144
    145#ifdef DEBUG_IOSAPIC
    146#define DBG(x...) printk(x)
    147#else /* DEBUG_IOSAPIC */
    148#define DBG(x...)
    149#endif /* DEBUG_IOSAPIC */
    150
    151#ifdef DEBUG_IOSAPIC_IRT
    152#define DBG_IRT(x...) printk(x)
    153#else
    154#define DBG_IRT(x...)
    155#endif
    156
    157#ifdef CONFIG_64BIT
    158#define COMPARE_IRTE_ADDR(irte, hpa)	((irte)->dest_iosapic_addr == (hpa))
    159#else
    160#define COMPARE_IRTE_ADDR(irte, hpa)	\
    161		((irte)->dest_iosapic_addr == ((hpa) | 0xffffffff00000000ULL))
    162#endif
    163
    164#define IOSAPIC_REG_SELECT              0x00
    165#define IOSAPIC_REG_WINDOW              0x10
    166#define IOSAPIC_REG_EOI                 0x40
    167
    168#define IOSAPIC_REG_VERSION		0x1
    169
    170#define IOSAPIC_IRDT_ENTRY(idx)		(0x10+(idx)*2)
    171#define IOSAPIC_IRDT_ENTRY_HI(idx)	(0x11+(idx)*2)
    172
    173static inline unsigned int iosapic_read(void __iomem *iosapic, unsigned int reg)
    174{
    175	writel(reg, iosapic + IOSAPIC_REG_SELECT);
    176	return readl(iosapic + IOSAPIC_REG_WINDOW);
    177}
    178
    179static inline void iosapic_write(void __iomem *iosapic, unsigned int reg, u32 val)
    180{
    181	writel(reg, iosapic + IOSAPIC_REG_SELECT);
    182	writel(val, iosapic + IOSAPIC_REG_WINDOW);
    183}
    184
    185#define IOSAPIC_VERSION_MASK	0x000000ff
    186#define	IOSAPIC_VERSION(ver)	((int) (ver & IOSAPIC_VERSION_MASK))
    187
    188#define IOSAPIC_MAX_ENTRY_MASK          0x00ff0000
    189#define IOSAPIC_MAX_ENTRY_SHIFT         0x10
    190#define	IOSAPIC_IRDT_MAX_ENTRY(ver)	\
    191	(int) (((ver) & IOSAPIC_MAX_ENTRY_MASK) >> IOSAPIC_MAX_ENTRY_SHIFT)
    192
    193/* bits in the "low" I/O Sapic IRdT entry */
    194#define IOSAPIC_IRDT_ENABLE       0x10000
    195#define IOSAPIC_IRDT_PO_LOW       0x02000
    196#define IOSAPIC_IRDT_LEVEL_TRIG   0x08000
    197#define IOSAPIC_IRDT_MODE_LPRI    0x00100
    198
    199/* bits in the "high" I/O Sapic IRdT entry */
    200#define IOSAPIC_IRDT_ID_EID_SHIFT              0x10
    201
    202
    203static DEFINE_SPINLOCK(iosapic_lock);
    204
    205static inline void iosapic_eoi(void __iomem *addr, unsigned int data)
    206{
    207	__raw_writel(data, addr);
    208}
    209
    210/*
    211** REVISIT: future platforms may have more than one IRT.
    212** If so, the following three fields form a structure which
    213** then be linked into a list. Names are chosen to make searching
    214** for them easy - not necessarily accurate (eg "cell").
    215**
    216** Alternative: iosapic_info could point to the IRT it's in.
    217** iosapic_register() could search a list of IRT's.
    218*/
    219static struct irt_entry *irt_cell;
    220static size_t irt_num_entry;
    221
    222static struct irt_entry *iosapic_alloc_irt(int num_entries)
    223{
    224	unsigned long a;
    225
    226	/* The IRT needs to be 8-byte aligned for the PDC call. 
    227	 * Normally kmalloc would guarantee larger alignment, but
    228	 * if CONFIG_DEBUG_SLAB is enabled, then we can get only
    229	 * 4-byte alignment on 32-bit kernels
    230	 */
    231	a = (unsigned long)kmalloc(sizeof(struct irt_entry) * num_entries + 8, GFP_KERNEL);
    232	a = (a + 7UL) & ~7UL;
    233	return (struct irt_entry *)a;
    234}
    235
    236/**
    237 * iosapic_load_irt - Fill in the interrupt routing table
    238 * @cell_num: The cell number of the CPU we're currently executing on
    239 * @irt: The address to place the new IRT at
    240 * @return The number of entries found
    241 *
    242 * The "Get PCI INT Routing Table Size" option returns the number of 
    243 * entries in the PCI interrupt routing table for the cell specified 
    244 * in the cell_number argument.  The cell number must be for a cell 
    245 * within the caller's protection domain.
    246 *
    247 * The "Get PCI INT Routing Table" option returns, for the cell 
    248 * specified in the cell_number argument, the PCI interrupt routing 
    249 * table in the caller allocated memory pointed to by mem_addr.
    250 * We assume the IRT only contains entries for I/O SAPIC and
    251 * calculate the size based on the size of I/O sapic entries.
    252 *
    253 * The PCI interrupt routing table entry format is derived from the
    254 * IA64 SAL Specification 2.4.   The PCI interrupt routing table defines
    255 * the routing of PCI interrupt signals between the PCI device output
    256 * "pins" and the IO SAPICs' input "lines" (including core I/O PCI
    257 * devices).  This table does NOT include information for devices/slots
    258 * behind PCI to PCI bridges. See PCI to PCI Bridge Architecture Spec.
    259 * for the architected method of routing of IRQ's behind PPB's.
    260 */
    261
    262
    263static int __init
    264iosapic_load_irt(unsigned long cell_num, struct irt_entry **irt)
    265{
    266	long status;              /* PDC return value status */
    267	struct irt_entry *table;  /* start of interrupt routing tbl */
    268	unsigned long num_entries = 0UL;
    269
    270	BUG_ON(!irt);
    271
    272	if (is_pdc_pat()) {
    273		/* Use pat pdc routine to get interrupt routing table size */
    274		DBG("calling get_irt_size (cell %ld)\n", cell_num);
    275		status = pdc_pat_get_irt_size(&num_entries, cell_num);
    276		DBG("get_irt_size: %ld\n", status);
    277
    278		BUG_ON(status != PDC_OK);
    279		BUG_ON(num_entries == 0);
    280
    281		/*
    282		** allocate memory for interrupt routing table
    283		** This interface isn't really right. We are assuming
    284		** the contents of the table are exclusively
    285		** for I/O sapic devices.
    286		*/
    287		table = iosapic_alloc_irt(num_entries);
    288		if (table == NULL) {
    289			printk(KERN_WARNING MODULE_NAME ": read_irt : can "
    290					"not alloc mem for IRT\n");
    291			return 0;
    292		}
    293
    294		/* get PCI INT routing table */
    295		status = pdc_pat_get_irt(table, cell_num);
    296		DBG("pdc_pat_get_irt: %ld\n", status);
    297		WARN_ON(status != PDC_OK);
    298	} else {
    299		/*
    300		** C3000/J5000 (and similar) platforms with Sprockets PDC
    301		** will return exactly one IRT for all iosapics.
    302		** So if we have one, don't need to get it again.
    303		*/
    304		if (irt_cell)
    305			return 0;
    306
    307		/* Should be using the Elroy's HPA, but it's ignored anyway */
    308		status = pdc_pci_irt_size(&num_entries, 0);
    309		DBG("pdc_pci_irt_size: %ld\n", status);
    310
    311		if (status != PDC_OK) {
    312			/* Not a "legacy" system with I/O SAPIC either */
    313			return 0;
    314		}
    315
    316		BUG_ON(num_entries == 0);
    317
    318		table = iosapic_alloc_irt(num_entries);
    319		if (!table) {
    320			printk(KERN_WARNING MODULE_NAME ": read_irt : can "
    321					"not alloc mem for IRT\n");
    322			return 0;
    323		}
    324
    325		/* HPA ignored by this call too. */
    326		status = pdc_pci_irt(num_entries, 0, table);
    327		BUG_ON(status != PDC_OK);
    328	}
    329
    330	/* return interrupt table address */
    331	*irt = table;
    332
    333#ifdef DEBUG_IOSAPIC_IRT
    334{
    335	struct irt_entry *p = table;
    336	int i;
    337
    338	printk(MODULE_NAME " Interrupt Routing Table (cell %ld)\n", cell_num);
    339	printk(MODULE_NAME " start = 0x%p num_entries %ld entry_size %d\n",
    340		table,
    341		num_entries,
    342		(int) sizeof(struct irt_entry));
    343
    344	for (i = 0 ; i < num_entries ; i++, p++) {
    345		printk(MODULE_NAME " %02x %02x %02x %02x %02x %02x %02x %02x %08x%08x\n",
    346		p->entry_type, p->entry_length, p->interrupt_type,
    347		p->polarity_trigger, p->src_bus_irq_devno, p->src_bus_id,
    348		p->src_seg_id, p->dest_iosapic_intin,
    349		((u32 *) p)[2],
    350		((u32 *) p)[3]
    351		);
    352	}
    353}
    354#endif /* DEBUG_IOSAPIC_IRT */
    355
    356	return num_entries;
    357}
    358
    359
    360
    361void __init iosapic_init(void)
    362{
    363	unsigned long cell = 0;
    364
    365	DBG("iosapic_init()\n");
    366
    367#ifdef __LP64__
    368	if (is_pdc_pat()) {
    369		int status;
    370		struct pdc_pat_cell_num cell_info;
    371
    372		status = pdc_pat_cell_get_number(&cell_info);
    373		if (status == PDC_OK) {
    374			cell = cell_info.cell_num;
    375		}
    376	}
    377#endif
    378
    379	/* get interrupt routing table for this cell */
    380	irt_num_entry = iosapic_load_irt(cell, &irt_cell);
    381	if (irt_num_entry == 0)
    382		irt_cell = NULL;	/* old PDC w/o iosapic */
    383}
    384
    385
    386/*
    387** Return the IRT entry in case we need to look something else up.
    388*/
    389static struct irt_entry *
    390irt_find_irqline(struct iosapic_info *isi, u8 slot, u8 intr_pin)
    391{
    392	struct irt_entry *i = irt_cell;
    393	int cnt;	/* track how many entries we've looked at */
    394	u8 irq_devno = (slot << IRT_DEV_SHIFT) | (intr_pin-1);
    395
    396	DBG_IRT("irt_find_irqline() SLOT %d pin %d\n", slot, intr_pin);
    397
    398	for (cnt=0; cnt < irt_num_entry; cnt++, i++) {
    399
    400		/*
    401		** Validate: entry_type, entry_length, interrupt_type
    402		**
    403		** Difference between validate vs compare is the former
    404		** should print debug info and is not expected to "fail"
    405		** on current platforms.
    406		*/
    407		if (i->entry_type != IRT_IOSAPIC_TYPE) {
    408			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d type %d\n", i, cnt, i->entry_type);
    409			continue;
    410		}
    411		
    412		if (i->entry_length != IRT_IOSAPIC_LENGTH) {
    413			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry %d  length %d\n", i, cnt, i->entry_length);
    414			continue;
    415		}
    416
    417		if (i->interrupt_type != IRT_VECTORED_INTR) {
    418			DBG_IRT(KERN_WARNING MODULE_NAME ":find_irqline(0x%p): skipping entry  %d interrupt_type %d\n", i, cnt, i->interrupt_type);
    419			continue;
    420		}
    421
    422		if (!COMPARE_IRTE_ADDR(i, isi->isi_hpa))
    423			continue;
    424
    425		if ((i->src_bus_irq_devno & IRT_IRQ_DEVNO_MASK) != irq_devno)
    426			continue;
    427
    428		/*
    429		** Ignore: src_bus_id and rc_seg_id correlate with
    430		**         iosapic_info->isi_hpa on HP platforms.
    431		**         If needed, pass in "PFA" (aka config space addr)
    432		**         instead of slot.
    433		*/
    434
    435		/* Found it! */
    436		return i;
    437	}
    438
    439	printk(KERN_WARNING MODULE_NAME ": 0x%lx : no IRT entry for slot %d, pin %d\n",
    440			isi->isi_hpa, slot, intr_pin);
    441	return NULL;
    442}
    443
    444
    445/*
    446** xlate_pin() supports the skewing of IRQ lines done by subsidiary bridges.
    447** Legacy PDC already does this translation for us and stores it in INTR_LINE.
    448**
    449** PAT PDC needs to basically do what legacy PDC does:
    450** o read PIN
    451** o adjust PIN in case device is "behind" a PPB
    452**     (eg 4-port 100BT and SCSI/LAN "Combo Card")
    453** o convert slot/pin to I/O SAPIC input line.
    454**
    455** HP platforms only support:
    456** o one level of skewing for any number of PPBs
    457** o only support PCI-PCI Bridges.
    458*/
    459static struct irt_entry *
    460iosapic_xlate_pin(struct iosapic_info *isi, struct pci_dev *pcidev)
    461{
    462	u8 intr_pin, intr_slot;
    463
    464	pci_read_config_byte(pcidev, PCI_INTERRUPT_PIN, &intr_pin);
    465
    466	DBG_IRT("iosapic_xlate_pin(%s) SLOT %d pin %d\n",
    467		pcidev->slot_name, PCI_SLOT(pcidev->devfn), intr_pin);
    468
    469	if (intr_pin == 0) {
    470		/* The device does NOT support/use IRQ lines.  */
    471		return NULL;
    472	}
    473
    474	/* Check if pcidev behind a PPB */
    475	if (pcidev->bus->parent) {
    476		/* Convert pcidev INTR_PIN into something we
    477		** can lookup in the IRT.
    478		*/
    479#ifdef PCI_BRIDGE_FUNCS
    480		/*
    481		** Proposal #1:
    482		**
    483		** call implementation specific translation function
    484		** This is architecturally "cleaner". HP-UX doesn't
    485		** support other secondary bus types (eg. E/ISA) directly.
    486		** May be needed for other processor (eg IA64) architectures
    487		** or by some ambitous soul who wants to watch TV.
    488		*/
    489		if (pci_bridge_funcs->xlate_intr_line) {
    490			intr_pin = pci_bridge_funcs->xlate_intr_line(pcidev);
    491		}
    492#else	/* PCI_BRIDGE_FUNCS */
    493		struct pci_bus *p = pcidev->bus;
    494		/*
    495		** Proposal #2:
    496		** The "pin" is skewed ((pin + dev - 1) % 4).
    497		**
    498		** This isn't very clean since I/O SAPIC must assume:
    499		**   - all platforms only have PCI busses.
    500		**   - only PCI-PCI bridge (eg not PCI-EISA, PCI-PCMCIA)
    501		**   - IRQ routing is only skewed once regardless of
    502		**     the number of PPB's between iosapic and device.
    503		**     (Bit3 expansion chassis follows this rule)
    504		**
    505		** Advantage is it's really easy to implement.
    506		*/
    507		intr_pin = pci_swizzle_interrupt_pin(pcidev, intr_pin);
    508#endif /* PCI_BRIDGE_FUNCS */
    509
    510		/*
    511		 * Locate the host slot of the PPB.
    512		 */
    513		while (p->parent->parent)
    514			p = p->parent;
    515
    516		intr_slot = PCI_SLOT(p->self->devfn);
    517	} else {
    518		intr_slot = PCI_SLOT(pcidev->devfn);
    519	}
    520	DBG_IRT("iosapic_xlate_pin:  bus %d slot %d pin %d\n",
    521			pcidev->bus->busn_res.start, intr_slot, intr_pin);
    522
    523	return irt_find_irqline(isi, intr_slot, intr_pin);
    524}
    525
    526static void iosapic_rd_irt_entry(struct vector_info *vi , u32 *dp0, u32 *dp1)
    527{
    528	struct iosapic_info *isp = vi->iosapic;
    529	u8 idx = vi->irqline;
    530
    531	*dp0 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY(idx));
    532	*dp1 = iosapic_read(isp->addr, IOSAPIC_IRDT_ENTRY_HI(idx));
    533}
    534
    535
    536static void iosapic_wr_irt_entry(struct vector_info *vi, u32 dp0, u32 dp1)
    537{
    538	struct iosapic_info *isp = vi->iosapic;
    539
    540	DBG_IRT("iosapic_wr_irt_entry(): irq %d hpa %lx 0x%x 0x%x\n",
    541		vi->irqline, isp->isi_hpa, dp0, dp1);
    542
    543	iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY(vi->irqline), dp0);
    544
    545	/* Read the window register to flush the writes down to HW  */
    546	dp0 = readl(isp->addr+IOSAPIC_REG_WINDOW);
    547
    548	iosapic_write(isp->addr, IOSAPIC_IRDT_ENTRY_HI(vi->irqline), dp1);
    549
    550	/* Read the window register to flush the writes down to HW  */
    551	dp1 = readl(isp->addr+IOSAPIC_REG_WINDOW);
    552}
    553
    554/*
    555** set_irt prepares the data (dp0, dp1) according to the vector_info
    556** and target cpu (id_eid).  dp0/dp1 are then used to program I/O SAPIC
    557** IRdT for the given "vector" (aka IRQ line).
    558*/
    559static void
    560iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1)
    561{
    562	u32 mode = 0;
    563	struct irt_entry *p = vi->irte;
    564
    565	if ((p->polarity_trigger & IRT_PO_MASK) == IRT_ACTIVE_LO)
    566		mode |= IOSAPIC_IRDT_PO_LOW;
    567
    568	if (((p->polarity_trigger >> IRT_EL_SHIFT) & IRT_EL_MASK) == IRT_LEVEL_TRIG)
    569		mode |= IOSAPIC_IRDT_LEVEL_TRIG;
    570
    571	/*
    572	** IA64 REVISIT
    573	** PA doesn't support EXTINT or LPRIO bits.
    574	*/
    575
    576	*dp0 = mode | (u32) vi->txn_data;
    577
    578	/*
    579	** Extracting id_eid isn't a real clean way of getting it.
    580	** But the encoding is the same for both PA and IA64 platforms.
    581	*/
    582	if (is_pdc_pat()) {
    583		/*
    584		** PAT PDC just hands it to us "right".
    585		** txn_addr comes from cpu_data[x].txn_addr.
    586		*/
    587		*dp1 = (u32) (vi->txn_addr);
    588	} else {
    589		/* 
    590		** eg if base_addr == 0xfffa0000),
    591		**    we want to get 0xa0ff0000.
    592		**
    593		** eid	0x0ff00000 -> 0x00ff0000
    594		** id	0x000ff000 -> 0xff000000
    595		*/
    596		*dp1 = (((u32)vi->txn_addr & 0x0ff00000) >> 4) |
    597			(((u32)vi->txn_addr & 0x000ff000) << 12);
    598	}
    599	DBG_IRT("iosapic_set_irt_data(): 0x%x 0x%x\n", *dp0, *dp1);
    600}
    601
    602
    603static void iosapic_mask_irq(struct irq_data *d)
    604{
    605	unsigned long flags;
    606	struct vector_info *vi = irq_data_get_irq_chip_data(d);
    607	u32 d0, d1;
    608
    609	spin_lock_irqsave(&iosapic_lock, flags);
    610	iosapic_rd_irt_entry(vi, &d0, &d1);
    611	d0 |= IOSAPIC_IRDT_ENABLE;
    612	iosapic_wr_irt_entry(vi, d0, d1);
    613	spin_unlock_irqrestore(&iosapic_lock, flags);
    614}
    615
    616static void iosapic_unmask_irq(struct irq_data *d)
    617{
    618	struct vector_info *vi = irq_data_get_irq_chip_data(d);
    619	u32 d0, d1;
    620
    621	/* data is initialized by fixup_irq */
    622	WARN_ON(vi->txn_irq  == 0);
    623
    624	iosapic_set_irt_data(vi, &d0, &d1);
    625	iosapic_wr_irt_entry(vi, d0, d1);
    626
    627#ifdef DEBUG_IOSAPIC_IRT
    628{
    629	u32 *t = (u32 *) ((ulong) vi->eoi_addr & ~0xffUL);
    630	printk("iosapic_enable_irq(): regs %p", vi->eoi_addr);
    631	for ( ; t < vi->eoi_addr; t++)
    632		printk(" %x", readl(t));
    633	printk("\n");
    634}
    635
    636printk("iosapic_enable_irq(): sel ");
    637{
    638	struct iosapic_info *isp = vi->iosapic;
    639
    640	for (d0=0x10; d0<0x1e; d0++) {
    641		d1 = iosapic_read(isp->addr, d0);
    642		printk(" %x", d1);
    643	}
    644}
    645printk("\n");
    646#endif
    647
    648	/*
    649	 * Issuing I/O SAPIC an EOI causes an interrupt IFF IRQ line is
    650	 * asserted.  IRQ generally should not be asserted when a driver
    651	 * enables their IRQ. It can lead to "interesting" race conditions
    652	 * in the driver initialization sequence.
    653	 */
    654	DBG(KERN_DEBUG "enable_irq(%d): eoi(%p, 0x%x)\n", d->irq,
    655			vi->eoi_addr, vi->eoi_data);
    656	iosapic_eoi(vi->eoi_addr, vi->eoi_data);
    657}
    658
    659static void iosapic_eoi_irq(struct irq_data *d)
    660{
    661	struct vector_info *vi = irq_data_get_irq_chip_data(d);
    662
    663	iosapic_eoi(vi->eoi_addr, vi->eoi_data);
    664	cpu_eoi_irq(d);
    665}
    666
    667#ifdef CONFIG_SMP
    668static int iosapic_set_affinity_irq(struct irq_data *d,
    669				    const struct cpumask *dest, bool force)
    670{
    671	struct vector_info *vi = irq_data_get_irq_chip_data(d);
    672	u32 d0, d1, dummy_d0;
    673	unsigned long flags;
    674	int dest_cpu;
    675
    676	dest_cpu = cpu_check_affinity(d, dest);
    677	if (dest_cpu < 0)
    678		return -1;
    679
    680	cpumask_copy(irq_data_get_affinity_mask(d), cpumask_of(dest_cpu));
    681	vi->txn_addr = txn_affinity_addr(d->irq, dest_cpu);
    682
    683	spin_lock_irqsave(&iosapic_lock, flags);
    684	/* d1 contains the destination CPU, so only want to set that
    685	 * entry */
    686	iosapic_rd_irt_entry(vi, &d0, &d1);
    687	iosapic_set_irt_data(vi, &dummy_d0, &d1);
    688	iosapic_wr_irt_entry(vi, d0, d1);
    689	spin_unlock_irqrestore(&iosapic_lock, flags);
    690
    691	return 0;
    692}
    693#endif
    694
    695static struct irq_chip iosapic_interrupt_type = {
    696	.name		=	"IO-SAPIC-level",
    697	.irq_unmask	=	iosapic_unmask_irq,
    698	.irq_mask	=	iosapic_mask_irq,
    699	.irq_ack	=	cpu_ack_irq,
    700	.irq_eoi	=	iosapic_eoi_irq,
    701#ifdef CONFIG_SMP
    702	.irq_set_affinity =	iosapic_set_affinity_irq,
    703#endif
    704};
    705
    706int iosapic_fixup_irq(void *isi_obj, struct pci_dev *pcidev)
    707{
    708	struct iosapic_info *isi = isi_obj;
    709	struct irt_entry *irte = NULL;  /* only used if PAT PDC */
    710	struct vector_info *vi;
    711	int isi_line;	/* line used by device */
    712
    713	if (!isi) {
    714		printk(KERN_WARNING MODULE_NAME ": hpa not registered for %s\n",
    715			pci_name(pcidev));
    716		return -1;
    717	}
    718
    719#ifdef CONFIG_SUPERIO
    720	/*
    721	 * HACK ALERT! (non-compliant PCI device support)
    722	 *
    723	 * All SuckyIO interrupts are routed through the PIC's on function 1.
    724	 * But SuckyIO OHCI USB controller gets an IRT entry anyway because
    725	 * it advertises INT D for INT_PIN.  Use that IRT entry to get the
    726	 * SuckyIO interrupt routing for PICs on function 1 (*BLEECCHH*).
    727	 */
    728	if (is_superio_device(pcidev)) {
    729		/* We must call superio_fixup_irq() to register the pdev */
    730		pcidev->irq = superio_fixup_irq(pcidev);
    731
    732		/* Don't return if need to program the IOSAPIC's IRT... */
    733		if (PCI_FUNC(pcidev->devfn) != SUPERIO_USB_FN)
    734			return pcidev->irq;
    735	}
    736#endif /* CONFIG_SUPERIO */
    737
    738	/* lookup IRT entry for isi/slot/pin set */
    739	irte = iosapic_xlate_pin(isi, pcidev);
    740	if (!irte) {
    741		printk("iosapic: no IRTE for %s (IRQ not connected?)\n",
    742				pci_name(pcidev));
    743		return -1;
    744	}
    745	DBG_IRT("iosapic_fixup_irq(): irte %p %x %x %x %x %x %x %x %x\n",
    746		irte,
    747		irte->entry_type,
    748		irte->entry_length,
    749		irte->polarity_trigger,
    750		irte->src_bus_irq_devno,
    751		irte->src_bus_id,
    752		irte->src_seg_id,
    753		irte->dest_iosapic_intin,
    754		(u32) irte->dest_iosapic_addr);
    755	isi_line = irte->dest_iosapic_intin;
    756
    757	/* get vector info for this input line */
    758	vi = isi->isi_vector + isi_line;
    759	DBG_IRT("iosapic_fixup_irq:  line %d vi 0x%p\n", isi_line, vi);
    760
    761	/* If this IRQ line has already been setup, skip it */
    762	if (vi->irte)
    763		goto out;
    764
    765	vi->irte = irte;
    766
    767	/*
    768	 * Allocate processor IRQ
    769	 *
    770	 * XXX/FIXME The txn_alloc_irq() code and related code should be
    771	 * moved to enable_irq(). That way we only allocate processor IRQ
    772	 * bits for devices that actually have drivers claiming them.
    773	 * Right now we assign an IRQ to every PCI device present,
    774	 * regardless of whether it's used or not.
    775	 */
    776	vi->txn_irq = txn_alloc_irq(8);
    777
    778	if (vi->txn_irq < 0)
    779		panic("I/O sapic: couldn't get TXN IRQ\n");
    780
    781	/* enable_irq() will use txn_* to program IRdT */
    782	vi->txn_addr = txn_alloc_addr(vi->txn_irq);
    783	vi->txn_data = txn_alloc_data(vi->txn_irq);
    784
    785	vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
    786	vi->eoi_data = cpu_to_le32(vi->txn_data);
    787
    788	cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
    789
    790 out:
    791	pcidev->irq = vi->txn_irq;
    792
    793	DBG_IRT("iosapic_fixup_irq() %d:%d %x %x line %d irq %d\n",
    794		PCI_SLOT(pcidev->devfn), PCI_FUNC(pcidev->devfn),
    795		pcidev->vendor, pcidev->device, isi_line, pcidev->irq);
    796
    797	return pcidev->irq;
    798}
    799
    800static struct iosapic_info *iosapic_list;
    801
    802#ifdef CONFIG_64BIT
    803int iosapic_serial_irq(struct parisc_device *dev)
    804{
    805	struct iosapic_info *isi;
    806	struct irt_entry *irte;
    807	struct vector_info *vi;
    808	int cnt;
    809	int intin;
    810
    811	intin = (dev->mod_info >> 24) & 15;
    812
    813	/* lookup IRT entry for isi/slot/pin set */
    814	for (cnt = 0; cnt < irt_num_entry; cnt++) {
    815		irte = &irt_cell[cnt];
    816		if (COMPARE_IRTE_ADDR(irte, dev->mod0) &&
    817		    irte->dest_iosapic_intin == intin)
    818			break;
    819	}
    820	if (cnt >= irt_num_entry)
    821		return 0; /* no irq found, force polling */
    822
    823	DBG_IRT("iosapic_serial_irq(): irte %p %x %x %x %x %x %x %x %x\n",
    824		irte,
    825		irte->entry_type,
    826		irte->entry_length,
    827		irte->polarity_trigger,
    828		irte->src_bus_irq_devno,
    829		irte->src_bus_id,
    830		irte->src_seg_id,
    831		irte->dest_iosapic_intin,
    832		(u32) irte->dest_iosapic_addr);
    833
    834	/* search for iosapic */
    835	for (isi = iosapic_list; isi; isi = isi->isi_next)
    836		if (isi->isi_hpa == dev->mod0)
    837			break;
    838	if (!isi)
    839		return 0; /* no iosapic found, force polling */
    840
    841	/* get vector info for this input line */
    842	vi = isi->isi_vector + intin;
    843	DBG_IRT("iosapic_serial_irq:  line %d vi 0x%p\n", iosapic_intin, vi);
    844
    845	/* If this IRQ line has already been setup, skip it */
    846	if (vi->irte)
    847		goto out;
    848
    849	vi->irte = irte;
    850
    851	/*
    852	 * Allocate processor IRQ
    853	 *
    854	 * XXX/FIXME The txn_alloc_irq() code and related code should be
    855	 * moved to enable_irq(). That way we only allocate processor IRQ
    856	 * bits for devices that actually have drivers claiming them.
    857	 * Right now we assign an IRQ to every PCI device present,
    858	 * regardless of whether it's used or not.
    859	 */
    860	vi->txn_irq = txn_alloc_irq(8);
    861
    862	if (vi->txn_irq < 0)
    863		panic("I/O sapic: couldn't get TXN IRQ\n");
    864
    865	/* enable_irq() will use txn_* to program IRdT */
    866	vi->txn_addr = txn_alloc_addr(vi->txn_irq);
    867	vi->txn_data = txn_alloc_data(vi->txn_irq);
    868
    869	vi->eoi_addr = isi->addr + IOSAPIC_REG_EOI;
    870	vi->eoi_data = cpu_to_le32(vi->txn_data);
    871
    872	cpu_claim_irq(vi->txn_irq, &iosapic_interrupt_type, vi);
    873
    874 out:
    875
    876	return vi->txn_irq;
    877}
    878#endif
    879
    880
    881/*
    882** squirrel away the I/O Sapic Version
    883*/
    884static unsigned int
    885iosapic_rd_version(struct iosapic_info *isi)
    886{
    887	return iosapic_read(isi->addr, IOSAPIC_REG_VERSION);
    888}
    889
    890
    891/*
    892** iosapic_register() is called by "drivers" with an integrated I/O SAPIC.
    893** Caller must be certain they have an I/O SAPIC and know its MMIO address.
    894**
    895**	o allocate iosapic_info and add it to the list
    896**	o read iosapic version and squirrel that away
    897**	o read size of IRdT.
    898**	o allocate and initialize isi_vector[]
    899**	o allocate irq region
    900*/
    901void *iosapic_register(unsigned long hpa)
    902{
    903	struct iosapic_info *isi = NULL;
    904	struct irt_entry *irte = irt_cell;
    905	struct vector_info *vip;
    906	int cnt;	/* track how many entries we've looked at */
    907
    908	/*
    909	 * Astro based platforms can only support PCI OLARD if they implement
    910	 * PAT PDC.  Legacy PDC omits LBAs with no PCI devices from the IRT.
    911	 * Search the IRT and ignore iosapic's which aren't in the IRT.
    912	 */
    913	for (cnt=0; cnt < irt_num_entry; cnt++, irte++) {
    914		WARN_ON(IRT_IOSAPIC_TYPE != irte->entry_type);
    915		if (COMPARE_IRTE_ADDR(irte, hpa))
    916			break;
    917	}
    918
    919	if (cnt >= irt_num_entry) {
    920		DBG("iosapic_register() ignoring 0x%lx (NOT FOUND)\n", hpa);
    921		return NULL;
    922	}
    923
    924	isi = kzalloc(sizeof(struct iosapic_info), GFP_KERNEL);
    925	if (!isi) {
    926		BUG();
    927		return NULL;
    928	}
    929
    930	isi->addr = ioremap(hpa, 4096);
    931	isi->isi_hpa = hpa;
    932	isi->isi_version = iosapic_rd_version(isi);
    933	isi->isi_num_vectors = IOSAPIC_IRDT_MAX_ENTRY(isi->isi_version) + 1;
    934
    935	vip = isi->isi_vector = kcalloc(isi->isi_num_vectors,
    936					sizeof(struct vector_info), GFP_KERNEL);
    937	if (vip == NULL) {
    938		kfree(isi);
    939		return NULL;
    940	}
    941
    942	for (cnt=0; cnt < isi->isi_num_vectors; cnt++, vip++) {
    943		vip->irqline = (unsigned char) cnt;
    944		vip->iosapic = isi;
    945	}
    946	isi->isi_next = iosapic_list;
    947	iosapic_list = isi;
    948	return isi;
    949}
    950
    951
    952#ifdef DEBUG_IOSAPIC
    953
    954static void
    955iosapic_prt_irt(void *irt, long num_entry)
    956{
    957	unsigned int i, *irp = (unsigned int *) irt;
    958
    959
    960	printk(KERN_DEBUG MODULE_NAME ": Interrupt Routing Table (%lx entries)\n", num_entry);
    961
    962	for (i=0; i<num_entry; i++, irp += 4) {
    963		printk(KERN_DEBUG "%p : %2d %.8x %.8x %.8x %.8x\n",
    964					irp, i, irp[0], irp[1], irp[2], irp[3]);
    965	}
    966}
    967
    968
    969static void
    970iosapic_prt_vi(struct vector_info *vi)
    971{
    972	printk(KERN_DEBUG MODULE_NAME ": vector_info[%d] is at %p\n", vi->irqline, vi);
    973	printk(KERN_DEBUG "\t\tstatus:	 %.4x\n", vi->status);
    974	printk(KERN_DEBUG "\t\ttxn_irq:  %d\n",  vi->txn_irq);
    975	printk(KERN_DEBUG "\t\ttxn_addr: %lx\n", vi->txn_addr);
    976	printk(KERN_DEBUG "\t\ttxn_data: %lx\n", vi->txn_data);
    977	printk(KERN_DEBUG "\t\teoi_addr: %p\n",  vi->eoi_addr);
    978	printk(KERN_DEBUG "\t\teoi_data: %x\n",  vi->eoi_data);
    979}
    980
    981
    982static void
    983iosapic_prt_isi(struct iosapic_info *isi)
    984{
    985	printk(KERN_DEBUG MODULE_NAME ": io_sapic_info at %p\n", isi);
    986	printk(KERN_DEBUG "\t\tisi_hpa:       %lx\n", isi->isi_hpa);
    987	printk(KERN_DEBUG "\t\tisi_status:    %x\n", isi->isi_status);
    988	printk(KERN_DEBUG "\t\tisi_version:   %x\n", isi->isi_version);
    989	printk(KERN_DEBUG "\t\tisi_vector:    %p\n", isi->isi_vector);
    990}
    991#endif /* DEBUG_IOSAPIC */