/*
* Copyright 2000, 2001
* Broadcom Corporation. All rights reserved.
*
* This software is furnished under license and may be used and copied only
* in accordance with the following terms and conditions. Subject to these
* conditions, you may download, copy, install, use, modify and distribute
* modified or unmodified copies of this software in source and/or binary
* form. No title or ownership is transferred hereby.
*
* 1) Any source code used, modified or distributed must reproduce and
* retain this copyright notice and list of conditions as they appear in
* the source file.
*
* 2) No right is granted to use any trade name, trademark, or logo of
* Broadcom Corporation. The "Broadcom Corporation" name may not be
* used to endorse or promote products derived from this software
* without the prior written permission of Broadcom Corporation.
*
* 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
* NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE
* FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE
* LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
WRITE_REG(cpu->sb1cpu_imr_base + R_IMR_INTERRUPT_MASK, cpu->sb1cpu_imr_all);
#ifdef MULTIPROCESSOR
if (sb1250_ihands[K_INT_MBOX_0].ih_fun == NULL) {
/*
* For now, deliver all IPIs at IPL_SCHED. Eventually
* some will be at IPL_VM.
*/
for (int irq = K_INT_MBOX_0; irq <= K_INT_MBOX_3; irq++)
sb1250_intr_establish(irq, IPL_SCHED,
sb1250_ipi_intr, NULL);
}
#endif /* MULTIPROCESSOR */
}
#ifdef MULTIPROCESSOR
/*
* Bits 27:24 (11:8 of G_SYS_PART) encode the number of CPUs present.
*/
u_int sys_part = G_SYS_PART(READ_REG(MIPS_PHYS_TO_KSEG1(A_SCD_SYSTEM_REVISION)));
const u_int cpus = (sys_part >> 8) & 0xf;
/*
* Allocate an evcnt structure for every possible interrupt on
* every possible CPU.
*/
vaddr_t imr = MIPS_PHYS_TO_KSEG1(A_IMR_CPU0_BASE + R_IMR_INTERRUPT_MASK);
for (u_int i = 1; imr += IMR_REGISTER_SPACING, i < cpus; i++) {
WRITE_REG(imr, imr_all);
}
#endif /* MULTIPROCESSOR */
WRITE_REG(MIPS_PHYS_TO_KSEG1(A_IMR_CPU0_BASE + R_IMR_INTERRUPT_MASK),
imr_all);
static void *
sb1250_intr_establish(u_int num, u_int ipl,
void (*fun)(void *, uint32_t, vaddr_t), void *arg)
{
struct cpu_softc * const cpu = curcpu()->ci_softc;
struct sb1250_ihand * const ih = &sb1250_ihands[num];
const int s = splhigh();
/*
* XXX simonb
* The swarm wedges hard on first serial interrupt when
* we try to map IPL_SERIAL at a higher priority than
* other device interrupts. For now, just force all
* devices to interrupt at IPL_VM.
*
*/
ipl = IPL_VM; /* XXX */
if (num >= K_INT_SOURCES)
panic("%s: invalid interrupt number (0x%x)", __func__, num);
if (ipl >= _IPL_N || ipl < IPL_VM)
panic("%s: invalid ipl %d", __func__, ipl);
if (ih->ih_fun != NULL)
panic("%s: cannot share sb1250 interrupts", __func__);