code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_rawhide.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996 Jay A Estabrook
 *	Copyright (C) 1998, 1999 Richard Henderson
 *
 * Code supporting the RAWHIDE.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_mcpcia.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"

/*
 * HACK ALERT! only the boot cpu is used for interrupts.
 */

/* Note mask bit is true for ENABLED irqs.  */

static unsigned int hose_irq_masks[4] = {
	0xff0000, 0xfe0000, 0xff0000, 0xff0000
};
static unsigned int cached_irq_masks[4];
DEFINE_SPINLOCK(rawhide_irq_lock);

static inline void
rawhide_update_irq_hw(int hose, int mask)
{
	*(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose)) = mask;
	mb();
	*(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(hose));
}

#define hose_exists(h) \
  (((h) < MCPCIA_MAX_HOSES) && (cached_irq_masks[(h)] != 0))

static inline void
rawhide_enable_irq(struct irq_data *d)
{
	unsigned int mask, hose;
	unsigned int irq = d->irq;

	irq -= 16;
	hose = irq / 24;
	if (!hose_exists(hose)) /* if hose non-existent, exit */
		return;

	irq -= hose * 24;
	mask = 1 << irq;

	spin_lock(&rawhide_irq_lock);
	mask |= cached_irq_masks[hose];
	cached_irq_masks[hose] = mask;
	rawhide_update_irq_hw(hose, mask);
	spin_unlock(&rawhide_irq_lock);
}

static void
rawhide_disable_irq(struct irq_data *d)
{
	unsigned int mask, hose;
	unsigned int irq = d->irq;

	irq -= 16;
	hose = irq / 24;
	if (!hose_exists(hose)) /* if hose non-existent, exit */
		return;

	irq -= hose * 24;
	mask = ~(1 << irq) | hose_irq_masks[hose];

	spin_lock(&rawhide_irq_lock);
	mask &= cached_irq_masks[hose];
	cached_irq_masks[hose] = mask;
	rawhide_update_irq_hw(hose, mask);
	spin_unlock(&rawhide_irq_lock);
}

static void
rawhide_mask_and_ack_irq(struct irq_data *d)
{
	unsigned int mask, mask1, hose;
	unsigned int irq = d->irq;

	irq -= 16;
	hose = irq / 24;
	if (!hose_exists(hose)) /* if hose non-existent, exit */
		return;

	irq -= hose * 24;
	mask1 = 1 << irq;
	mask = ~mask1 | hose_irq_masks[hose];

	spin_lock(&rawhide_irq_lock);

	mask &= cached_irq_masks[hose];
	cached_irq_masks[hose] = mask;
	rawhide_update_irq_hw(hose, mask);

	/* Clear the interrupt.  */
	*(vuip)MCPCIA_INT_REQ(MCPCIA_HOSE2MID(hose)) = mask1;

	spin_unlock(&rawhide_irq_lock);
}

static struct irq_chip rawhide_irq_type = {
	.name		= "RAWHIDE",
	.irq_unmask	= rawhide_enable_irq,
	.irq_mask	= rawhide_disable_irq,
	.irq_mask_ack	= rawhide_mask_and_ack_irq,
};

static void
rawhide_srm_device_interrupt(unsigned long vector)
{
	int irq;

	irq = (vector - 0x800) >> 4;

        /*
         * The RAWHIDE SRM console reports PCI interrupts with a vector
	 * 0x80 *higher* than one might expect, as PCI IRQ 0 (ie bit 0)
	 * shows up as IRQ 24, etc, etc. We adjust it down by 8 to have
	 * it line up with the actual bit numbers from the REQ registers,
	 * which is how we manage the interrupts/mask. Sigh...
	 *
	 * Also, PCI #1 interrupts are offset some more... :-(
         */

	if (irq == 52) {
		/* SCSI on PCI1 is special.  */
		irq = 72;
	}

	/* Adjust by which hose it is from.  */
	irq -= ((irq + 16) >> 2) & 0x38;

	handle_irq(irq);
}

static void __init
rawhide_init_irq(void)
{
	struct pci_controller *hose;
	long i;

	mcpcia_init_hoses();

	/* Clear them all; only hoses that exist will be non-zero. */
	for (i = 0; i < MCPCIA_MAX_HOSES; i++) cached_irq_masks[i] = 0;

	for (hose = hose_head; hose; hose = hose->next) {
		unsigned int h = hose->index;
		unsigned int mask = hose_irq_masks[h];

		cached_irq_masks[h] = mask;
		*(vuip)MCPCIA_INT_MASK0(MCPCIA_HOSE2MID(h)) = mask;
		*(vuip)MCPCIA_INT_MASK1(MCPCIA_HOSE2MID(h)) = 0;
	}

	for (i = 16; i < 128; ++i) {
		irq_set_chip_and_handler(i, &rawhide_irq_type,
					 handle_level_irq);
		irq_set_status_flags(i, IRQ_LEVEL);
	}

	init_i8259a_irqs();
	common_init_isa_dma();
}

/*
 * PCI Fixup configuration.
 *
 * Summary @ MCPCIA_PCI0_INT_REQ:
 * Bit      Meaning
 * 0        Interrupt Line A from slot 2 PCI0
 * 1        Interrupt Line B from slot 2 PCI0
 * 2        Interrupt Line C from slot 2 PCI0
 * 3        Interrupt Line D from slot 2 PCI0
 * 4        Interrupt Line A from slot 3 PCI0
 * 5        Interrupt Line B from slot 3 PCI0
 * 6        Interrupt Line C from slot 3 PCI0
 * 7        Interrupt Line D from slot 3 PCI0
 * 8        Interrupt Line A from slot 4 PCI0
 * 9        Interrupt Line B from slot 4 PCI0
 * 10       Interrupt Line C from slot 4 PCI0
 * 11       Interrupt Line D from slot 4 PCI0
 * 12       Interrupt Line A from slot 5 PCI0
 * 13       Interrupt Line B from slot 5 PCI0
 * 14       Interrupt Line C from slot 5 PCI0
 * 15       Interrupt Line D from slot 5 PCI0
 * 16       EISA interrupt (PCI 0) or SCSI interrupt (PCI 1)
 * 17-23    NA
 *
 * IdSel
 *   1	 EISA bridge (PCI bus 0 only)
 *   2 	 PCI option slot 2
 *   3	 PCI option slot 3
 *   4   PCI option slot 4
 *   5   PCI option slot 5
 *
 */

static int
rawhide_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[5][5] = {
		/*INT    INTA   INTB   INTC   INTD */
		{ 16+16, 16+16, 16+16, 16+16, 16+16}, /* IdSel 1 SCSI PCI 1 */
		{ 16+ 0, 16+ 0, 16+ 1, 16+ 2, 16+ 3}, /* IdSel 2 slot 2 */
		{ 16+ 4, 16+ 4, 16+ 5, 16+ 6, 16+ 7}, /* IdSel 3 slot 3 */
		{ 16+ 8, 16+ 8, 16+ 9, 16+10, 16+11}, /* IdSel 4 slot 4 */
		{ 16+12, 16+12, 16+13, 16+14, 16+15}  /* IdSel 5 slot 5 */
	};
	const long min_idsel = 1, max_idsel = 5, irqs_per_slot = 5;

	struct pci_controller *hose = dev->sysdata;
	int irq = COMMON_TABLE_LOOKUP;
	if (irq >= 0)
		irq += 24 * hose->index;
	return irq;
}

/*
 * The System Vector
 */

struct alpha_machine_vector rawhide_mv __initmv = {
	.vector_name		= "Rawhide",
	DO_EV5_MMU,
	DO_DEFAULT_RTC,
	DO_MCPCIA_IO,
	.machine_check		= mcpcia_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= MCPCIA_DEFAULT_MEM_BASE,
	.pci_dac_offset		= MCPCIA_DAC_OFFSET,

	.nr_irqs		= 128,
	.device_interrupt	= rawhide_srm_device_interrupt,

	.init_arch		= mcpcia_init_arch,
	.init_irq		= rawhide_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= common_init_pci,
	.kill_arch		= NULL,
	.pci_map_irq		= rawhide_map_irq,
	.pci_swizzle		= common_swizzle,
};
ALIAS_MV(rawhide)


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_ruffian.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996 Jay A Estabrook
 *	Copyright (C) 1998, 1999, 2000 Richard Henderson
 *
 * Code supporting the RUFFIAN.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/ioport.h>
#include <linux/timex.h>
#include <linux/init.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_cia.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"

static void __init
ruffian_init_irq(void)
{
	/* Invert 6&7 for i82371 */
	*(vulp)PYXIS_INT_HILO  = 0x000000c0UL; mb();
	*(vulp)PYXIS_INT_CNFG  = 0x00002064UL; mb();	 /* all clear */

	outb(0x11,0xA0);
	outb(0x08,0xA1);
	outb(0x02,0xA1);
	outb(0x01,0xA1);
	outb(0xFF,0xA1);

	outb(0x11,0x20);
	outb(0x00,0x21);
	outb(0x04,0x21);
	outb(0x01,0x21);
	outb(0xFF,0x21);

	/* Finish writing the 82C59A PIC Operation Control Words */
	outb(0x20,0xA0);
	outb(0x20,0x20);

	init_i8259a_irqs();

	/* Not interested in the bogus interrupts (0,3,6),
	   NMI (1), HALT (2), flash (5), or 21142 (8).  */
	init_pyxis_irqs(0x16f0000);

	common_init_isa_dma();
}

#define RUFFIAN_LATCH	DIV_ROUND_CLOSEST(PIT_TICK_RATE, HZ)

static void __init
ruffian_init_rtc(void)
{
	/* Ruffian does not have the RTC connected to the CPU timer
	   interrupt.  Instead, it uses the PIT connected to IRQ 0.  */

	/* Setup interval timer.  */
	outb(0x34, 0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
	outb(RUFFIAN_LATCH & 0xff, 0x40);	/* LSB */
	outb(RUFFIAN_LATCH >> 8, 0x40);		/* MSB */

	outb(0xb6, 0x43);		/* pit counter 2: speaker */
	outb(0x31, 0x42);
	outb(0x13, 0x42);

	if (request_irq(0, rtc_timer_interrupt, 0, "timer", NULL))
		pr_err("Failed to request irq 0 (timer)\n");
}

static void
ruffian_kill_arch (int mode)
{
	cia_kill_arch(mode);
#if 0
	/* This only causes re-entry to ARCSBIOS */
	/* Perhaps this works for other PYXIS as well?  */
	*(vuip) PYXIS_RESET = 0x0000dead;
	mb();
#endif
}

/*
 *  Interrupt routing:
 *
 *		Primary bus
 *	  IdSel		INTA	INTB	INTC	INTD
 * 21052   13		  -	  -	  -	  -
 * SIO	   14		 23	  -	  -	  -
 * 21143   15		 44	  -	  -	  -
 * Slot 0  17		 43	 42	 41	 40
 *
 *		Secondary bus
 *	  IdSel		INTA	INTB	INTC	INTD
 * Slot 0   8 (18)	 19	 18	 17	 16
 * Slot 1   9 (19)	 31	 30	 29	 28
 * Slot 2  10 (20)	 27	 26	 25	 24
 * Slot 3  11 (21)	 39	 38	 37	 36
 * Slot 4  12 (22)	 35	 34	 33	 32
 * 53c875  13 (23)	 20	  -	  -	  -
 *
 */

static int
ruffian_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
        static char irq_tab[11][5] = {
	      /*INT  INTA INTB INTC INTD */
		{-1,  -1,  -1,  -1,  -1},  /* IdSel 13,  21052	     */
		{-1,  -1,  -1,  -1,  -1},  /* IdSel 14,  SIO	     */
		{44,  44,  44,  44,  44},  /* IdSel 15,  21143	     */
		{-1,  -1,  -1,  -1,  -1},  /* IdSel 16,  none	     */
		{43,  43,  42,  41,  40},  /* IdSel 17,  64-bit slot */
		/* the next 6 are actually on PCI bus 1, across the bridge */
		{19,  19,  18,  17,  16},  /* IdSel  8,  slot 0	     */
		{31,  31,  30,  29,  28},  /* IdSel  9,  slot 1	     */
		{27,  27,  26,  25,  24},  /* IdSel 10,  slot 2	     */
		{39,  39,  38,  37,  36},  /* IdSel 11,  slot 3	     */
		{35,  35,  34,  33,  32},  /* IdSel 12,  slot 4	     */
		{20,  20,  20,  20,  20},  /* IdSel 13,  53c875	     */
        };
	const long min_idsel = 13, max_idsel = 23, irqs_per_slot = 5;
	return COMMON_TABLE_LOOKUP;
}

static u8
ruffian_swizzle(struct pci_dev *dev, u8 *pinp)
{
	int slot, pin = *pinp;

	if (dev->bus->number == 0) {
		slot = PCI_SLOT(dev->devfn);
	}
	/* Check for the built-in bridge.  */
	else if (PCI_SLOT(dev->bus->self->devfn) == 13) {
		slot = PCI_SLOT(dev->devfn) + 10;
	}
	else
	{
		/* Must be a card-based bridge.  */
		do {
			if (PCI_SLOT(dev->bus->self->devfn) == 13) {
				slot = PCI_SLOT(dev->devfn) + 10;
				break;
			}
			pin = pci_swizzle_interrupt_pin(dev, pin);

			/* Move up the chain of bridges.  */
			dev = dev->bus->self;
			/* Slot of the next bridge.  */
			slot = PCI_SLOT(dev->devfn);
		} while (dev->bus->self);
	}
	*pinp = pin;
	return slot;
}

#ifdef BUILDING_FOR_MILO
/*
 * The DeskStation Ruffian motherboard firmware does not place
 * the memory size in the PALimpure area.  Therefore, we use
 * the Bank Configuration Registers in PYXIS to obtain the size.
 */
static unsigned long __init
ruffian_get_bank_size(unsigned long offset)
{
	unsigned long bank_addr, bank, ret = 0;

	/* Valid offsets are: 0x800, 0x840 and 0x880
	   since Ruffian only uses three banks.  */
	bank_addr = (unsigned long)PYXIS_MCR + offset;
	bank = *(vulp)bank_addr;

	/* Check BANK_ENABLE */
	if (bank & 0x01) {
		static unsigned long size[] __initdata = {
			0x40000000UL, /* 0x00,   1G */
			0x20000000UL, /* 0x02, 512M */
			0x10000000UL, /* 0x04, 256M */
			0x08000000UL, /* 0x06, 128M */
			0x04000000UL, /* 0x08,  64M */
			0x02000000UL, /* 0x0a,  32M */
			0x01000000UL, /* 0x0c,  16M */
			0x00800000UL, /* 0x0e,   8M */
			0x80000000UL, /* 0x10,   2G */
		};

		bank = (bank & 0x1e) >> 1;
		if (bank < ARRAY_SIZE(size))
			ret = size[bank];
	}

	return ret;
}
#endif /* BUILDING_FOR_MILO */

