Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/arch/mips/mti-malta/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 6 kB image not shown  

Quelle  malta-int.c   Sprache: C

 
/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Carsten Langgaard, carstenl@mips.com
 * Copyright (C) 2000, 2001, 2004 MIPS Technologies, Inc.
 * Copyright (C) 2001 Ralf Baechle
 * Copyright (C) 2013 Imagination Technologies Ltd.
 *
 * Routines for generic manipulation of the interrupts found on the MIPS
 * Malta board. The interrupt controller is located in the South Bridge
 * a PIIX4 device with two internal 82C95 interrupt controllers.
 */

#include <linux/init.h>
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/sched.h>
#include <linux/smp.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/kernel_stat.h>
#include <linux/kernel.h>
#include <linux/random.h>

#include <asm/traps.h>
#include <asm/i8259.h>
#include <asm/irq_cpu.h>
#include <asm/irq_regs.h>
#include <asm/mips-boards/malta.h>
#include <asm/mips-boards/maltaint.h>
#include <asm/mips-cps.h>
#include <asm/gt64120.h>
#include <asm/mips-boards/generic.h>
#include <asm/mips-boards/msc01_pci.h>
#include <asm/msc01_ic.h>
#include <asm/setup.h>
#include <asm/rtlx.h>

static inline int mips_pcibios_iack(void)
{
 int irq;

 /*
 * Determine highest priority pending interrupt by performing
 * a PCI Interrupt Acknowledge cycle.
 */

 switch (mips_revision_sconid) {
 case MIPS_REVISION_SCON_SOCIT:
 case MIPS_REVISION_SCON_ROCIT:
 case MIPS_REVISION_SCON_SOCITSC:
 case MIPS_REVISION_SCON_SOCITSCP:
  MSC_READ(MSC01_PCI_IACK, irq);
  irq &= 0xff;
  break;
 case MIPS_REVISION_SCON_GT64120:
  irq = GT_READ(GT_PCI0_IACK_OFS);
  irq &= 0xff;
  break;
 case MIPS_REVISION_SCON_BONITO:
  /* The following will generate a PCI IACK cycle on the
 * Bonito controller. It's a little bit kludgy, but it
 * was the easiest way to implement it in hardware at
 * the given time.
 */

  BONITO_PCIMAP_CFG = 0x20000;

  /* Flush Bonito register block */
  (void) BONITO_PCIMAP_CFG;
  iob();   /* sync */

  irq = __raw_readl((u32 *)_pcictrl_bonito_pcicfg);
  iob();   /* sync */
  irq &= 0xff;
  BONITO_PCIMAP_CFG = 0;
  break;
 default:
  pr_emerg("Unknown system controller.\n");
  return -1;
 }
 return irq;
}

static void corehi_irqdispatch(void)
{
 unsigned int intedge, intsteer, pcicmd, pcibadaddr;
 unsigned int pcimstat, intisr, inten, intpol;
 unsigned int intrcause, datalo, datahi;
 struct pt_regs *regs = get_irq_regs();

 pr_emerg("CoreHI interrupt, shouldn't happen, we die here!\n");
 pr_emerg("epc : %08lx\nStatus: %08lx\n"
   "Cause : %08lx\nbadVaddr : %08lx\n",
   regs->cp0_epc, regs->cp0_status,
   regs->cp0_cause, regs->cp0_badvaddr);

 /* Read all the registers and then print them as there is a
   problem with interspersed printk's upsetting the Bonito controller.
   Do it for the others too.
*/


 switch (mips_revision_sconid) {
 case MIPS_REVISION_SCON_SOCIT:
 case MIPS_REVISION_SCON_ROCIT:
 case MIPS_REVISION_SCON_SOCITSC:
 case MIPS_REVISION_SCON_SOCITSCP:
  ll_msc_irq();
  break;
 case MIPS_REVISION_SCON_GT64120:
  intrcause = GT_READ(GT_INTRCAUSE_OFS);
  datalo = GT_READ(GT_CPUERR_ADDRLO_OFS);
  datahi = GT_READ(GT_CPUERR_ADDRHI_OFS);
  pr_emerg("GT_INTRCAUSE = %08x\n", intrcause);
  pr_emerg("GT_CPUERR_ADDR = %02x%08x\n",
    datahi, datalo);
  break;
 case MIPS_REVISION_SCON_BONITO:
  pcibadaddr = BONITO_PCIBADADDR;
  pcimstat = BONITO_PCIMSTAT;
  intisr = BONITO_INTISR;
  inten = BONITO_INTEN;
  intpol = BONITO_INTPOL;
  intedge = BONITO_INTEDGE;
  intsteer = BONITO_INTSTEER;
  pcicmd = BONITO_PCICMD;
  pr_emerg("BONITO_INTISR = %08x\n", intisr);
  pr_emerg("BONITO_INTEN = %08x\n", inten);
  pr_emerg("BONITO_INTPOL = %08x\n", intpol);
  pr_emerg("BONITO_INTEDGE = %08x\n", intedge);
  pr_emerg("BONITO_INTSTEER = %08x\n", intsteer);
  pr_emerg("BONITO_PCICMD = %08x\n", pcicmd);
  pr_emerg("BONITO_PCIBADADDR = %08x\n", pcibadaddr);
  pr_emerg("BONITO_PCIMSTAT = %08x\n", pcimstat);
  break;
 }

 die("CoreHi interrupt", regs);
}

