static void ixp12x0_set_intrmask(uint32_t irqs, uint32_t pci_irqs) { if (irqs & (1U << IXP12X0_INTR_UART)) { ixp12x0_disable_uart_irq(); } else { ixp12x0_enable_uart_irq(); } IXPREG(IXPPCI_IRQ_ENABLE_CLEAR) = pci_irqs; IXPREG(IXPPCI_IRQ_ENABLE_SET) = pci_intr_enabled & ~pci_irqs; }
void arm_mask_irq(uintptr_t nb) { int i; i = disable_interrupts(I32_bit); if (nb < 32) { intr_enabled &= ~(1 << nb); ixp425_set_intrmask(); } else { intr_enabled2 &= ~(1 << (nb - 32)); ixp435_set_intrmask(); } restore_interrupts(i); /*XXX; If it's a GPIO interrupt, ACK it know. Can it be a problem ?*/ if (nb < 32 && ((1 << nb) & IXP425_INT_GPIOMASK)) IXPREG(IXP425_GPIO_VBASE + IXP425_GPIO_GPISR) = ixp425_irq2gpio_bit(nb); }
static void ixp12x0_enable_irq(int irq) { if (irq < SYS_NIRQ) { intr_enabled |= (1U << irq); switch (irq) { case IXP12X0_INTR_UART: ixp12x0_enable_uart_irq(); break; case IXP12X0_INTR_PCI: /* nothing to do */ break; default: panic("enable_irq:bad IRQ %d", irq); } } else { pci_intr_enabled |= (1U << (irq - SYS_NIRQ)); IXPREG(IXPPCI_IRQ_ENABLE_SET) = (1U << (irq - SYS_NIRQ)); } }
static inline void ixp12x0_disable_irq(int irq) { if (irq < SYS_NIRQ) { intr_enabled ^= ~(1U << irq); switch (irq) { case IXP12X0_INTR_UART: ixp12x0_disable_uart_irq(); break; case IXP12X0_INTR_PCI: /* nothing to do */ break; default: /* nothing to do */ break; } } else { pci_intr_enabled &= ~(1U << (irq - SYS_NIRQ)); IXPREG(IXPPCI_IRQ_ENABLE_CLEAR) = (1U << (irq - SYS_NIRQ)); } }
/* * void cpu_reboot(int howto, char *bootstr) * * Reboots the system * * Deal with any syncing, unmounting, dumping and shutdown hooks, * then reset the CPU. */ void cpu_reboot(int howto, char *bootstr) { u_int32_t reg; #ifdef DIAGNOSTIC /* info */ printf("boot: howto=%08x curproc=%p\n", howto, curproc); #endif /* * If we are still cold then hit the air brakes * and crash to earth fast */ if (cold) { doshutdownhooks(); printf("The operating system has halted.\n"); printf("Please press any key to reboot.\n\n"); cngetc(); printf("rebooting...\n"); goto reset; } /* Disable console buffering */ /* * If RB_NOSYNC was not specified sync the discs. * Note: Unless cold is set to 1 here, syslogd will die during the * unmount. It looks like syslogd is getting woken up only to find * that it cannot page part of the binary in as the filesystem has * been unmounted. */ if (!(howto & RB_NOSYNC)) bootsync(); /* Say NO to interrupts */ splhigh(); /* Do a dump if requested. */ if ((howto & (RB_DUMP | RB_HALT)) == RB_DUMP) dumpsys(); /* Run any shutdown hooks */ doshutdownhooks(); /* Make sure IRQ's are disabled */ IRQdisable; if (howto & RB_HALT) { printf("The operating system has halted.\n"); printf("Please press any key to reboot.\n\n"); cngetc(); } printf("rebooting...\n\r"); reset: /* * Make really really sure that all interrupts are disabled, */ (void) disable_interrupts(I32_bit|F32_bit); IXPREG(IXP425_INT_ENABLE) = 0; /* * Map the boot Flash device down at physical address 0. * This is safe since NetBSD runs out of an alias of * SDRAM at 0x10000000. */ reg = EXP_CSR_READ_4(ixpsip_softc, EXP_CNFG0_OFFSET); reg |= EXP_CNFG0_MEM_MAP; EXP_CSR_WRITE_4(ixpsip_softc, EXP_CNFG0_OFFSET, reg); /* * Jump into the bootcode's reset vector * * XXX: * Redboot doesn't like the state in which we leave the PCI * ethernet card, and so fails to detect it on reboot. This * pretty much necessitates a hard reset/power cycle to be * able to download a new kernel image over ethernet. * * I suspect this is due to a bug in Redboot's i82557 driver. */ cpu_reset(); /* ...and if that didn't work, just croak. */ printf("RESET FAILED!\n"); for (;;); }
static inline uint32_t ixp12x0_pci_irq_read(void) { return IXPREG(IXPPCI_IRQ_STATUS); }
static inline uint32_t ixp12x0_irq_read(void) { return IXPREG(IXP12X0_IRQ_VBASE) & IXP12X0_INTR_MASK; }
static __inline uint32_t ixp435_irq_read(void) { return IXPREG(IXP435_INT_STATUS2) & intr_enabled2; }
void ixp4xx_write_feature_bits(uint32_t v) { IXPREG(IXP425_EXP_VBASE + EXP_FCTRL_OFFSET) = ~v; }