/*
 * The System Vector
 */

struct alpha_machine_vector ruffian_mv __initmv = {
	.vector_name		= "Ruffian",
	DO_EV5_MMU,
	DO_DEFAULT_RTC,
	DO_PYXIS_IO,
	.machine_check		= cia_machine_check,
	.max_isa_dma_address	= ALPHA_RUFFIAN_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= DEFAULT_MEM_BASE,
	.pci_dac_offset		= PYXIS_DAC_OFFSET,

	.nr_irqs		= 48,
	.device_interrupt	= pyxis_device_interrupt,

	.init_arch		= pyxis_init_arch,
	.init_irq		= ruffian_init_irq,
	.init_rtc		= ruffian_init_rtc,
	.init_pci		= cia_init_pci,
	.kill_arch		= ruffian_kill_arch,
	.pci_map_irq		= ruffian_map_irq,
	.pci_swizzle		= ruffian_swizzle,
};
ALIAS_MV(ruffian)

repo_name: angery/linux


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_rx164.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996 Jay A Estabrook
 *	Copyright (C) 1998, 1999 Richard Henderson
 *
 * Code supporting the RX164 (PCA56+POLARIS).
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_polaris.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"

/* Note mask bit is true for ENABLED irqs.  */
static unsigned long cached_irq_mask;

static inline void
rx164_update_irq_hw(unsigned long mask)
{
	volatile unsigned int *irq_mask;

	irq_mask = (void *)(POLARIS_DENSE_CONFIG_BASE + 0x74);
	*irq_mask = mask;
	mb();
	*irq_mask;
}

static inline void
rx164_enable_irq(struct irq_data *d)
{
	rx164_update_irq_hw(cached_irq_mask |= 1UL << (d->irq - 16));
}

static void
rx164_disable_irq(struct irq_data *d)
{
	rx164_update_irq_hw(cached_irq_mask &= ~(1UL << (d->irq - 16)));
}

static struct irq_chip rx164_irq_type = {
	.name		= "RX164",
	.irq_unmask	= rx164_enable_irq,
	.irq_mask	= rx164_disable_irq,
	.irq_mask_ack	= rx164_disable_irq,
};

static void
rx164_device_interrupt(unsigned long vector)
{
	unsigned long pld;
	volatile unsigned int *dirr;
	long i;

	/* Read the interrupt summary register.  On Polaris, this is
	   the DIRR register in PCI config space (offset 0x84).  */
	dirr = (void *)(POLARIS_DENSE_CONFIG_BASE + 0x84);
	pld = *dirr;

	/*
	 * Now for every possible bit set, work through them and call
	 * the appropriate interrupt handler.
	 */
	while (pld) {
		i = ffz(~pld);
		pld &= pld - 1; /* clear least bit set */
		if (i == 20) {
			isa_no_iack_sc_device_interrupt(vector);
		} else {
			handle_irq(16+i);
		}
	}
}

static void __init
rx164_init_irq(void)
{
	long i;

	rx164_update_irq_hw(0);
	for (i = 16; i < 40; ++i) {
		irq_set_chip_and_handler(i, &rx164_irq_type, handle_level_irq);
		irq_set_status_flags(i, IRQ_LEVEL);
	}

	init_i8259a_irqs();
	common_init_isa_dma();

	if (request_irq(16 + 20, no_action, 0, "isa-cascade", NULL))
		pr_err("Failed to register isa-cascade interrupt\n");
}

/*
 * The RX164 changed its interrupt routing between pass1 and pass2...
 *
 * PASS1:
 *
 *      Slot    IDSEL   INTA    INTB    INTC    INTD
 *      0       6       5       10      15      20
 *      1       7       4       9       14      19
 *      2       5       3       8       13      18
 *      3       9       2       7       12      17
 *      4       10      1       6       11      16
 *
 * PASS2:
 *      Slot    IDSEL   INTA    INTB    INTC    INTD
 *      0       5       1       7       12      17
 *      1       6       2       8       13      18
 *      2       8       3       9       14      19
 *      3       9       4       10      15      20
 *      4       10      5       11      16      6
 *
 */

/*
 * IdSel
 *   5  32 bit PCI option slot 0
 *   6  64 bit PCI option slot 1
 *   7  PCI-ISA bridge
 *   7  64 bit PCI option slot 2
 *   9  32 bit PCI option slot 3
 *  10  PCI-PCI bridge
 *
 */

static int
rx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
#if 0
	static char irq_tab_pass1[6][5] __initdata = {
	  /*INT   INTA  INTB  INTC   INTD */
	  { 16+3, 16+3, 16+8, 16+13, 16+18},      /* IdSel 5,  slot 2 */
	  { 16+5, 16+5, 16+10, 16+15, 16+20},     /* IdSel 6,  slot 0 */
	  { 16+4, 16+4, 16+9, 16+14, 16+19},      /* IdSel 7,  slot 1 */
	  { -1,     -1,    -1,    -1,   -1},      /* IdSel 8, PCI/ISA bridge */
	  { 16+2, 16+2, 16+7, 16+12, 16+17},      /* IdSel 9,  slot 3 */
	  { 16+1, 16+1, 16+6, 16+11, 16+16},      /* IdSel 10, slot 4 */
	};
#else
	static char irq_tab[6][5] = {
	  /*INT   INTA  INTB  INTC   INTD */
	  { 16+0, 16+0, 16+6, 16+11, 16+16},      /* IdSel 5,  slot 0 */
	  { 16+1, 16+1, 16+7, 16+12, 16+17},      /* IdSel 6,  slot 1 */
	  { -1,     -1,    -1,    -1,   -1},      /* IdSel 7, PCI/ISA bridge */
	  { 16+2, 16+2, 16+8, 16+13, 16+18},      /* IdSel 8,  slot 2 */
	  { 16+3, 16+3, 16+9, 16+14, 16+19},      /* IdSel 9,  slot 3 */
	  { 16+4, 16+4, 16+10, 16+15, 16+5},      /* IdSel 10, PCI-PCI */
	};
#endif
	const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5;

	/* JRP - Need to figure out how to distinguish pass1 from pass2,
	   and use the correct table.  */
	return COMMON_TABLE_LOOKUP;
}

/*
 * The System Vector
 */

struct alpha_machine_vector rx164_mv __initmv = {
	.vector_name		= "RX164",
	DO_EV5_MMU,
	DO_DEFAULT_RTC,
	DO_POLARIS_IO,
	.machine_check		= polaris_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= DEFAULT_MEM_BASE,

	.nr_irqs		= 40,
	.device_interrupt	= rx164_device_interrupt,

	.init_arch		= polaris_init_arch,
	.init_irq		= rx164_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= common_init_pci,
	.kill_arch		= NULL,
	.pci_map_irq		= rx164_map_irq,
	.pci_swizzle		= common_swizzle,
};
ALIAS_MV(rx164)


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_sable.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996 Jay A Estabrook
 *	Copyright (C) 1998, 1999 Richard Henderson
 *
 * Code supporting the Sable, Sable-Gamma, and Lynx systems.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_t2.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"

DEFINE_SPINLOCK(sable_lynx_irq_lock);

typedef struct irq_swizzle_struct
{
	char irq_to_mask[64];
	char mask_to_irq[64];

	/* Note mask bit is true for DISABLED irqs.  */
	unsigned long shadow_mask;

	void (*update_irq_hw)(unsigned long bit, unsigned long mask);
	void (*ack_irq_hw)(unsigned long bit);

} irq_swizzle_t;

static irq_swizzle_t *sable_lynx_irq_swizzle;

static void sable_lynx_init_irq(int nr_of_irqs);

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE)

/***********************************************************************/
/*
 *   For SABLE, which is really baroque, we manage 40 IRQ's, but the
 *   hardware really only supports 24, not via normal ISA PIC,
 *   but cascaded custom 8259's, etc.
 *	 0-7  (char at 536)
 *	 8-15 (char at 53a)
 *	16-23 (char at 53c)
 *
 * Summary Registers (536/53a/53c):
 *
 * Bit      Meaning               Kernel IRQ
 *------------------------------------------
 * 0        PCI slot 0			34
 * 1        NCR810 (builtin)		33
 * 2        TULIP (builtin)		32
 * 3        mouse			12
 * 4        PCI slot 1			35
 * 5        PCI slot 2			36
 * 6        keyboard			1
 * 7        floppy			6
 * 8        COM2			3
 * 9        parallel port		7
 *10        EISA irq 3			-
 *11        EISA irq 4			-
 *12        EISA irq 5			5
 *13        EISA irq 6			-
 *14        EISA irq 7			-
 *15        COM1			4
 *16        EISA irq 9			9
 *17        EISA irq 10			10
 *18        EISA irq 11			11
 *19        EISA irq 12			-
 *20        EISA irq 13			-
 *21        EISA irq 14			14
 *22        NC				15
 *23        IIC				-
 */

static void
sable_update_irq_hw(unsigned long bit, unsigned long mask)
{
	int port = 0x537;

	if (bit >= 16) {
		port = 0x53d;
		mask >>= 16;
	} else if (bit >= 8) {
		port = 0x53b;
		mask >>= 8;
	}

	outb(mask, port);
}

static void
sable_ack_irq_hw(unsigned long bit)
{
	int port, val1, val2;

	if (bit >= 16) {
		port = 0x53c;
		val1 = 0xE0 | (bit - 16);
		val2 = 0xE0 | 4;
	} else if (bit >= 8) {
		port = 0x53a;
		val1 = 0xE0 | (bit - 8);
		val2 = 0xE0 | 3;
	} else {
		port = 0x536;
		val1 = 0xE0 | (bit - 0);
		val2 = 0xE0 | 1;
	}

	outb(val1, port);	/* ack the slave */
	outb(val2, 0x534);	/* ack the master */
}

static irq_swizzle_t sable_irq_swizzle = {
	{
		-1,  6, -1,  8, 15, 12,  7,  9,	/* pseudo PIC  0-7  */
		-1, 16, 17, 18,  3, -1, 21, 22,	/* pseudo PIC  8-15 */
		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo EISA 0-7  */
		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo EISA 8-15  */
		 2,  1,  0,  4,  5, -1, -1, -1,	/* pseudo PCI */
		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
		-1, -1, -1, -1, -1, -1, -1, -1 	/*  */
	},
	{
		34, 33, 32, 12, 35, 36,  1,  6,	/* mask 0-7  */
		 3,  7, -1, -1,  5, -1, -1,  4,	/* mask 8-15  */
		 9, 10, 11, -1, -1, 14, 15, -1,	/* mask 16-23  */
		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
		-1, -1, -1, -1, -1, -1, -1, -1,	/*  */
		-1, -1, -1, -1, -1, -1, -1, -1	/*  */
	},
	-1,
	sable_update_irq_hw,
	sable_ack_irq_hw
};

static void __init
sable_init_irq(void)
{
	outb(-1, 0x537);	/* slave 0 */
	outb(-1, 0x53b);	/* slave 1 */
	outb(-1, 0x53d);	/* slave 2 */
	outb(0x44, 0x535);	/* enable cascades in master */

	sable_lynx_irq_swizzle = &sable_irq_swizzle;
	sable_lynx_init_irq(40);
}

/*
 * PCI Fixup configuration for ALPHA SABLE (2100).
 *
 * The device to slot mapping looks like:
 *
 * Slot     Device
 *  0       TULIP
 *  1       SCSI
 *  2       PCI-EISA bridge
 *  3       none
 *  4       none
 *  5       none
 *  6       PCI on board slot 0
 *  7       PCI on board slot 1
 *  8       PCI on board slot 2
 *
 *
 * This two layered interrupt approach means that we allocate IRQ 16 and
 * above for PCI interrupts.  The IRQ relates to which bit the interrupt
 * comes in on.  This makes interrupt processing much easier.
 */
/*
 * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
 * with the values in the irq swizzling tables above.
 */

static int
sable_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[9][5] = {
		/*INT    INTA   INTB   INTC   INTD */
		{ 32+0,  32+0,  32+0,  32+0,  32+0},  /* IdSel 0,  TULIP  */
		{ 32+1,  32+1,  32+1,  32+1,  32+1},  /* IdSel 1,  SCSI   */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 2,  SIO   */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 3,  none   */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 4,  none   */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 5,  none   */
		{ 32+2,  32+2,  32+2,  32+2,  32+2},  /* IdSel 6,  slot 0 */
		{ 32+3,  32+3,  32+3,  32+3,  32+3},  /* IdSel 7,  slot 1 */
		{ 32+4,  32+4,  32+4,  32+4,  32+4}   /* IdSel 8,  slot 2 */
	};
	long min_idsel = 0, max_idsel = 8, irqs_per_slot = 5;
	return COMMON_TABLE_LOOKUP;
}
#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SABLE) */

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)

/***********************************************************************/
/* LYNX hardware specifics
 */
/*
 *   For LYNX, which is also baroque, we manage 64 IRQs, via a custom IC.
 *
 * Bit      Meaning               Kernel IRQ
 *------------------------------------------
 * 0
 * 1
 * 2
 * 3        mouse			12
 * 4
 * 5
 * 6        keyboard			1
 * 7        floppy			6
 * 8        COM2			3
 * 9        parallel port		7
 *10        EISA irq 3			-
 *11        EISA irq 4			-
 *12        EISA irq 5			5
 *13        EISA irq 6			-
 *14        EISA irq 7			-
 *15        COM1			4
 *16        EISA irq 9			9
 *17        EISA irq 10			10
 *18        EISA irq 11			11
 *19        EISA irq 12			-
 *20
 *21        EISA irq 14			14
 *22        EISA irq 15			15
 *23        IIC				-
 *24        VGA (builtin)               -
 *25
 *26
 *27
 *28        NCR810 (builtin)		28
 *29
 *30
 *31
 *32        PCI 0 slot 4 A primary bus  32
 *33        PCI 0 slot 4 B primary bus  33
 *34        PCI 0 slot 4 C primary bus  34
 *35        PCI 0 slot 4 D primary bus
 *36        PCI 0 slot 5 A primary bus
 *37        PCI 0 slot 5 B primary bus
 *38        PCI 0 slot 5 C primary bus
 *39        PCI 0 slot 5 D primary bus
 *40        PCI 0 slot 6 A primary bus
 *41        PCI 0 slot 6 B primary bus
 *42        PCI 0 slot 6 C primary bus
 *43        PCI 0 slot 6 D primary bus
 *44        PCI 0 slot 7 A primary bus
 *45        PCI 0 slot 7 B primary bus
 *46        PCI 0 slot 7 C primary bus
 *47        PCI 0 slot 7 D primary bus
 *48        PCI 0 slot 0 A secondary bus
 *49        PCI 0 slot 0 B secondary bus
 *50        PCI 0 slot 0 C secondary bus
 *51        PCI 0 slot 0 D secondary bus
 *52        PCI 0 slot 1 A secondary bus
 *53        PCI 0 slot 1 B secondary bus
 *54        PCI 0 slot 1 C secondary bus
 *55        PCI 0 slot 1 D secondary bus
 *56        PCI 0 slot 2 A secondary bus
 *57        PCI 0 slot 2 B secondary bus
 *58        PCI 0 slot 2 C secondary bus
 *59        PCI 0 slot 2 D secondary bus
 *60        PCI 0 slot 3 A secondary bus
 *61        PCI 0 slot 3 B secondary bus
 *62        PCI 0 slot 3 C secondary bus
 *63        PCI 0 slot 3 D secondary bus
 */