static irqreturn_t corehi_handler(int irq, void *dev_id)
{
 corehi_irqdispatch();
 return IRQ_HANDLED;
}

static msc_irqmap_t msc_irqmap[] __initdata = {
 {MSC01C_INT_TMR,  MSC01_IRQ_EDGE, 0},
 {MSC01C_INT_PCI,  MSC01_IRQ_LEVEL, 0},
};
static int msc_nr_irqs __initdata = ARRAY_SIZE(msc_irqmap);

static msc_irqmap_t msc_eicirqmap[] __initdata = {
 {MSC01E_INT_SW0,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_SW1,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_I8259A,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_SMI,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_COREHI,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_CORELO,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_TMR,  MSC01_IRQ_EDGE, 0},
 {MSC01E_INT_PCI,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_PERFCTR,  MSC01_IRQ_LEVEL, 0},
 {MSC01E_INT_CPUCTR,  MSC01_IRQ_LEVEL, 0}
};

static int msc_nr_eicirqs __initdata = ARRAY_SIZE(msc_eicirqmap);

void __init arch_init_irq(void)
{
 int corehi_irq;

 /*
 * Preallocate the i8259's expected virq's here. Since irqchip_init()
 * will probe the irqchips in hierarchial order, i8259 is probed last.
 * If anything allocates a virq before the i8259 is probed, it will
 * be given one of the i8259's expected range and consequently setup
 * of the i8259 will fail.
 */

 WARN(irq_alloc_descs(I8259A_IRQ_BASE, I8259A_IRQ_BASE,
       16, numa_node_id()) < 0,
  "Cannot reserve i8259 virqs at IRQ%d\n", I8259A_IRQ_BASE);

 i8259_set_poll(mips_pcibios_iack);
 irqchip_init();

 switch (mips_revision_sconid) {
 case MIPS_REVISION_SCON_SOCIT:
 case MIPS_REVISION_SCON_ROCIT:
  if (cpu_has_veic)
   init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
     MSC01E_INT_BASE, msc_eicirqmap,
     msc_nr_eicirqs);
  else
   init_msc_irqs(MIPS_MSC01_IC_REG_BASE,
     MSC01C_INT_BASE, msc_irqmap,
     msc_nr_irqs);
  break;

 case MIPS_REVISION_SCON_SOCITSC:
 case MIPS_REVISION_SCON_SOCITSCP:
  if (cpu_has_veic)
   init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
     MSC01E_INT_BASE, msc_eicirqmap,
     msc_nr_eicirqs);
  else
   init_msc_irqs(MIPS_SOCITSC_IC_REG_BASE,
     MSC01C_INT_BASE, msc_irqmap,
     msc_nr_irqs);
 }

 if (mips_gic_present()) {
  corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
 } else if (cpu_has_veic) {
  set_vi_handler(MSC01E_INT_COREHI, corehi_irqdispatch);
  corehi_irq = MSC01E_INT_BASE + MSC01E_INT_COREHI;
 } else {
  corehi_irq = MIPS_CPU_IRQ_BASE + MIPSCPU_INT_COREHI;
 }

 if (request_irq(corehi_irq, corehi_handler, IRQF_NO_THREAD, "CoreHi",
   NULL))
  pr_err("Failed to request irq %d (CoreHi)\n", corehi_irq);
}

Messung V0.5
C=96 H=94 G=94

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.