static void
lynx_update_irq_hw(unsigned long bit, unsigned long mask)
{
	/*
	 * Write the AIR register on the T3/T4 with the
	 * address of the IC mask register (offset 0x40)
	 */
	*(vulp)T2_AIR = 0x40;
	mb();
	*(vulp)T2_AIR; /* re-read to force write */
	mb();
	*(vulp)T2_DIR = mask;
	mb();
	mb();
}

static void
lynx_ack_irq_hw(unsigned long bit)
{
	*(vulp)T2_VAR = (u_long) bit;
	mb();
	mb();
}

static irq_swizzle_t lynx_irq_swizzle = {
	{ /* irq_to_mask */
		-1,  6, -1,  8, 15, 12,  7,  9,	/* pseudo PIC  0-7  */
		-1, 16, 17, 18,  3, -1, 21, 22,	/* pseudo PIC  8-15 */
		-1, -1, -1, -1, -1, -1, -1, -1,	/* pseudo */
		-1, -1, -1, -1, 28, -1, -1, -1,	/* pseudo */
		32, 33, 34, 35, 36, 37, 38, 39,	/* mask 32-39 */
		40, 41, 42, 43, 44, 45, 46, 47,	/* mask 40-47 */
		48, 49, 50, 51, 52, 53, 54, 55,	/* mask 48-55 */
		56, 57, 58, 59, 60, 61, 62, 63	/* mask 56-63 */
	},
	{ /* mask_to_irq */
		-1, -1, -1, 12, -1, -1,  1,  6,	/* mask 0-7   */
		 3,  7, -1, -1,  5, -1, -1,  4,	/* mask 8-15  */
		 9, 10, 11, -1, -1, 14, 15, -1,	/* mask 16-23 */
		-1, -1, -1, -1, 28, -1, -1, -1,	/* mask 24-31 */
		32, 33, 34, 35, 36, 37, 38, 39,	/* mask 32-39 */
		40, 41, 42, 43, 44, 45, 46, 47,	/* mask 40-47 */
		48, 49, 50, 51, 52, 53, 54, 55,	/* mask 48-55 */
		56, 57, 58, 59, 60, 61, 62, 63	/* mask 56-63 */
	},
	-1,
	lynx_update_irq_hw,
	lynx_ack_irq_hw
};

static void __init
lynx_init_irq(void)
{
	sable_lynx_irq_swizzle = &lynx_irq_swizzle;
	sable_lynx_init_irq(64);
}

/*
 * PCI Fixup configuration for ALPHA LYNX (2100A)
 *
 * The device to slot mapping looks like:
 *
 * Slot     Device
 *  0       none
 *  1       none
 *  2       PCI-EISA bridge
 *  3       PCI-PCI bridge
 *  4       NCR 810 (Demi-Lynx only)
 *  5       none
 *  6       PCI on board slot 4
 *  7       PCI on board slot 5
 *  8       PCI on board slot 6
 *  9       PCI on board slot 7
 *
 * And behind the PPB we have:
 *
 * 11       PCI on board slot 0
 * 12       PCI on board slot 1
 * 13       PCI on board slot 2
 * 14       PCI on board slot 3
 */
/*
 * NOTE: the IRQ assignments below are arbitrary, but need to be consistent
 * with the values in the irq swizzling tables above.
 */

static int
lynx_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[19][5] = {
		/*INT    INTA   INTB   INTC   INTD */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 13,  PCEB   */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 14,  PPB    */
		{   28,    28,    28,    28,    28},  /* IdSel 15,  NCR demi */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 16,  none   */
		{   32,    32,    33,    34,    35},  /* IdSel 17,  slot 4 */
		{   36,    36,    37,    38,    39},  /* IdSel 18,  slot 5 */
		{   40,    40,    41,    42,    43},  /* IdSel 19,  slot 6 */
		{   44,    44,    45,    46,    47},  /* IdSel 20,  slot 7 */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 22,  none   */
		/* The following are actually behind the PPB. */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 16   none */
		{   28,    28,    28,    28,    28},  /* IdSel 17   NCR lynx */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 18   none */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 19   none */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 20   none */
		{   -1,    -1,    -1,    -1,    -1},  /* IdSel 21   none */
		{   48,    48,    49,    50,    51},  /* IdSel 22   slot 0 */
		{   52,    52,    53,    54,    55},  /* IdSel 23   slot 1 */
		{   56,    56,    57,    58,    59},  /* IdSel 24   slot 2 */
		{   60,    60,    61,    62,    63}   /* IdSel 25   slot 3 */
	};
	const long min_idsel = 2, max_idsel = 20, irqs_per_slot = 5;
	return COMMON_TABLE_LOOKUP;
}

static u8
lynx_swizzle(struct pci_dev *dev, u8 *pinp)
{
	int slot, pin = *pinp;

	if (dev->bus->number == 0) {
		slot = PCI_SLOT(dev->devfn);
	}
	/* Check for the built-in bridge */
	else if (PCI_SLOT(dev->bus->self->devfn) == 3) {
		slot = PCI_SLOT(dev->devfn) + 11;
	}
	else
	{
		/* Must be a card-based bridge.  */
		do {
			if (PCI_SLOT(dev->bus->self->devfn) == 3) {
				slot = PCI_SLOT(dev->devfn) + 11;
				break;
			}
			pin = pci_swizzle_interrupt_pin(dev, pin);

			/* Move up the chain of bridges.  */
			dev = dev->bus->self;
			/* Slot of the next bridge.  */
			slot = PCI_SLOT(dev->devfn);
		} while (dev->bus->self);
	}
	*pinp = pin;
	return slot;
}

#endif /* defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX) */

/***********************************************************************/
/* GENERIC irq routines */

static inline void
sable_lynx_enable_irq(struct irq_data *d)
{
	unsigned long bit, mask;

	bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];
	spin_lock(&sable_lynx_irq_lock);
	mask = sable_lynx_irq_swizzle->shadow_mask &= ~(1UL << bit);
	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
	spin_unlock(&sable_lynx_irq_lock);
#if 0
	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
	       __func__, mask, bit, irq);
#endif
}

static void
sable_lynx_disable_irq(struct irq_data *d)
{
	unsigned long bit, mask;

	bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];
	spin_lock(&sable_lynx_irq_lock);
	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
	spin_unlock(&sable_lynx_irq_lock);
#if 0
	printk("%s: mask 0x%lx bit 0x%lx irq 0x%x\n",
	       __func__, mask, bit, irq);
#endif
}

static void
sable_lynx_mask_and_ack_irq(struct irq_data *d)
{
	unsigned long bit, mask;

	bit = sable_lynx_irq_swizzle->irq_to_mask[d->irq];
	spin_lock(&sable_lynx_irq_lock);
	mask = sable_lynx_irq_swizzle->shadow_mask |= 1UL << bit;
	sable_lynx_irq_swizzle->update_irq_hw(bit, mask);
	sable_lynx_irq_swizzle->ack_irq_hw(bit);
	spin_unlock(&sable_lynx_irq_lock);
}

static struct irq_chip sable_lynx_irq_type = {
	.name		= "SABLE/LYNX",
	.irq_unmask	= sable_lynx_enable_irq,
	.irq_mask	= sable_lynx_disable_irq,
	.irq_mask_ack	= sable_lynx_mask_and_ack_irq,
};

static void
sable_lynx_srm_device_interrupt(unsigned long vector)
{
	/* Note that the vector reported by the SRM PALcode corresponds
	   to the interrupt mask bits, but we have to manage via the
	   so-called legacy IRQs for many common devices.  */

	int bit, irq;

	bit = (vector - 0x800) >> 4;
	irq = sable_lynx_irq_swizzle->mask_to_irq[bit];
#if 0
	printk("%s: vector 0x%lx bit 0x%x irq 0x%x\n",
	       __func__, vector, bit, irq);
#endif
	handle_irq(irq);
}

static void __init
sable_lynx_init_irq(int nr_of_irqs)
{
	long i;

	for (i = 0; i < nr_of_irqs; ++i) {
		irq_set_chip_and_handler(i, &sable_lynx_irq_type,
					 handle_level_irq);
		irq_set_status_flags(i, IRQ_LEVEL);
	}

	common_init_isa_dma();
}

static void __init
sable_lynx_init_pci(void)
{
	common_init_pci();
}

/*****************************************************************/
/*
 * The System Vectors
 *
 * In order that T2_HAE_ADDRESS should be a constant, we play
 * these games with GAMMA_BIAS.
 */

#if defined(CONFIG_ALPHA_GENERIC) || \
    (defined(CONFIG_ALPHA_SABLE) && !defined(CONFIG_ALPHA_GAMMA))
#undef GAMMA_BIAS
#define GAMMA_BIAS 0
struct alpha_machine_vector sable_mv __initmv = {
	.vector_name		= "Sable",
	DO_EV4_MMU,
	DO_DEFAULT_RTC,
	DO_T2_IO,
	.machine_check		= t2_machine_check,
	.max_isa_dma_address	= ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= EISA_DEFAULT_IO_BASE,
	.min_mem_address	= T2_DEFAULT_MEM_BASE,

	.nr_irqs		= 40,
	.device_interrupt	= sable_lynx_srm_device_interrupt,

	.init_arch		= t2_init_arch,
	.init_irq		= sable_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= sable_lynx_init_pci,
	.kill_arch		= t2_kill_arch,
	.pci_map_irq		= sable_map_irq,
	.pci_swizzle		= common_swizzle,

	.sys = { .t2 = {
	    .gamma_bias		= 0
	} }
};
ALIAS_MV(sable)
#endif /* GENERIC || (SABLE && !GAMMA) */

#if defined(CONFIG_ALPHA_GENERIC) || \
    (defined(CONFIG_ALPHA_SABLE) && defined(CONFIG_ALPHA_GAMMA))
#undef GAMMA_BIAS
#define GAMMA_BIAS _GAMMA_BIAS
struct alpha_machine_vector sable_gamma_mv __initmv = {
	.vector_name		= "Sable-Gamma",
	DO_EV5_MMU,
	DO_DEFAULT_RTC,
	DO_T2_IO,
	.machine_check		= t2_machine_check,
	.max_isa_dma_address	= ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= EISA_DEFAULT_IO_BASE,
	.min_mem_address	= T2_DEFAULT_MEM_BASE,

	.nr_irqs		= 40,
	.device_interrupt	= sable_lynx_srm_device_interrupt,

	.init_arch		= t2_init_arch,
	.init_irq		= sable_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= sable_lynx_init_pci,
	.kill_arch		= t2_kill_arch,
	.pci_map_irq		= sable_map_irq,
	.pci_swizzle		= common_swizzle,

	.sys = { .t2 = {
	    .gamma_bias		= _GAMMA_BIAS
	} }
};
ALIAS_MV(sable_gamma)
#endif /* GENERIC || (SABLE && GAMMA) */

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_LYNX)
#undef GAMMA_BIAS
#define GAMMA_BIAS _GAMMA_BIAS
struct alpha_machine_vector lynx_mv __initmv = {
	.vector_name		= "Lynx",
	DO_EV4_MMU,
	DO_DEFAULT_RTC,
	DO_T2_IO,
	.machine_check		= t2_machine_check,
	.max_isa_dma_address	= ALPHA_SABLE_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= EISA_DEFAULT_IO_BASE,
	.min_mem_address	= T2_DEFAULT_MEM_BASE,

	.nr_irqs		= 64,
	.device_interrupt	= sable_lynx_srm_device_interrupt,

	.init_arch		= t2_init_arch,
	.init_irq		= lynx_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= sable_lynx_init_pci,
	.kill_arch		= t2_kill_arch,
	.pci_map_irq		= lynx_map_irq,
	.pci_swizzle		= lynx_swizzle,

	.sys = { .t2 = {
	    .gamma_bias		= _GAMMA_BIAS
	} }
};
ALIAS_MV(lynx)
#endif /* GENERIC || LYNX */


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_sio.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996 Jay A Estabrook
 *	Copyright (C) 1998, 1999 Richard Henderson
 *
 * Code for all boards that route the PCI interrupts through the SIO
 * PCI/ISA bridge.  This includes Noname (AXPpci33), Multia (UDB),
 * Kenetics's Platform 2000, Avanti (AlphaStation), XL, and AlphaBook1.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/screen_info.h>

#include <asm/compiler.h>
#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_apecs.h>
#include <asm/core_lca.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"
#include "pc873xx.h"

#if defined(ALPHA_RESTORE_SRM_SETUP)
/* Save LCA configuration data as the console had it set up.  */
struct
{
	unsigned int orig_route_tab; /* for SAVE/RESTORE */
} saved_config __attribute((common));
#endif

static void __init
sio_init_irq(void)
{
	if (alpha_using_srm)
		alpha_mv.device_interrupt = srm_device_interrupt;

	init_i8259a_irqs();
	common_init_isa_dma();
}

static inline void __init
alphabook1_init_arch(void)
{
	/* The AlphaBook1 has LCD video fixed at 800x600,
	   37 rows and 100 cols. */
	screen_info.orig_y = 37;
	screen_info.orig_video_cols = 100;
	screen_info.orig_video_lines = 37;

	lca_init_arch();
}

/*
 * sio_route_tab selects irq routing in PCI/ISA bridge so that:
 *		PIRQ0 -> irq 15
 *		PIRQ1 -> irq  9
 *		PIRQ2 -> irq 10
 *		PIRQ3 -> irq 11
 *
 * This probably ought to be configurable via MILO.  For
 * example, sound boards seem to like using IRQ 9.
 *
 * This is NOT how we should do it. PIRQ0-X should have
 * their own IRQs, the way intel uses the IO-APIC IRQs.
 */

static void __init
sio_pci_route(void)
{
	unsigned int orig_route_tab;

	/* First, ALWAYS read and print the original setting. */
	pci_bus_read_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
				  &orig_route_tab);
	printk("%s: PIRQ original 0x%x new 0x%x\n", __func__,
	       orig_route_tab, alpha_mv.sys.sio.route_tab);

#if defined(ALPHA_RESTORE_SRM_SETUP)
	saved_config.orig_route_tab = orig_route_tab;
#endif

	/* Now override with desired setting. */
	pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
				   alpha_mv.sys.sio.route_tab);
}

static bool sio_pci_dev_irq_needs_level(const struct pci_dev *dev)
{
	if ((dev->class >> 16 == PCI_BASE_CLASS_BRIDGE) &&
	    (dev->class >> 8 != PCI_CLASS_BRIDGE_PCMCIA))
		return false;

	return true;
}

static unsigned int __init
sio_collect_irq_levels(void)
{
	unsigned int level_bits = 0;
	struct pci_dev *dev = NULL;

	/* Iterate through the devices, collecting IRQ levels.  */
	for_each_pci_dev(dev) {
		if (!sio_pci_dev_irq_needs_level(dev))
			continue;

		if (dev->irq)
			level_bits |= (1 << dev->irq);
	}
	return level_bits;
}

static void __sio_fixup_irq_levels(unsigned int level_bits, bool reset)
{
	unsigned int old_level_bits;

	/*
	 * Now, make all PCI interrupts level sensitive.  Notice:
	 * these registers must be accessed byte-wise.  inw()/outw()
	 * don't work.
	 *
	 * Make sure to turn off any level bits set for IRQs 9,10,11,15,
	 *  so that the only bits getting set are for devices actually found.
	 * Note that we do preserve the remainder of the bits, which we hope
	 *  will be set correctly by ARC/SRM.
	 *
	 * Note: we at least preserve any level-set bits on AlphaBook1
	 */
	old_level_bits = inb(0x4d0) | (inb(0x4d1) << 8);

	if (reset)
		old_level_bits &= 0x71ff;

	level_bits |= old_level_bits;

	outb((level_bits >> 0) & 0xff, 0x4d0);
	outb((level_bits >> 8) & 0xff, 0x4d1);
}

static inline void
sio_fixup_irq_levels(unsigned int level_bits)
{
	__sio_fixup_irq_levels(level_bits, true);
}

static inline int
noname_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	/*
	 * The Noname board has 5 PCI slots with each of the 4
	 * interrupt pins routed to different pins on the PCI/ISA
	 * bridge (PIRQ0-PIRQ3).  The table below is based on
	 * information available at:
	 *
	 *   http://ftp.digital.com/pub/DEC/axppci/ref_interrupts.txt
	 *
	 * I have no information on the Avanti interrupt routing, but
	 * the routing seems to be identical to the Noname except
	 * that the Avanti has an additional slot whose routing I'm
	 * unsure of.
	 *
	 * pirq_tab[0] is a fake entry to deal with old PCI boards
	 * that have the interrupt pin number hardwired to 0 (meaning
	 * that they use the default INTA line, if they are interrupt
	 * driven at all).
	 */
	static char irq_tab[][5] = {
		/*INT A   B   C   D */
		{ 3,  3,  3,  3,  3}, /* idsel  6 (53c810) */
		{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
		{ 2,  2, -1, -1, -1}, /* idsel  8 (Hack: slot closest ISA) */
		{-1, -1, -1, -1, -1}, /* idsel  9 (unused) */
		{-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
		{ 0,  0,  2,  1,  0}, /* idsel 11 KN25_PCI_SLOT0 */
		{ 1,  1,  0,  2,  1}, /* idsel 12 KN25_PCI_SLOT1 */
		{ 2,  2,  1,  0,  2}, /* idsel 13 KN25_PCI_SLOT2 */
		{ 0,  0,  0,  0,  0}, /* idsel 14 AS255 TULIP */
	};
	const long min_idsel = 6, max_idsel = 14, irqs_per_slot = 5;
	int irq = COMMON_TABLE_LOOKUP, tmp;
	tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);

	irq = irq >= 0 ? tmp : -1;

	/* Fixup IRQ level if an actual IRQ mapping is detected */
	if (sio_pci_dev_irq_needs_level(dev) && irq >= 0)
		__sio_fixup_irq_levels(1 << irq, false);

	return irq;
}

static inline int
p2k_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[][5] = {
		/*INT A   B   C   D */
		{ 0,  0, -1, -1, -1}, /* idsel  6 (53c810) */
		{-1, -1, -1, -1, -1}, /* idsel  7 (SIO: PCI/ISA bridge) */
		{ 1,  1,  2,  3,  0}, /* idsel  8 (slot A) */
		{ 2,  2,  3,  0,  1}, /* idsel  9 (slot B) */
		{-1, -1, -1, -1, -1}, /* idsel 10 (unused) */
		{-1, -1, -1, -1, -1}, /* idsel 11 (unused) */
		{ 3,  3, -1, -1, -1}, /* idsel 12 (CMD0646) */
	};
	const long min_idsel = 6, max_idsel = 12, irqs_per_slot = 5;
	int irq = COMMON_TABLE_LOOKUP, tmp;
	tmp = __kernel_extbl(alpha_mv.sys.sio.route_tab, irq);
	return irq >= 0 ? tmp : -1;
}

static inline void __init
noname_init_pci(void)
{
	common_init_pci();
	sio_pci_route();
	sio_fixup_irq_levels(sio_collect_irq_levels());

	if (pc873xx_probe() == -1) {
		printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n");
	} else {
		printk(KERN_INFO "Found %s Super IO chip at 0x%x\n",
			pc873xx_get_model(), pc873xx_get_base());

		/* Enabling things in the Super IO chip doesn't actually
		 * configure and enable things, the legacy drivers still
		 * need to do the actual configuration and enabling.
		 * This only unblocks them.
		 */

#if !defined(CONFIG_ALPHA_AVANTI)
		/* Don't bother on the Avanti family.
		 * None of them had on-board IDE.
		 */
		pc873xx_enable_ide();
#endif
		pc873xx_enable_epp19();
	}
}

static inline void __init
alphabook1_init_pci(void)
{
	struct pci_dev *dev;
	unsigned char orig, config;

	common_init_pci();
	sio_pci_route();

	/*
	 * On the AlphaBook1, the PCMCIA chip (Cirrus 6729)
	 * is sensitive to PCI bus bursts, so we must DISABLE
	 * burst mode for the NCR 8xx SCSI... :-(
	 *
	 * Note that the NCR810 SCSI driver must preserve the
	 * setting of the bit in order for this to work.  At the
	 * moment (2.0.29), ncr53c8xx.c does NOT do this, but
	 * 53c7,8xx.c DOES.
	 */

	dev = NULL;
	while ((dev = pci_get_device(PCI_VENDOR_ID_NCR, PCI_ANY_ID, dev))) {
		if (dev->device == PCI_DEVICE_ID_NCR_53C810
		    || dev->device == PCI_DEVICE_ID_NCR_53C815
		    || dev->device == PCI_DEVICE_ID_NCR_53C820
		    || dev->device == PCI_DEVICE_ID_NCR_53C825) {
			unsigned long io_port;
			unsigned char ctest4;

			io_port = dev->resource[0].start;
			ctest4 = inb(io_port+0x21);
			if (!(ctest4 & 0x80)) {
				printk("AlphaBook1 NCR init: setting"
				       " burst disable\n");
				outb(ctest4 | 0x80, io_port+0x21);
			}
                }
	}

	/* Do not set *ANY* level triggers for AlphaBook1. */
	sio_fixup_irq_levels(0);

	/* Make sure that register PR1 indicates 1Mb mem */
	outb(0x0f, 0x3ce); orig = inb(0x3cf);   /* read PR5  */
	outb(0x0f, 0x3ce); outb(0x05, 0x3cf);   /* unlock PR0-4 */
	outb(0x0b, 0x3ce); config = inb(0x3cf); /* read PR1 */
	if ((config & 0xc0) != 0xc0) {
		printk("AlphaBook1 VGA init: setting 1Mb memory\n");
		config |= 0xc0;
		outb(0x0b, 0x3ce); outb(config, 0x3cf); /* write PR1 */
	}
	outb(0x0f, 0x3ce); outb(orig, 0x3cf); /* (re)lock PR0-4 */
}

void
sio_kill_arch(int mode)
{
#if defined(ALPHA_RESTORE_SRM_SETUP)
	/* Since we cannot read the PCI DMA Window CSRs, we
	 * cannot restore them here.
	 *
	 * However, we CAN read the PIRQ route register, so restore it
	 * now...
	 */
 	pci_bus_write_config_dword(pci_isa_hose->bus, PCI_DEVFN(7, 0), 0x60,
				   saved_config.orig_route_tab);
#endif
}

/*
 * The System Vectors
 */

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_BOOK1)
struct alpha_machine_vector alphabook1_mv __initmv = {
	.vector_name		= "AlphaBook1",
	DO_EV4_MMU,
	DO_DEFAULT_RTC,
	DO_LCA_IO,
	.machine_check		= lca_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,

	.nr_irqs		= 16,
	.device_interrupt	= isa_device_interrupt,

	.init_arch		= alphabook1_init_arch,
	.init_irq		= sio_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= alphabook1_init_pci,
	.kill_arch		= sio_kill_arch,
	.pci_map_irq		= noname_map_irq,
	.pci_swizzle		= common_swizzle,

	.sys = { .sio = {
		/* NCR810 SCSI is 14, PCMCIA controller is 15.  */
		.route_tab	= 0x0e0f0a0a,
	}}
};
ALIAS_MV(alphabook1)
#endif

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_AVANTI)
struct alpha_machine_vector avanti_mv __initmv = {
	.vector_name		= "Avanti",
	DO_EV4_MMU,
	DO_DEFAULT_RTC,
	DO_APECS_IO,
	.machine_check		= apecs_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,

	.nr_irqs		= 16,
	.device_interrupt	= isa_device_interrupt,

	.init_arch		= apecs_init_arch,
	.init_irq		= sio_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= noname_init_pci,
	.kill_arch		= sio_kill_arch,
	.pci_map_irq		= noname_map_irq,
	.pci_swizzle		= common_swizzle,

	.sys = { .sio = {
		.route_tab	= 0x0b0a050f, /* leave 14 for IDE, 9 for SND */
	}}
};
ALIAS_MV(avanti)
#endif

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_NONAME)
struct alpha_machine_vector noname_mv __initmv = {
	.vector_name		= "Noname",
	DO_EV4_MMU,
	DO_DEFAULT_RTC,
	DO_LCA_IO,
	.machine_check		= lca_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,

	.nr_irqs		= 16,
	.device_interrupt	= srm_device_interrupt,

	.init_arch		= lca_init_arch,
	.init_irq		= sio_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= noname_init_pci,
	.kill_arch		= sio_kill_arch,
	.pci_map_irq		= noname_map_irq,
	.pci_swizzle		= common_swizzle,

	.sys = { .sio = {
		/* For UDB, the only available PCI slot must not map to IRQ 9,
		   since that's the builtin MSS sound chip. That PCI slot
		   will map to PIRQ1 (for INTA at least), so we give it IRQ 15
		   instead.

		   Unfortunately we have to do this for NONAME as well, since
		   they are co-indicated when the platform type "Noname" is
		   selected... :-(  */

		.route_tab	= 0x0b0a0f0d,
	}}
};
ALIAS_MV(noname)
#endif

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_P2K)
struct alpha_machine_vector p2k_mv __initmv = {
	.vector_name		= "Platform2000",
	DO_EV4_MMU,
	DO_DEFAULT_RTC,
	DO_LCA_IO,
	.machine_check		= lca_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= APECS_AND_LCA_DEFAULT_MEM_BASE,

	.nr_irqs		= 16,
	.device_interrupt	= srm_device_interrupt,

	.init_arch		= lca_init_arch,
	.init_irq		= sio_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= noname_init_pci,
	.kill_arch		= sio_kill_arch,
	.pci_map_irq		= p2k_map_irq,
	.pci_swizzle		= common_swizzle,

	.sys = { .sio = {
		.route_tab	= 0x0b0a090f,
	}}
};
ALIAS_MV(p2k)
#endif

#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_XL)
struct alpha_machine_vector xl_mv __initmv = {
	.vector_name		= "XL",
	DO_EV4_MMU,
	DO_DEFAULT_RTC,
	DO_APECS_IO,
	.machine_check		= apecs_machine_check,
	.max_isa_dma_address	= ALPHA_XL_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= XL_DEFAULT_MEM_BASE,

	.nr_irqs		= 16,
	.device_interrupt	= isa_device_interrupt,

	.init_arch		= apecs_init_arch,
	.init_irq		= sio_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= noname_init_pci,
	.kill_arch		= sio_kill_arch,
	.pci_map_irq		= noname_map_irq,
	.pci_swizzle		= common_swizzle,

	.sys = { .sio = {
		.route_tab	= 0x0b0a090f,
	}}
};
ALIAS_MV(xl)
#endif


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_sx164.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996 Jay A Estabrook
 *	Copyright (C) 1998, 1999, 2000 Richard Henderson
 *
 * Code supporting the SX164 (PCA56+PYXIS).
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_cia.h>
#include <asm/hwrpb.h>
#include <asm/tlbflush.h>
#include <asm/special_insns.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"

static void __init
sx164_init_irq(void)
{
	outb(0, DMA1_RESET_REG);
	outb(0, DMA2_RESET_REG);
	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
	outb(0, DMA2_MASK_REG);

	if (alpha_using_srm)
		alpha_mv.device_interrupt = srm_device_interrupt;

	init_i8259a_irqs();

	/* Not interested in the bogus interrupts (0,3,4,5,40-47),
	   NMI (1), or HALT (2).  */
	if (alpha_using_srm)
		init_srm_irqs(40, 0x3f0000);
	else
		init_pyxis_irqs(0xff00003f0000UL);

	if (request_irq(16 + 6, no_action, 0, "timer-cascade", NULL))
		pr_err("Failed to register timer-cascade interrupt\n");
}

/*
 * PCI Fixup configuration.
 *
 * Summary @ PYXIS_INT_REQ:
 * Bit      Meaning
 * 0        RSVD
 * 1        NMI
 * 2        Halt/Reset switch
 * 3        MBZ
 * 4        RAZ
 * 5        RAZ
 * 6        Interval timer (RTC)
 * 7        PCI-ISA Bridge
 * 8        Interrupt Line A from slot 3
 * 9        Interrupt Line A from slot 2
 *10        Interrupt Line A from slot 1
 *11        Interrupt Line A from slot 0
 *12        Interrupt Line B from slot 3
 *13        Interrupt Line B from slot 2
 *14        Interrupt Line B from slot 1
 *15        Interrupt line B from slot 0
 *16        Interrupt Line C from slot 3
 *17        Interrupt Line C from slot 2
 *18        Interrupt Line C from slot 1
 *19        Interrupt Line C from slot 0
 *20        Interrupt Line D from slot 3
 *21        Interrupt Line D from slot 2
 *22        Interrupt Line D from slot 1
 *23        Interrupt Line D from slot 0
 *
 * IdSel
 *   5  32 bit PCI option slot 2
 *   6  64 bit PCI option slot 0
 *   7  64 bit PCI option slot 1
 *   8  Cypress I/O
 *   9  32 bit PCI option slot 3
 */

static int
sx164_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[5][5] = {
		/*INT    INTA   INTB   INTC   INTD */
		{ 16+ 9, 16+ 9, 16+13, 16+17, 16+21}, /* IdSel 5 slot 2 J17 */
		{ 16+11, 16+11, 16+15, 16+19, 16+23}, /* IdSel 6 slot 0 J19 */
		{ 16+10, 16+10, 16+14, 16+18, 16+22}, /* IdSel 7 slot 1 J18 */
		{    -1,    -1,    -1,	  -1,    -1}, /* IdSel 8 SIO        */
		{ 16+ 8, 16+ 8, 16+12, 16+16, 16+20}  /* IdSel 9 slot 3 J15 */
	};
	const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5;
	return COMMON_TABLE_LOOKUP;
}

static void __init
sx164_init_pci(void)
{
	cia_init_pci();
	SMC669_Init(0);
}

static void __init
sx164_init_arch(void)
{
	/*
	 * OSF palcode v1.23 forgets to enable PCA56 Motion Video
	 * Instructions. Let's enable it.
	 * We have to check palcode revision because CSERVE interface
	 * is subject to change without notice. For example, it
	 * has been changed completely since v1.16 (found in MILO
	 * distribution). -ink
	 */
	struct percpu_struct *cpu = (struct percpu_struct*)
		((char*)hwrpb + hwrpb->processor_offset);

	if (amask(AMASK_MAX) != 0
	    && alpha_using_srm
	    && (cpu->pal_revision & 0xffff) <= 0x117) {
		__asm__ __volatile__(
		"lda	$16,8($31)\n"
		"call_pal 9\n"		/* Allow PALRES insns in kernel mode */
		".long  0x64000118\n\n"	/* hw_mfpr $0,icsr */
		"ldah	$16,(1<<(19-16))($31)\n"
		"or	$0,$16,$0\n"	/* set MVE bit */
		".long  0x74000118\n"	/* hw_mtpr $0,icsr */
		"lda	$16,9($31)\n"
		"call_pal 9"		/* Disable PALRES insns */
		: : : "$0", "$16");
		printk("PCA56 MVI set enabled\n");
	}

	pyxis_init_arch();
}

/*
 * The System Vector
 */

struct alpha_machine_vector sx164_mv __initmv = {
	.vector_name		= "SX164",
	DO_EV5_MMU,
	DO_DEFAULT_RTC,
	DO_PYXIS_IO,
	.machine_check		= cia_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= DEFAULT_MEM_BASE,
	.pci_dac_offset		= PYXIS_DAC_OFFSET,

	.nr_irqs		= 48,
	.device_interrupt	= pyxis_device_interrupt,

	.init_arch		= sx164_init_arch,
	.init_irq		= sx164_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= sx164_init_pci,
	.kill_arch		= cia_kill_arch,
	.pci_map_irq		= sx164_map_irq,
	.pci_swizzle		= common_swizzle,
};
ALIAS_MV(sx164)


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_takara.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996 Jay A Estabrook
 *	Copyright (C) 1998, 1999 Richard Henderson
 *
 * Code supporting the TAKARA.
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_cia.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"
#include "pc873xx.h"

/* Note mask bit is true for DISABLED irqs.  */
static unsigned long cached_irq_mask[2] = { -1, -1 };

static inline void
takara_update_irq_hw(unsigned long irq, unsigned long mask)
{
	int regaddr;

	mask = (irq >= 64 ? mask << 16 : mask >> ((irq - 16) & 0x30));
	regaddr = 0x510 + (((irq - 16) >> 2) & 0x0c);
	outl(mask & 0xffff0000UL, regaddr);
}

static inline void
takara_enable_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;
	unsigned long mask;
	mask = (cached_irq_mask[irq >= 64] &= ~(1UL << (irq & 63)));
	takara_update_irq_hw(irq, mask);
}

static void
takara_disable_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;
	unsigned long mask;
	mask = (cached_irq_mask[irq >= 64] |= 1UL << (irq & 63));
	takara_update_irq_hw(irq, mask);
}

static struct irq_chip takara_irq_type = {
	.name		= "TAKARA",
	.irq_unmask	= takara_enable_irq,
	.irq_mask	= takara_disable_irq,
	.irq_mask_ack	= takara_disable_irq,
};

static void
takara_device_interrupt(unsigned long vector)
{
	unsigned intstatus;

	/*
	 * The PALcode will have passed us vectors 0x800 or 0x810,
	 * which are fairly arbitrary values and serve only to tell
	 * us whether an interrupt has come in on IRQ0 or IRQ1. If
	 * it's IRQ1 it's a PCI interrupt; if it's IRQ0, it's
	 * probably ISA, but PCI interrupts can come through IRQ0
	 * as well if the interrupt controller isn't in accelerated
	 * mode.
	 *
	 * OTOH, the accelerator thing doesn't seem to be working
	 * overly well, so what we'll do instead is try directly
	 * examining the Master Interrupt Register to see if it's a
	 * PCI interrupt, and if _not_ then we'll pass it on to the
	 * ISA handler.
	 */

	intstatus = inw(0x500) & 15;
	if (intstatus) {
		/*
		 * This is a PCI interrupt. Check each bit and
		 * despatch an interrupt if it's set.
		 */

		if (intstatus & 8) handle_irq(16+3);
		if (intstatus & 4) handle_irq(16+2);
		if (intstatus & 2) handle_irq(16+1);
		if (intstatus & 1) handle_irq(16+0);
	} else {
		isa_device_interrupt (vector);
	}
}

static void
takara_srm_device_interrupt(unsigned long vector)
{
	int irq = (vector - 0x800) >> 4;
	handle_irq(irq);
}

static void __init
takara_init_irq(void)
{
	long i;

	init_i8259a_irqs();

	if (alpha_using_srm) {
		alpha_mv.device_interrupt = takara_srm_device_interrupt;
	} else {
		unsigned int ctlreg = inl(0x500);

		/* Return to non-accelerated mode.  */
		ctlreg &= ~0x8000;
		outl(ctlreg, 0x500);

		/* Enable the PCI interrupt register.  */
		ctlreg = 0x05107c00;
		outl(ctlreg, 0x500);
	}

	for (i = 16; i < 128; i += 16)
		takara_update_irq_hw(i, -1);

	for (i = 16; i < 128; ++i) {
		irq_set_chip_and_handler(i, &takara_irq_type,
					 handle_level_irq);
		irq_set_status_flags(i, IRQ_LEVEL);
	}

	common_init_isa_dma();
}

/*
 * The Takara has PCI devices 1, 2, and 3 configured to slots 20,
 * 19, and 18 respectively, in the default configuration. They can
 * also be jumpered to slots 8, 7, and 6 respectively, which is fun
 * because the SIO ISA bridge can also be slot 7. However, the SIO
 * doesn't explicitly generate PCI-type interrupts, so we can
 * assign it whatever the hell IRQ we like and it doesn't matter.
 */

static int
takara_map_irq_srm(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[15][5] = {
		{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */
		{ 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot  7 == device 2 */
		{ 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot  8 == device 1 */
		{   -1,   -1,   -1,   -1,   -1},   /* slot  9 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 10 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 11 == nothing */
		/* These are behind the bridges.  */
		{   12,   12,   13,   14,   15},   /* slot 12 == nothing */
		{    8,    8,    9,   19,   11},   /* slot 13 == nothing */
		{    4,    4,    5,    6,    7},   /* slot 14 == nothing */
		{    0,    0,    1,    2,    3},   /* slot 15 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 16 == nothing */
		{64+ 0, 64+0, 64+1, 64+2, 64+3},   /* slot 17= device 4 */
		{48+ 0, 48+0, 48+1, 48+2, 48+3},   /* slot 18= device 3 */
		{32+ 0, 32+0, 32+1, 32+2, 32+3},   /* slot 19= device 2 */
		{16+ 0, 16+0, 16+1, 16+2, 16+3},   /* slot 20= device 1 */
	};
	const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
        int irq = COMMON_TABLE_LOOKUP;
	if (irq >= 0 && irq < 16) {
		/* Guess that we are behind a bridge.  */
		unsigned int busslot = PCI_SLOT(dev->bus->self->devfn);
		irq += irq_tab[busslot-min_idsel][0];
	}
	return irq;
}

static int __init
takara_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[15][5] __initdata = {
		{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot  6 == device 3 */
		{ 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot  7 == device 2 */
		{ 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot  8 == device 1 */
		{   -1,   -1,   -1,   -1,   -1},   /* slot  9 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 10 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 11 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 12 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 13 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 14 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 15 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 16 == nothing */
		{   -1,   -1,   -1,   -1,   -1},   /* slot 17 == nothing */
		{ 16+3, 16+3, 16+3, 16+3, 16+3},   /* slot 18 == device 3 */
		{ 16+2, 16+2, 16+2, 16+2, 16+2},   /* slot 19 == device 2 */
		{ 16+1, 16+1, 16+1, 16+1, 16+1},   /* slot 20 == device 1 */
	};
	const long min_idsel = 6, max_idsel = 20, irqs_per_slot = 5;
	return COMMON_TABLE_LOOKUP;
}

static u8
takara_swizzle(struct pci_dev *dev, u8 *pinp)
{
	int slot = PCI_SLOT(dev->devfn);
	int pin = *pinp;
	unsigned int ctlreg = inl(0x500);
	unsigned int busslot;

	if (!dev->bus->self)
		return slot;

	busslot = PCI_SLOT(dev->bus->self->devfn);
	/* Check for built-in bridges.  */
	if (dev->bus->number != 0
	    && busslot > 16
	    && ((1<<(36-busslot)) & ctlreg)) {
		if (pin == 1)
			pin += (20 - busslot);
		else {
			printk(KERN_WARNING "takara_swizzle: can only "
			       "handle cards with INTA IRQ pin.\n");
		}
	} else {
		/* Must be a card-based bridge.  */
		printk(KERN_WARNING "takara_swizzle: cannot handle "
		       "card-bridge behind builtin bridge yet.\n");
	}

	*pinp = pin;
	return slot;
}

static void __init
takara_init_pci(void)
{
	if (alpha_using_srm)
		alpha_mv.pci_map_irq = takara_map_irq_srm;

	cia_init_pci();

	if (pc873xx_probe() == -1) {
		printk(KERN_ERR "Probing for PC873xx Super IO chip failed.\n");
	} else {
		printk(KERN_INFO "Found %s Super IO chip at 0x%x\n",
			pc873xx_get_model(), pc873xx_get_base());
		pc873xx_enable_ide();
	}
}

/*
 * The System Vector
 */

struct alpha_machine_vector takara_mv __initmv = {
	.vector_name		= "Takara",
	DO_EV5_MMU,
	DO_DEFAULT_RTC,
	DO_CIA_IO,
	.machine_check		= cia_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= CIA_DEFAULT_MEM_BASE,

	.nr_irqs		= 128,
	.device_interrupt	= takara_device_interrupt,

	.init_arch		= cia_init_arch,
	.init_irq		= takara_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= takara_init_pci,
	.kill_arch		= cia_kill_arch,
	.pci_map_irq		= takara_map_irq,
	.pci_swizzle		= takara_swizzle,
};
ALIAS_MV(takara)


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *	linux/arch/alpha/kernel/sys_titan.c
 *
 *	Copyright (C) 1995 David A Rusling
 *	Copyright (C) 1996, 1999 Jay A Estabrook
 *	Copyright (C) 1998, 1999 Richard Henderson
 *      Copyright (C) 1999, 2000 Jeff Wiedemeier
 *
 * Code supporting TITAN systems (EV6+TITAN), currently:
 *      Privateer
 *	Falcon
 *	Granite
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_titan.h>
#include <asm/hwrpb.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"
#include "err_impl.h"

/*
 * Titan generic
 */

/*
 * Titan supports up to 4 CPUs
 */
static unsigned long titan_cpu_irq_affinity[4] = { ~0UL, ~0UL, ~0UL, ~0UL };

/*
 * Mask is set (1) if enabled
 */
static unsigned long titan_cached_irq_mask;

/*
 * Need SMP-safe access to interrupt CSRs
 */
DEFINE_SPINLOCK(titan_irq_lock);

static void
titan_update_irq_hw(unsigned long mask)
{
	register titan_cchip *cchip = TITAN_cchip;
	unsigned long isa_enable = 1UL << 55;
	register int bcpu = boot_cpuid;

#ifdef CONFIG_SMP
	cpumask_t cpm;
	volatile unsigned long *dim0, *dim1, *dim2, *dim3;
	unsigned long mask0, mask1, mask2, mask3, dummy;

	cpumask_copy(&cpm, cpu_present_mask);
	mask &= ~isa_enable;
	mask0 = mask & titan_cpu_irq_affinity[0];
	mask1 = mask & titan_cpu_irq_affinity[1];
	mask2 = mask & titan_cpu_irq_affinity[2];
	mask3 = mask & titan_cpu_irq_affinity[3];

	if (bcpu == 0) mask0 |= isa_enable;
	else if (bcpu == 1) mask1 |= isa_enable;
	else if (bcpu == 2) mask2 |= isa_enable;
	else mask3 |= isa_enable;

	dim0 = &cchip->dim0.csr;
	dim1 = &cchip->dim1.csr;
	dim2 = &cchip->dim2.csr;
	dim3 = &cchip->dim3.csr;
	if (!cpumask_test_cpu(0, &cpm)) dim0 = &dummy;
	if (!cpumask_test_cpu(1, &cpm)) dim1 = &dummy;
	if (!cpumask_test_cpu(2, &cpm)) dim2 = &dummy;
	if (!cpumask_test_cpu(3, &cpm)) dim3 = &dummy;

	*dim0 = mask0;
	*dim1 = mask1;
	*dim2 = mask2;
	*dim3 = mask3;
	mb();
	*dim0;
	*dim1;
	*dim2;
	*dim3;
#else
	volatile unsigned long *dimB;
	dimB = &cchip->dim0.csr;
	if (bcpu == 1) dimB = &cchip->dim1.csr;
	else if (bcpu == 2) dimB = &cchip->dim2.csr;
	else if (bcpu == 3) dimB = &cchip->dim3.csr;

	*dimB = mask | isa_enable;
	mb();
	*dimB;
#endif
}

static inline void
titan_enable_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;
	spin_lock(&titan_irq_lock);
	titan_cached_irq_mask |= 1UL << (irq - 16);
	titan_update_irq_hw(titan_cached_irq_mask);
	spin_unlock(&titan_irq_lock);
}

static inline void
titan_disable_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;
	spin_lock(&titan_irq_lock);
	titan_cached_irq_mask &= ~(1UL << (irq - 16));
	titan_update_irq_hw(titan_cached_irq_mask);
	spin_unlock(&titan_irq_lock);
}

static void
titan_cpu_set_irq_affinity(unsigned int irq, cpumask_t affinity)
{
	int cpu;

	for (cpu = 0; cpu < 4; cpu++) {
		if (cpumask_test_cpu(cpu, &affinity))
			titan_cpu_irq_affinity[cpu] |= 1UL << irq;
		else
			titan_cpu_irq_affinity[cpu] &= ~(1UL << irq);
	}

}

static int
titan_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
		       bool force)
{
	unsigned int irq = d->irq;
	spin_lock(&titan_irq_lock);
	titan_cpu_set_irq_affinity(irq - 16, *affinity);
	titan_update_irq_hw(titan_cached_irq_mask);
	spin_unlock(&titan_irq_lock);

	return 0;
}

static void
titan_device_interrupt(unsigned long vector)
{
	printk("titan_device_interrupt: NOT IMPLEMENTED YET!!\n");
}

static void
titan_srm_device_interrupt(unsigned long vector)
{
	int irq;

	irq = (vector - 0x800) >> 4;
	handle_irq(irq);
}

static void __init
init_titan_irqs(struct irq_chip * ops, int imin, int imax)
{
	long i;
	for (i = imin; i <= imax; ++i) {
		irq_set_chip_and_handler(i, ops, handle_level_irq);
		irq_set_status_flags(i, IRQ_LEVEL);
	}
}

static struct irq_chip titan_irq_type = {
       .name			= "TITAN",
       .irq_unmask		= titan_enable_irq,
       .irq_mask		= titan_disable_irq,
       .irq_mask_ack		= titan_disable_irq,
       .irq_set_affinity	= titan_set_irq_affinity,
};

static irqreturn_t
titan_intr_nop(int irq, void *dev_id)
{
      /*
       * This is a NOP interrupt handler for the purposes of
       * event counting -- just return.
       */
       return IRQ_HANDLED;
}

static void __init
titan_init_irq(void)
{
	if (alpha_using_srm && !alpha_mv.device_interrupt)
		alpha_mv.device_interrupt = titan_srm_device_interrupt;
	if (!alpha_mv.device_interrupt)
		alpha_mv.device_interrupt = titan_device_interrupt;

	titan_update_irq_hw(0);

	init_titan_irqs(&titan_irq_type, 16, 63 + 16);
}

static void __init
titan_legacy_init_irq(void)
{
	/* init the legacy dma controller */
	outb(0, DMA1_RESET_REG);
	outb(0, DMA2_RESET_REG);
	outb(DMA_MODE_CASCADE, DMA2_MODE_REG);
	outb(0, DMA2_MASK_REG);

	/* init the legacy irq controller */
	init_i8259a_irqs();

	/* init the titan irqs */
	titan_init_irq();
}

void
titan_dispatch_irqs(u64 mask)
{
	unsigned long vector;

	/*
	 * Mask down to those interrupts which are enable on this processor
	 */
	mask &= titan_cpu_irq_affinity[smp_processor_id()];

	/*
	 * Dispatch all requested interrupts
	 */
	while (mask) {
		/* convert to SRM vector... priority is <63> -> <0> */
		vector = 63 - __kernel_ctlz(mask);
		mask &= ~(1UL << vector);	/* clear it out 	 */
		vector = 0x900 + (vector << 4);	/* convert to SRM vector */

		/* dispatch it */
		alpha_mv.device_interrupt(vector);
	}
}

/*
 * Titan Family
 */
static void __init
titan_request_irq(unsigned int irq, irq_handler_t handler,
		  unsigned long irqflags, const char *devname,
		  void *dev_id)
{
	int err;
	err = request_irq(irq, handler, irqflags, devname, dev_id);
	if (err) {
		printk("titan_request_irq for IRQ %d returned %d; ignoring\n",
		       irq, err);
	}
}

static void __init
titan_late_init(void)
{
	/*
	 * Enable the system error interrupts. These interrupts are
	 * all reported to the kernel as machine checks, so the handler
	 * is a nop so it can be called to count the individual events.
	 */
	titan_request_irq(63+16, titan_intr_nop, 0,
		    "CChip Error", NULL);
	titan_request_irq(62+16, titan_intr_nop, 0,
		    "PChip 0 H_Error", NULL);
	titan_request_irq(61+16, titan_intr_nop, 0,
		    "PChip 1 H_Error", NULL);
	titan_request_irq(60+16, titan_intr_nop, 0,
		    "PChip 0 C_Error", NULL);
	titan_request_irq(59+16, titan_intr_nop, 0,
		    "PChip 1 C_Error", NULL);

	/*
	 * Register our error handlers.
	 */
	titan_register_error_handlers();

	/*
	 * Check if the console left us any error logs.
	 */
	cdl_check_console_data_log();

}

static int
titan_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	u8 intline;
	int irq;

 	/* Get the current intline.  */
	pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &intline);
	irq = intline;

 	/* Is it explicitly routed through ISA?  */
 	if ((irq & 0xF0) == 0xE0)
 		return irq;

 	/* Offset by 16 to make room for ISA interrupts 0 - 15.  */
 	return irq + 16;
}

static void __init
titan_init_pci(void)
{
 	/*
 	 * This isn't really the right place, but there's some init
 	 * that needs to be done after everything is basically up.
 	 */
 	titan_late_init();

	/* Indicate that we trust the console to configure things properly */
	pci_set_flags(PCI_PROBE_ONLY);
	common_init_pci();
	SMC669_Init(0);
	locate_and_init_vga(NULL);
}

/*
 * Privateer
 */
static void __init
privateer_init_pci(void)
{
	/*
	 * Hook a couple of extra err interrupts that the
	 * common titan code won't.
	 */
	titan_request_irq(53+16, titan_intr_nop, 0,
		    "NMI", NULL);
	titan_request_irq(50+16, titan_intr_nop, 0,
		    "Temperature Warning", NULL);

	/*
	 * Finish with the common version.
	 */
	return titan_init_pci();
}

/*
 * The System Vectors.
 */
struct alpha_machine_vector titan_mv __initmv = {
	.vector_name		= "TITAN",
	DO_EV6_MMU,
	DO_DEFAULT_RTC,
	DO_TITAN_IO,
	.machine_check		= titan_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= DEFAULT_MEM_BASE,
	.pci_dac_offset		= TITAN_DAC_OFFSET,

	.nr_irqs		= 80,	/* 64 + 16 */
	/* device_interrupt will be filled in by titan_init_irq */

	.agp_info		= titan_agp_info,

	.init_arch		= titan_init_arch,
	.init_irq		= titan_legacy_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= titan_init_pci,

	.kill_arch		= titan_kill_arch,
	.pci_map_irq		= titan_map_irq,
	.pci_swizzle		= common_swizzle,
};
ALIAS_MV(titan)

struct alpha_machine_vector privateer_mv __initmv = {
	.vector_name		= "PRIVATEER",
	DO_EV6_MMU,
	DO_DEFAULT_RTC,
	DO_TITAN_IO,
	.machine_check		= privateer_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= DEFAULT_MEM_BASE,
	.pci_dac_offset		= TITAN_DAC_OFFSET,

	.nr_irqs		= 80,	/* 64 + 16 */
	/* device_interrupt will be filled in by titan_init_irq */

	.agp_info		= titan_agp_info,

	.init_arch		= titan_init_arch,
	.init_irq		= titan_legacy_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= privateer_init_pci,

	.kill_arch		= titan_kill_arch,
	.pci_map_irq		= titan_map_irq,
	.pci_swizzle		= common_swizzle,
};
/* No alpha_mv alias for privateer since we compile it
   in unconditionally with titan; setup_arch knows how to cope. */


code:
// SPDX-License-Identifier: GPL-2.0
/*
 *  linux/arch/alpha/kernel/sys_wildfire.c
 *
 *  Wildfire support.
 *
 *  Copyright (C) 2000 Andrea Arcangeli <andrea@suse.de> SuSE
 */

#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/bitops.h>

#include <asm/ptrace.h>
#include <asm/dma.h>
#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/io.h>
#include <asm/core_wildfire.h>
#include <asm/hwrpb.h>
#include <asm/tlbflush.h>

#include "proto.h"
#include "irq_impl.h"
#include "pci_impl.h"
#include "machvec_impl.h"

static unsigned long cached_irq_mask[WILDFIRE_NR_IRQS/(sizeof(long)*8)];

DEFINE_SPINLOCK(wildfire_irq_lock);

static int doing_init_irq_hw = 0;

static void
wildfire_update_irq_hw(unsigned int irq)
{
	int qbbno = (irq >> 8) & (WILDFIRE_MAX_QBB - 1);
	int pcano = (irq >> 6) & (WILDFIRE_PCA_PER_QBB - 1);
	wildfire_pca *pca;
	volatile unsigned long * enable0;

	if (!WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
		if (!doing_init_irq_hw) {
			printk(KERN_ERR "wildfire_update_irq_hw:"
			       " got irq %d for non-existent PCA %d"
			       " on QBB %d.\n",
			       irq, pcano, qbbno);
		}
		return;
	}

	pca = WILDFIRE_pca(qbbno, pcano);
	enable0 = (unsigned long *) &pca->pca_int[0].enable; /* ??? */

	*enable0 = cached_irq_mask[qbbno * WILDFIRE_PCA_PER_QBB + pcano];
	mb();
	*enable0;
}

static void __init
wildfire_init_irq_hw(void)
{
#if 0
	register wildfire_pca * pca = WILDFIRE_pca(0, 0);
	volatile unsigned long * enable0, * enable1, * enable2, *enable3;
	volatile unsigned long * target0, * target1, * target2, *target3;

	enable0 = (unsigned long *) &pca->pca_int[0].enable;
	enable1 = (unsigned long *) &pca->pca_int[1].enable;
	enable2 = (unsigned long *) &pca->pca_int[2].enable;
	enable3 = (unsigned long *) &pca->pca_int[3].enable;

	target0 = (unsigned long *) &pca->pca_int[0].target;
	target1 = (unsigned long *) &pca->pca_int[1].target;
	target2 = (unsigned long *) &pca->pca_int[2].target;
	target3 = (unsigned long *) &pca->pca_int[3].target;

	*enable0 = *enable1 = *enable2 = *enable3 = 0;

	*target0 = (1UL<<8) | WILDFIRE_QBB(0);
	*target1 = *target2 = *target3 = 0;

	mb();

	*enable0; *enable1; *enable2; *enable3;
	*target0; *target1; *target2; *target3;

#else
	int i;

	doing_init_irq_hw = 1;

	/* Need to update only once for every possible PCA. */
	for (i = 0; i < WILDFIRE_NR_IRQS; i+=WILDFIRE_IRQ_PER_PCA)
		wildfire_update_irq_hw(i);

	doing_init_irq_hw = 0;
#endif
}

static void
wildfire_enable_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;

	if (irq < 16)
		i8259a_enable_irq(d);

	spin_lock(&wildfire_irq_lock);
	set_bit(irq, &cached_irq_mask);
	wildfire_update_irq_hw(irq);
	spin_unlock(&wildfire_irq_lock);
}

static void
wildfire_disable_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;

	if (irq < 16)
		i8259a_disable_irq(d);

	spin_lock(&wildfire_irq_lock);
	clear_bit(irq, &cached_irq_mask);
	wildfire_update_irq_hw(irq);
	spin_unlock(&wildfire_irq_lock);
}

static void
wildfire_mask_and_ack_irq(struct irq_data *d)
{
	unsigned int irq = d->irq;

	if (irq < 16)
		i8259a_mask_and_ack_irq(d);

	spin_lock(&wildfire_irq_lock);
	clear_bit(irq, &cached_irq_mask);
	wildfire_update_irq_hw(irq);
	spin_unlock(&wildfire_irq_lock);
}

static struct irq_chip wildfire_irq_type = {
	.name		= "WILDFIRE",
	.irq_unmask	= wildfire_enable_irq,
	.irq_mask	= wildfire_disable_irq,
	.irq_mask_ack	= wildfire_mask_and_ack_irq,
};

static void __init
wildfire_init_irq_per_pca(int qbbno, int pcano)
{
	int i, irq_bias;

	irq_bias = qbbno * (WILDFIRE_PCA_PER_QBB * WILDFIRE_IRQ_PER_PCA)
		 + pcano * WILDFIRE_IRQ_PER_PCA;

#if 0
	unsigned long io_bias;

	/* Only need the following for first PCI bus per PCA. */
	io_bias = WILDFIRE_IO(qbbno, pcano<<1) - WILDFIRE_IO_BIAS;

	outb(0, DMA1_RESET_REG + io_bias);
	outb(0, DMA2_RESET_REG + io_bias);
	outb(DMA_MODE_CASCADE, DMA2_MODE_REG + io_bias);
	outb(0, DMA2_MASK_REG + io_bias);
#endif

#if 0
	/* ??? Not sure how to do this, yet... */
	init_i8259a_irqs(); /* ??? */
#endif

	for (i = 0; i < 16; ++i) {
		if (i == 2)
			continue;
		irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
					 handle_level_irq);
		irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
	}

	irq_set_chip_and_handler(36 + irq_bias, &wildfire_irq_type,
				 handle_level_irq);
	irq_set_status_flags(36 + irq_bias, IRQ_LEVEL);
	for (i = 40; i < 64; ++i) {
		irq_set_chip_and_handler(i + irq_bias, &wildfire_irq_type,
					 handle_level_irq);
		irq_set_status_flags(i + irq_bias, IRQ_LEVEL);
	}

	if (request_irq(32 + irq_bias, no_action, 0, "isa_enable", NULL))
		pr_err("Failed to register isa_enable interrupt\n");
}

static void __init
wildfire_init_irq(void)
{
	int qbbno, pcano;

#if 1
	wildfire_init_irq_hw();
	init_i8259a_irqs();
#endif

	for (qbbno = 0; qbbno < WILDFIRE_MAX_QBB; qbbno++) {
	  if (WILDFIRE_QBB_EXISTS(qbbno)) {
	    for (pcano = 0; pcano < WILDFIRE_PCA_PER_QBB; pcano++) {
	      if (WILDFIRE_PCA_EXISTS(qbbno, pcano)) {
		wildfire_init_irq_per_pca(qbbno, pcano);
	      }
	    }
	  }
	}
}

static void
wildfire_device_interrupt(unsigned long vector)
{
	int irq;

	irq = (vector - 0x800) >> 4;

	/*
	 * bits 10-8:	source QBB ID
	 * bits 7-6:	PCA
	 * bits 5-0:	irq in PCA
	 */

	handle_irq(irq);
	return;
}

/*
 * PCI Fixup configuration.
 *
 * Summary per PCA (2 PCI or HIPPI buses):
 *
 * Bit      Meaning
 * 0-15     ISA
 *
 *32        ISA summary
 *33        SMI
 *34        NMI
 *36        builtin QLogic SCSI (or slot 0 if no IO module)
 *40        Interrupt Line A from slot 2 PCI0
 *41        Interrupt Line B from slot 2 PCI0
 *42        Interrupt Line C from slot 2 PCI0
 *43        Interrupt Line D from slot 2 PCI0
 *44        Interrupt Line A from slot 3 PCI0
 *45        Interrupt Line B from slot 3 PCI0
 *46        Interrupt Line C from slot 3 PCI0
 *47        Interrupt Line D from slot 3 PCI0
 *
 *48        Interrupt Line A from slot 4 PCI1
 *49        Interrupt Line B from slot 4 PCI1
 *50        Interrupt Line C from slot 4 PCI1
 *51        Interrupt Line D from slot 4 PCI1
 *52        Interrupt Line A from slot 5 PCI1
 *53        Interrupt Line B from slot 5 PCI1
 *54        Interrupt Line C from slot 5 PCI1
 *55        Interrupt Line D from slot 5 PCI1
 *56        Interrupt Line A from slot 6 PCI1
 *57        Interrupt Line B from slot 6 PCI1
 *58        Interrupt Line C from slot 6 PCI1
 *50        Interrupt Line D from slot 6 PCI1
 *60        Interrupt Line A from slot 7 PCI1
 *61        Interrupt Line B from slot 7 PCI1
 *62        Interrupt Line C from slot 7 PCI1
 *63        Interrupt Line D from slot 7 PCI1
 *
 *
 * IdSel
 *   0	 Cypress Bridge I/O (ISA summary interrupt)
 *   1	 64 bit PCI 0 option slot 1 (SCSI QLogic builtin)
 *   2	 64 bit PCI 0 option slot 2
 *   3	 64 bit PCI 0 option slot 3
 *   4	 64 bit PCI 1 option slot 4
 *   5	 64 bit PCI 1 option slot 5
 *   6	 64 bit PCI 1 option slot 6
 *   7	 64 bit PCI 1 option slot 7
 */

static int
wildfire_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
	static char irq_tab[8][5] = {
		/*INT    INTA   INTB   INTC   INTD */
		{ -1,    -1,    -1,    -1,    -1}, /* IdSel 0 ISA Bridge */
		{ 36,    36,    36+1, 36+2, 36+3}, /* IdSel 1 SCSI builtin */
		{ 40,    40,    40+1, 40+2, 40+3}, /* IdSel 2 PCI 0 slot 2 */
		{ 44,    44,    44+1, 44+2, 44+3}, /* IdSel 3 PCI 0 slot 3 */
		{ 48,    48,    48+1, 48+2, 48+3}, /* IdSel 4 PCI 1 slot 4 */
		{ 52,    52,    52+1, 52+2, 52+3}, /* IdSel 5 PCI 1 slot 5 */
		{ 56,    56,    56+1, 56+2, 56+3}, /* IdSel 6 PCI 1 slot 6 */
		{ 60,    60,    60+1, 60+2, 60+3}, /* IdSel 7 PCI 1 slot 7 */
	};
	long min_idsel = 0, max_idsel = 7, irqs_per_slot = 5;

	struct pci_controller *hose = dev->sysdata;
	int irq = COMMON_TABLE_LOOKUP;

	if (irq > 0) {
		int qbbno = hose->index >> 3;
		int pcano = (hose->index >> 1) & 3;
		irq += (qbbno << 8) + (pcano << 6);
	}
	return irq;
}

/*
 * The System Vectors
 */

struct alpha_machine_vector wildfire_mv __initmv = {
	.vector_name		= "WILDFIRE",
	DO_EV6_MMU,
	DO_DEFAULT_RTC,
	DO_WILDFIRE_IO,
	.machine_check		= wildfire_machine_check,
	.max_isa_dma_address	= ALPHA_MAX_ISA_DMA_ADDRESS,
	.min_io_address		= DEFAULT_IO_BASE,
	.min_mem_address	= DEFAULT_MEM_BASE,

	.nr_irqs		= WILDFIRE_NR_IRQS,
	.device_interrupt	= wildfire_device_interrupt,

	.init_arch		= wildfire_init_arch,
	.init_irq		= wildfire_init_irq,
	.init_rtc		= common_init_rtc,
	.init_pci		= common_init_pci,
	.kill_arch		= wildfire_kill_arch,
	.pci_map_irq		= wildfire_map_irq,
	.pci_swizzle		= common_swizzle,
};
ALIAS_MV(wildfire)


code:
# SPDX-License-Identifier: GPL-2.0
kapi := arch/$(SRCARCH)/include/generated/asm
uapi := arch/$(SRCARCH)/include/generated/uapi/asm

$(shell mkdir -p $(uapi) $(kapi))

syscall := $(src)/syscall.tbl
syshdr := $(srctree)/scripts/syscallhdr.sh
systbl := $(srctree)/scripts/syscalltbl.sh

quiet_cmd_syshdr = SYSHDR  $@
      cmd_syshdr = $(CONFIG_SHELL) $(syshdr) --emit-nr $< $@

quiet_cmd_systbl = SYSTBL  $@
      cmd_systbl = $(CONFIG_SHELL) $(systbl) $< $@

$(uapi)/unistd_32.h: $(syscall) $(syshdr) FORCE
	$(call if_changed,syshdr)

$(kapi)/syscall_table.h: $(syscall) $(systbl) FORCE
	$(call if_changed,systbl)

uapisyshdr-y		+= unistd_32.h
kapisyshdr-y		+= syscall_table.h

uapisyshdr-y	:= $(addprefix $(uapi)/, $(uapisyshdr-y))
kapisyshdr-y	:= $(addprefix $(kapi)/, $(kapisyshdr-y))
targets		+= $(addprefix ../../../../, $(uapisyshdr-y) $(kapisyshdr-y))

PHONY += all
all: $(uapisyshdr-y) $(kapisyshdr-y)
	@:

path: arch/alpha/kernel/syscalls/Makefile


code:
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
#
# system call numbers and entry vectors for alpha
#
# The format is:
# <number> <abi> <name> <entry point>
#
# The <abi> is always "common" for this file
#
0	common	osf_syscall			alpha_syscall_zero
1	common	exit				sys_exit
2	common	fork				alpha_fork
3	common	read				sys_read
4	common	write				sys_write
5	common	osf_old_open			sys_ni_syscall
6	common	close				sys_close
7	common	osf_wait4			sys_osf_wait4
8	common	osf_old_creat			sys_ni_syscall
9	common	link				sys_link
10	common	unlink				sys_unlink
11	common	osf_execve			sys_ni_syscall
12	common	chdir				sys_chdir
13	common	fchdir				sys_fchdir
14	common	mknod				sys_mknod
15	common	chmod				sys_chmod
16	common	chown				sys_chown
17	common	brk				sys_osf_brk
18	common	osf_getfsstat			sys_ni_syscall
19	common	lseek				sys_lseek
20	common	getxpid				sys_getxpid
21	common	osf_mount			sys_osf_mount
22	common	umount2				sys_umount
23	common	setuid				sys_setuid
24	common	getxuid				sys_getxuid
25	common	exec_with_loader		sys_ni_syscall
26	common	ptrace				sys_ptrace
27	common	osf_nrecvmsg			sys_ni_syscall
28	common	osf_nsendmsg			sys_ni_syscall
29	common	osf_nrecvfrom			sys_ni_syscall
30	common	osf_naccept			sys_ni_syscall
31	common	osf_ngetpeername		sys_ni_syscall
32	common	osf_ngetsockname		sys_ni_syscall
33	common	access				sys_access
34	common	osf_chflags			sys_ni_syscall
35	common	osf_fchflags			sys_ni_syscall
36	common	sync				sys_sync
37	common	kill				sys_kill
38	common	osf_old_stat			sys_ni_syscall
39	common	setpgid				sys_setpgid
40	common	osf_old_lstat			sys_ni_syscall
41	common	dup				sys_dup
42	common	pipe				sys_alpha_pipe
43	common	osf_set_program_attributes	sys_osf_set_program_attributes
44	common	osf_profil			sys_ni_syscall
45	common	open				sys_open
46	common	osf_old_sigaction		sys_ni_syscall
47	common	getxgid				sys_getxgid
48	common	osf_sigprocmask			sys_osf_sigprocmask
49	common	osf_getlogin			sys_ni_syscall
50	common	osf_setlogin			sys_ni_syscall
51	common	acct				sys_acct
52	common	sigpending			sys_sigpending
54	common	ioctl				sys_ioctl
55	common	osf_reboot			sys_ni_syscall
56	common	osf_revoke			sys_ni_syscall
57	common	symlink				sys_symlink
58	common	readlink			sys_readlink
59	common	execve				sys_execve
60	common	umask				sys_umask
61	common	chroot				sys_chroot
62	common	osf_old_fstat			sys_ni_syscall
63	common	getpgrp				sys_getpgrp
64	common	getpagesize			sys_getpagesize
65	common	osf_mremap			sys_ni_syscall
66	common	vfork				alpha_vfork
67	common	stat				sys_newstat
68	common	lstat				sys_newlstat
69	common	osf_sbrk			sys_ni_syscall
70	common	osf_sstk			sys_ni_syscall
71	common	mmap				sys_osf_mmap
72	common	osf_old_vadvise			sys_ni_syscall
73	common	munmap				sys_munmap
74	common	mprotect			sys_mprotect
75	common	madvise				sys_madvise
76	common	vhangup				sys_vhangup
77	common	osf_kmodcall			sys_ni_syscall
78	common	osf_mincore			sys_ni_syscall
79	common	getgroups			sys_getgroups
80	common	setgroups			sys_setgroups
81	common	osf_old_getpgrp			sys_ni_syscall
82	common	setpgrp				sys_setpgid
83	common	osf_setitimer			compat_sys_setitimer
84	common	osf_old_wait			sys_ni_syscall
85	common	osf_table			sys_ni_syscall
86	common	osf_getitimer			compat_sys_getitimer
87	common	gethostname			sys_gethostname
88	common	sethostname			sys_sethostname
89	common	getdtablesize			sys_getdtablesize
90	common	dup2				sys_dup2
91	common	fstat				sys_newfstat
92	common	fcntl				sys_fcntl
93	common	osf_select			sys_osf_select
94	common	poll				sys_poll
95	common	fsync				sys_fsync
96	common	setpriority			sys_setpriority
97	common	socket				sys_socket
98	common	connect				sys_connect
99	common	accept				sys_accept
100	common	getpriority			sys_osf_getpriority
101	common	send				sys_send
102	common	recv				sys_recv
103	common	sigreturn			sys_sigreturn
104	common	bind				sys_bind
105	common	setsockopt			sys_setsockopt
106	common	listen				sys_listen
107	common	osf_plock			sys_ni_syscall
108	common	osf_old_sigvec			sys_ni_syscall
109	common	osf_old_sigblock		sys_ni_syscall
110	common	osf_old_sigsetmask		sys_ni_syscall
111	common	sigsuspend			sys_sigsuspend
112	common	osf_sigstack			sys_osf_sigstack
113	common	recvmsg				sys_recvmsg
114	common	sendmsg				sys_sendmsg
115	common	osf_old_vtrace			sys_ni_syscall
116	common	osf_gettimeofday		sys_osf_gettimeofday
117	common	osf_getrusage			sys_osf_getrusage
118	common	getsockopt			sys_getsockopt
120	common	readv				sys_readv
121	common	writev				sys_writev
122	common	osf_settimeofday		sys_osf_settimeofday
123	common	fchown				sys_fchown
124	common	fchmod				sys_fchmod
125	common	recvfrom			sys_recvfrom
126	common	setreuid			sys_setreuid
127	common	setregid			sys_setregid
128	common	rename				sys_rename
129	common	truncate			sys_truncate
130	common	ftruncate			sys_ftruncate
131	common	flock				sys_flock
132	common	setgid				sys_setgid
133	common	sendto				sys_sendto
134	common	shutdown			sys_shutdown
135	common	socketpair			sys_socketpair
136	common	mkdir				sys_mkdir
137	common	rmdir				sys_rmdir
138	common	osf_utimes			sys_osf_utimes
139	common	osf_old_sigreturn		sys_ni_syscall
140	common	osf_adjtime			sys_ni_syscall
141	common	getpeername			sys_getpeername
142	common	osf_gethostid			sys_ni_syscall
143	common	osf_sethostid			sys_ni_syscall
144	common	getrlimit			sys_getrlimit
145	common	setrlimit			sys_setrlimit
146	common	osf_old_killpg			sys_ni_syscall
147	common	setsid				sys_setsid
148	common	quotactl			sys_quotactl
149	common	osf_oldquota			sys_ni_syscall
150	common	getsockname			sys_getsockname
153	common	osf_pid_block			sys_ni_syscall
154	common	osf_pid_unblock			sys_ni_syscall
156	common	sigaction			sys_osf_sigaction
157	common	osf_sigwaitprim			sys_ni_syscall
158	common	osf_nfssvc			sys_ni_syscall
159	common	osf_getdirentries		sys_osf_getdirentries
160	common	osf_statfs			sys_osf_statfs
161	common	osf_fstatfs			sys_osf_fstatfs
163	common	osf_asynch_daemon		sys_ni_syscall
164	common	osf_getfh			sys_ni_syscall
165	common	osf_getdomainname		sys_osf_getdomainname
166	common	setdomainname			sys_setdomainname
169	common	osf_exportfs			sys_ni_syscall
181	common	osf_alt_plock			sys_ni_syscall
184	common	osf_getmnt			sys_ni_syscall
187	common	osf_alt_sigpending		sys_ni_syscall
188	common	osf_alt_setsid			sys_ni_syscall
199	common	osf_swapon			sys_swapon
200	common	msgctl				sys_old_msgctl
201	common	msgget				sys_msgget
202	common	msgrcv				sys_msgrcv
203	common	msgsnd				sys_msgsnd
204	common	semctl				sys_old_semctl
205	common	semget				sys_semget
206	common	semop				sys_semop
207	common	osf_utsname			sys_osf_utsname
208	common	lchown				sys_lchown
209	common	shmat				sys_shmat
210	common	shmctl				sys_old_shmctl
211	common	shmdt				sys_shmdt
212	common	shmget				sys_shmget
213	common	osf_mvalid			sys_ni_syscall
214	common	osf_getaddressconf		sys_ni_syscall
215	common	osf_msleep			sys_ni_syscall
216	common	osf_mwakeup			sys_ni_syscall
217	common	msync				sys_msync
218	common	osf_signal			sys_ni_syscall
219	common	osf_utc_gettime			sys_ni_syscall
220	common	osf_utc_adjtime			sys_ni_syscall
222	common	osf_security			sys_ni_syscall
223	common	osf_kloadcall			sys_ni_syscall
224	common	osf_stat			sys_osf_stat
225	common	osf_lstat			sys_osf_lstat
226	common	osf_fstat			sys_osf_fstat
227	common	osf_statfs64			sys_osf_statfs64
228	common	osf_fstatfs64			sys_osf_fstatfs64
233	common	getpgid				sys_getpgid
234	common	getsid				sys_getsid
235	common	sigaltstack			sys_sigaltstack
236	common	osf_waitid			sys_ni_syscall
237	common	osf_priocntlset			sys_ni_syscall
238	common	osf_sigsendset			sys_ni_syscall
239	common	osf_set_speculative		sys_ni_syscall
240	common	osf_msfs_syscall		sys_ni_syscall
241	common	osf_sysinfo			sys_osf_sysinfo
242	common	osf_uadmin			sys_ni_syscall
243	common	osf_fuser			sys_ni_syscall
244	common	osf_proplist_syscall		sys_osf_proplist_syscall
245	common	osf_ntp_adjtime			sys_ni_syscall
246	common	osf_ntp_gettime			sys_ni_syscall
247	common	osf_pathconf			sys_ni_syscall
248	common	osf_fpathconf			sys_ni_syscall
250	common	osf_uswitch			sys_ni_syscall
251	common	osf_usleep_thread		sys_osf_usleep_thread
252	common	osf_audcntl			sys_ni_syscall
253	common	osf_audgen			sys_ni_syscall
254	common	sysfs				sys_sysfs
255	common	osf_subsys_info			sys_ni_syscall
256	common	osf_getsysinfo			sys_osf_getsysinfo
257	common	osf_setsysinfo			sys_osf_setsysinfo
258	common	osf_afs_syscall			sys_ni_syscall
259	common	osf_swapctl			sys_ni_syscall
260	common	osf_memcntl			sys_ni_syscall
261	common	osf_fdatasync			sys_ni_syscall
300	common	bdflush				sys_ni_syscall
301	common	sethae				sys_sethae
302	common	mount				sys_mount
303	common	old_adjtimex			sys_old_adjtimex
304	common	swapoff				sys_swapoff
305	common	getdents			sys_getdents
306	common	create_module			sys_ni_syscall
307	common	init_module			sys_init_module
308	common	delete_module			sys_delete_module
309	common	get_kernel_syms			sys_ni_syscall
310	common	syslog				sys_syslog
311	common	reboot				sys_reboot
312	common	clone				alpha_clone
313	common	uselib				sys_uselib
314	common	mlock				sys_mlock
315	common	munlock				sys_munlock
316	common	mlockall			sys_mlockall
317	common	munlockall			sys_munlockall
318	common	sysinfo				sys_sysinfo
319	common	_sysctl				sys_ni_syscall
# 320 was sys_idle
321	common	oldumount			sys_oldumount
322	common	swapon				sys_swapon
323	common	times				sys_times
324	common	personality			sys_personality
325	common	setfsuid			sys_setfsuid
326	common	setfsgid			sys_setfsgid
327	common	ustat				sys_ustat
328	common	statfs				sys_statfs
329	common	fstatfs				sys_fstatfs
330	common	sched_setparam			sys_sched_setparam
331	common	sched_getparam			sys_sched_getparam
332	common	sched_setscheduler		sys_sched_setscheduler
333	common	sched_getscheduler		sys_sched_getscheduler
334	common	sched_yield			sys_sched_yield
335	common	sched_get_priority_max		sys_sched_get_priority_max
336	common	sched_get_priority_min		sys_sched_get_priority_min
337	common	sched_rr_get_interval		sys_sched_rr_get_interval
338	common	afs_syscall			sys_ni_syscall
339	common	uname				sys_newuname
340	common	nanosleep			sys_nanosleep
341	common	mremap				sys_mremap
342	common	nfsservctl			sys_ni_syscall
343	common	setresuid			sys_setresuid
344	common	getresuid			sys_getresuid
345	common	pciconfig_read			sys_pciconfig_read
346	common	pciconfig_write			sys_pciconfig_write
347	common	query_module			sys_ni_syscall
348	common	prctl				sys_prctl
349	common	pread64				sys_pread64
350	common	pwrite64			sys_pwrite64
351	common	rt_sigreturn			sys_rt_sigreturn
352	common	rt_sigaction			sys_rt_sigaction
353	common	rt_sigprocmask			sys_rt_sigprocmask
354	common	rt_sigpending			sys_rt_sigpending
355	common	rt_sigtimedwait			sys_rt_sigtimedwait
356	common	rt_sigqueueinfo			sys_rt_sigqueueinfo
357	common	rt_sigsuspend			sys_rt_sigsuspend
358	common	select				sys_select
359	common	gettimeofday			sys_gettimeofday
360	common	settimeofday			sys_settimeofday
361	common	getitimer			sys_getitimer
362	common	setitimer			sys_setitimer
363	common	utimes				sys_utimes
364	common	getrusage			sys_getrusage
365	common	wait4				sys_wait4
366	common	adjtimex			sys_adjtimex
367	common	getcwd				sys_getcwd
368	common	capget				sys_capget
369	common	capset				sys_capset
370	common	sendfile			sys_sendfile64
371	common	setresgid			sys_setresgid
372	common	getresgid			sys_getresgid
373	common	dipc				sys_ni_syscall
374	common	pivot_root			sys_pivot_root
375	common	mincore				sys_mincore
376	common	pciconfig_iobase		sys_pciconfig_iobase
377	common	getdents64			sys_getdents64
378	common	gettid				sys_gettid
379	common	readahead			sys_readahead
# 380 is unused
381	common	tkill				sys_tkill
382	common	setxattr			sys_setxattr
383	common	lsetxattr			sys_lsetxattr
384	common	fsetxattr			sys_fsetxattr
385	common	getxattr			sys_getxattr
386	common	lgetxattr			sys_lgetxattr
387	common	fgetxattr			sys_fgetxattr
388	common	listxattr			sys_listxattr
389	common	llistxattr			sys_llistxattr
390	common	flistxattr			sys_flistxattr
391	common	removexattr			sys_removexattr
392	common	lremovexattr			sys_lremovexattr
393	common	fremovexattr			sys_fremovexattr
394	common	futex				sys_futex
395	common	sched_setaffinity		sys_sched_setaffinity
396	common	sched_getaffinity		sys_sched_getaffinity
397	common	tuxcall				sys_ni_syscall
398	common	io_setup			sys_io_setup
399	common	io_destroy			sys_io_destroy
400	common	io_getevents			sys_io_getevents
401	common	io_submit			sys_io_submit
402	common	io_cancel			sys_io_cancel
405	common	exit_group			sys_exit_group
406	common	lookup_dcookie			sys_lookup_dcookie
407	common	epoll_create			sys_epoll_create
408	common	epoll_ctl			sys_epoll_ctl
409	common	epoll_wait			sys_epoll_wait
410	common	remap_file_pages		sys_remap_file_pages
411	common	set_tid_address			sys_set_tid_address
412	common	restart_syscall			sys_restart_syscall
413	common	fadvise64			sys_fadvise64
414	common	timer_create			sys_timer_create
415	common	timer_settime			sys_timer_settime
416	common	timer_gettime			sys_timer_gettime
417	common	timer_getoverrun		sys_timer_getoverrun
418	common	timer_delete			sys_timer_delete
419	common	clock_settime			sys_clock_settime
420	common	clock_gettime			sys_clock_gettime
421	common	clock_getres			sys_clock_getres
422	common	clock_nanosleep			sys_clock_nanosleep
423	common	semtimedop			sys_semtimedop
424	common	tgkill				sys_tgkill
425	common	stat64				sys_stat64
426	common	lstat64				sys_lstat64
427	common	fstat64				sys_fstat64
428	common	vserver				sys_ni_syscall
429	common	mbind				sys_ni_syscall
430	common	get_mempolicy			sys_ni_syscall
431	common	set_mempolicy			sys_ni_syscall
432	common	mq_open				sys_mq_open
433	common	mq_unlink			sys_mq_unlink
434	common	mq_timedsend			sys_mq_timedsend
435	common	mq_timedreceive			sys_mq_timedreceive
436	common	mq_notify			sys_mq_notify
437	common	mq_getsetattr			sys_mq_getsetattr
438	common	waitid				sys_waitid
439	common	add_key				sys_add_key
440	common	request_key			sys_request_key
441	common	keyctl				sys_keyctl
442	common	ioprio_set			sys_ioprio_set
443	common	ioprio_get			sys_ioprio_get
444	common	inotify_init			sys_inotify_init
445	common	inotify_add_watch		sys_inotify_add_watch
446	common	inotify_rm_watch		sys_inotify_rm_watch
447	common	fdatasync			sys_fdatasync
448	common	kexec_load			sys_kexec_load
449	common	migrate_pages			sys_migrate_pages
450	common	openat				sys_openat
451	common	mkdirat				sys_mkdirat
452	common	mknodat				sys_mknodat
453	common	fchownat			sys_fchownat
454	common	futimesat			sys_futimesat
455	common	fstatat64			sys_fstatat64
456	common	unlinkat			sys_unlinkat
457	common	renameat			sys_renameat
458	common	linkat				sys_linkat
459	common	symlinkat			sys_symlinkat
460	common	readlinkat			sys_readlinkat
461	common	fchmodat			sys_fchmodat
462	common	faccessat			sys_faccessat
463	common	pselect6			sys_pselect6
464	common	ppoll				sys_ppoll
465	common	unshare				sys_unshare
466	common	set_robust_list			sys_set_robust_list
467	common	get_robust_list			sys_get_robust_list
468	common	splice				sys_splice
469	common	sync_file_range			sys_sync_file_range
470	common	tee				sys_tee
471	common	vmsplice			sys_vmsplice
472	common	move_pages			sys_move_pages
473	common	getcpu				sys_getcpu
474	common	epoll_pwait			sys_epoll_pwait
475	common	utimensat			sys_utimensat
476	common	signalfd			sys_signalfd
477	common	timerfd				sys_ni_syscall
478	common	eventfd				sys_eventfd
479	common	recvmmsg			sys_recvmmsg
480	common	fallocate			sys_fallocate
481	common	timerfd_create			sys_timerfd_create
482	common	timerfd_settime			sys_timerfd_settime
483	common	timerfd_gettime			sys_timerfd_gettime
484	common	signalfd4			sys_signalfd4
485	common	eventfd2			sys_eventfd2
486	common	epoll_create1			sys_epoll_create1
487	common	dup3				sys_dup3
488	common	pipe2				sys_pipe2
489	common	inotify_init1			sys_inotify_init1
490	common	preadv				sys_preadv
491	common	pwritev				sys_pwritev
492	common	rt_tgsigqueueinfo		sys_rt_tgsigqueueinfo
493	common	perf_event_open			sys_perf_event_open
494	common	fanotify_init			sys_fanotify_init
495	common	fanotify_mark			sys_fanotify_mark
496	common	prlimit64			sys_prlimit64
497	common	name_to_handle_at		sys_name_to_handle_at
498	common	open_by_handle_at		sys_open_by_handle_at
499	common	clock_adjtime			sys_clock_adjtime
500	common	syncfs				sys_syncfs
501	common	setns				sys_setns
502	common	accept4				sys_accept4
503	common	sendmmsg			sys_sendmmsg
504	common	process_vm_readv		sys_process_vm_readv
505	common	process_vm_writev		sys_process_vm_writev
506	common	kcmp				sys_kcmp
507	common	finit_module			sys_finit_module
508	common	sched_setattr			sys_sched_setattr
509	common	sched_getattr			sys_sched_getattr
510	common	renameat2			sys_renameat2
511	common	getrandom			sys_getrandom
512	common	memfd_create			sys_memfd_create
513	common	execveat			sys_execveat
514	common	seccomp				sys_seccomp
515	common	bpf				sys_bpf
516	common	userfaultfd			sys_userfaultfd
517	common	membarrier			sys_membarrier
518	common	mlock2				sys_mlock2
519	common	copy_file_range			sys_copy_file_range
520	common	preadv2				sys_preadv2
521	common	pwritev2			sys_pwritev2
522	common	statx				sys_statx
523	common	io_pgetevents			sys_io_pgetevents
524	common	pkey_mprotect			sys_pkey_mprotect
525	common	pkey_alloc			sys_pkey_alloc
526	common	pkey_free			sys_pkey_free
527	common	rseq				sys_rseq
528	common	statfs64			sys_statfs64
529	common	fstatfs64			sys_fstatfs64
530	common	getegid				sys_getegid
531	common	geteuid				sys_geteuid
532	common	getppid				sys_getppid
# all other architectures have common numbers for new syscall, alpha
# is the exception.
534	common	pidfd_send_signal		sys_pidfd_send_signal
535	common	io_uring_setup			sys_io_uring_setup
536	common	io_uring_enter			sys_io_uring_enter
537	common	io_uring_register		sys_io_uring_register
538	common	open_tree			sys_open_tree
539	common	move_mount			sys_move_mount
540	common	fsopen				sys_fsopen
541	common	fsconfig			sys_fsconfig
542	common	fsmount				sys_fsmount
543	common	fspick				sys_fspick
544	common	pidfd_open			sys_pidfd_open
# 545 reserved for clone3
546	common	close_range			sys_close_range
547	common	openat2				sys_openat2
548	common	pidfd_getfd			sys_pidfd_getfd
549	common	faccessat2			sys_faccessat2
550	common	process_madvise			sys_process_madvise
551	common	epoll_pwait2			sys_epoll_pwait2
552	common	mount_setattr			sys_mount_setattr
553	common	quotactl_fd			sys_quotactl_fd
554	common	landlock_create_ruleset		sys_landlock_create_ruleset
555	common	landlock_add_rule		sys_landlock_add_rule
556	common	landlock_restrict_self		sys_landlock_restrict_self
# 557 reserved for memfd_secret
558	common	process_mrelease		sys_process_mrelease
559	common  futex_waitv                     sys_futex_waitv
560	common	set_mempolicy_home_node		sys_ni_syscall


code:
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * arch/alpha/kernel/systbls.S
 *
 * The system call table.
 */

#include <asm/unistd.h>

#define __SYSCALL(nr, entry) .quad entry
	.data
	.align 3
	.globl sys_call_table
sys_call_table:
#include <asm/syscall_table.h>