From a8193053ece43667030c4e6e51e033cbe0967d4c Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Tue, 7 Feb 2006 02:42:38 +0000 Subject: [PATCH] Added driver for Open PIC compatible interrupt controllers (ported from FreeBSD). At the moment it only recognizes Apple's Intrepid Mac I/O Controller. Not sure how well it works yet. Enabling all I/O interrupts definitely triggers one, but I don't seem to get rid of it afterwards. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16270 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- build/jam/HaikuImage | 8 +- src/add-ons/kernel/Jamfile | 1 + .../kernel/interrupt_controllers/Jamfile | 3 + .../interrupt_controllers/openpic/Jamfile | 6 + .../interrupt_controllers/openpic/openpic.cpp | 535 ++++++++++++++++++ .../interrupt_controllers/openpic/openpic.h | 111 ++++ 6 files changed, 662 insertions(+), 2 deletions(-) create mode 100644 src/add-ons/kernel/interrupt_controllers/Jamfile create mode 100644 src/add-ons/kernel/interrupt_controllers/openpic/Jamfile create mode 100644 src/add-ons/kernel/interrupt_controllers/openpic/openpic.cpp create mode 100644 src/add-ons/kernel/interrupt_controllers/openpic/openpic.h diff --git a/build/jam/HaikuImage b/build/jam/HaikuImage index a1584b1e0f..66681a4e80 100644 --- a/build/jam/HaikuImage +++ b/build/jam/HaikuImage @@ -6,8 +6,10 @@ AddDirectoryToHaikuImage var tmp ; if $(TARGET_ARCH) = x86 { X86_ONLY = "" ; + PPC_ONLY = ; } else if $(TARGET_ARCH) = ppc { X86_ONLY = ; + PPC_ONLY = "" ; } BEOS_BIN = addattr alert arp basename beep cat catattr chgrp chmod chop chown clear @@ -84,6 +86,8 @@ AddFilesToHaikuImage beos system add-ons kernel file_systems : bfs ; AddFilesToHaikuImage beos system add-ons kernel generic : block_io fast_log ide_adapter locked_pool scsi_periph ; AddFilesToHaikuImage beos system add-ons kernel partitioning_systems : intel ; +AddFilesToHaikuImage beos system add-ons kernel interrupt_controllers + : $(PPC_ONLY)openpic ; if $(TARGET_ARCH) = x86 { AddFilesToHaikuImage beos system add-ons kernel cpu : generic_x86 ; @@ -186,8 +190,8 @@ AddFilesToHaikuImage beos system : zbeos ; # boot module links AddBootModuleSymlinks config_manager bfs block_io fast_log generic_ide_pci - $(X86_ONLY)isa ide ide_adapter $(X86_ONLY)ide_isa intel locked_pool pci scsi - scsi_cd scsi_dsk scsi_periph + $(X86_ONLY)isa ide ide_adapter $(X86_ONLY)ide_isa intel locked_pool + $(PPC_ONLY)openpic pci scsi scsi_cd scsi_dsk scsi_periph ; # add-ons diff --git a/src/add-ons/kernel/Jamfile b/src/add-ons/kernel/Jamfile index 34697bd760..009aa7be9d 100644 --- a/src/add-ons/kernel/Jamfile +++ b/src/add-ons/kernel/Jamfile @@ -8,6 +8,7 @@ SubInclude HAIKU_TOP src add-ons kernel disk_scanner ; SubInclude HAIKU_TOP src add-ons kernel drivers ; SubInclude HAIKU_TOP src add-ons kernel file_cache ; SubInclude HAIKU_TOP src add-ons kernel file_systems ; +SubInclude HAIKU_TOP src add-ons kernel interrupt_controllers ; SubInclude HAIKU_TOP src add-ons kernel network ; SubInclude HAIKU_TOP src add-ons kernel media ; SubInclude HAIKU_TOP src add-ons kernel partitioning_systems ; diff --git a/src/add-ons/kernel/interrupt_controllers/Jamfile b/src/add-ons/kernel/interrupt_controllers/Jamfile new file mode 100644 index 0000000000..839abe35b0 --- /dev/null +++ b/src/add-ons/kernel/interrupt_controllers/Jamfile @@ -0,0 +1,3 @@ +SubDir HAIKU_TOP src add-ons kernel interrupt_controllers ; + +SubInclude HAIKU_TOP src add-ons kernel interrupt_controllers openpic ; diff --git a/src/add-ons/kernel/interrupt_controllers/openpic/Jamfile b/src/add-ons/kernel/interrupt_controllers/openpic/Jamfile new file mode 100644 index 0000000000..1353f7b3b0 --- /dev/null +++ b/src/add-ons/kernel/interrupt_controllers/openpic/Jamfile @@ -0,0 +1,6 @@ +SubDir HAIKU_TOP src add-ons kernel interrupt_controllers openpic ; + +UsePrivateHeaders kernel ; +UsePrivateHeaders shared ; + +KernelAddon openpic : kernel interrupt_controllers : openpic.cpp ; diff --git a/src/add-ons/kernel/interrupt_controllers/openpic/openpic.cpp b/src/add-ons/kernel/interrupt_controllers/openpic/openpic.cpp new file mode 100644 index 0000000000..b86a8980fc --- /dev/null +++ b/src/add-ons/kernel/interrupt_controllers/openpic/openpic.cpp @@ -0,0 +1,535 @@ +/* + * Copyright 2006, Ingo Weinhold . + * All rights reserved. Distributed under the terms of the MIT License. + */ +/*- + * Copyright (C) 2002 Benno Rice. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY 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) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include "openpic.h" + + +#define OPENPIC_MODULE_NAME "interrupt_controllers/openpic/device_v1" + +enum { + OPENPIC_MIN_REGISTER_SPACE_SIZE = 0x21000, + OPENPIC_MAX_REGISTER_SPACE_SIZE = 0x40000, +}; + +struct openpic_supported_device { + const char *name; + uint16 vendor_id; + uint16 device_id; + uint32 register_offset; +}; + +static openpic_supported_device sSupportedDevices[] = { + { "Intrepid I/O Controller", 0x106b, 0x003e, 0x40000 }, + {} +}; + +static device_manager_info *sDeviceManager; +static pci_module_info *sPCIBusManager; + +struct openpic_info : interrupt_controller_info { + openpic_info() + { + memset(this, 0, sizeof(openpic_info)); + register_area = -1; + } + + ~openpic_info() + { + // unmap registers) + if (register_area >= 0) + delete_area(register_area); + + // uninit parent node driver + if (pci) + sDeviceManager->uninit_driver(sDeviceManager->get_parent(node)); + } + + openpic_supported_device *supported_device; + device_node_handle node; + pci_device_module_info *pci; + pci_device device; + + addr_t physical_registers; // physical registers base + addr_t virtual_registers; // virtual (mapped) + // registers base + area_id register_area; // register area + size_t register_space_size; +}; + + +static openpic_supported_device * +openpic_check_supported_device(uint16 vendorID, uint16 deviceID) +{ + for (openpic_supported_device *supportedDevice = sSupportedDevices; + supportedDevice->name; + supportedDevice++) { + if (supportedDevice->vendor_id == vendorID + && supportedDevice->device_id == deviceID) { + return supportedDevice; + } + } + + return NULL; +} + + +static uint32 +openpic_read(openpic_info *info, int reg) +{ + return B_SWAP_INT32(info->pci->read_io_32(info->device, + info->virtual_registers + reg)); +} + + +static void +openpic_write(openpic_info *info, int reg, uint32 val) +{ + info->pci->write_io_32(info->device, info->virtual_registers + reg, + B_SWAP_INT32(val)); +} + + +static int +openpic_read_irq(openpic_info *info, int cpu) +{ + return openpic_read(info, OPENPIC_IACK(cpu)) & OPENPIC_VECTOR_MASK; +} + + +static void +openpic_eoi(openpic_info *info, int cpu) +{ + openpic_write(info, OPENPIC_EOI(cpu), 0); +// the Linux driver does this: +//openpic_read(info, OPENPIC_EOI(cpu)); +} + + +static void +openpic_enable_irq(openpic_info *info, int irq, int type) +{ +// TODO: Align this code with the sequence recommended in the Open PIC +// Specification (v 1.2 section 5.2.2). + uint32 x; + + x = openpic_read(info, OPENPIC_SRC_VECTOR(irq)); + x &= ~(OPENPIC_IMASK | OPENPIC_SENSE_LEVEL | OPENPIC_SENSE_EDGE); + if (type == IRQ_TYPE_LEVEL) + x |= OPENPIC_SENSE_LEVEL; + else + x |= OPENPIC_SENSE_EDGE; + openpic_write(info, OPENPIC_SRC_VECTOR(irq), x); +} + + +static void +openpic_disable_irq(openpic_info *info, int irq) +{ + uint32 x; + + x = openpic_read(info, OPENPIC_SRC_VECTOR(irq)); + x |= OPENPIC_IMASK; + openpic_write(info, OPENPIC_SRC_VECTOR(irq), x); +} + + +static void +openpic_set_priority(openpic_info *info, int cpu, int pri) +{ + uint32 x; + + x = openpic_read(info, OPENPIC_CPU_PRIORITY(cpu)); + x &= ~OPENPIC_CPU_PRIORITY_MASK; + x |= pri; + openpic_write(info, OPENPIC_CPU_PRIORITY(cpu), x); +} + + +static status_t +openpic_init(openpic_info *info) +{ + uint32 x = openpic_read(info, OPENPIC_FEATURE); + const char *featureVersion; + char versionBuffer[64]; + switch (x & OPENPIC_FEATURE_VERSION_MASK) { + case 1: + featureVersion = "1.0"; + break; + case 2: + featureVersion = "1.2"; + break; + case 3: + featureVersion = "1.3"; + break; + default: + snprintf(versionBuffer, sizeof(versionBuffer), + "unknown (feature reg: 0x%lx)", x); + featureVersion = versionBuffer; + break; + } + + info->cpu_count = ((x & OPENPIC_FEATURE_LAST_CPU_MASK) >> + OPENPIC_FEATURE_LAST_CPU_SHIFT) + 1; + info->irq_count = ((x & OPENPIC_FEATURE_LAST_IRQ_MASK) >> + OPENPIC_FEATURE_LAST_IRQ_SHIFT) + 1; + + /* + * PSIM seems to report 1 too many IRQs + */ +// if (sc->sc_psim) +// sc->sc_nirq--; + + dprintf("openpic: Version %s, supports %d CPUs and %d irqs\n", + featureVersion, info->cpu_count, info->irq_count); + + /* disable all interrupts */ + for (int irq = 0; irq < info->irq_count; irq++) + openpic_write(info, OPENPIC_SRC_VECTOR(irq), OPENPIC_IMASK); + + openpic_set_priority(info, 0, 15); + + /* we don't need 8259 passthrough mode */ + x = openpic_read(info, OPENPIC_CONFIG); + x |= OPENPIC_CONFIG_8259_PASSTHRU_DISABLE; + openpic_write(info, OPENPIC_CONFIG, x); + + /* send all interrupts to cpu 0 */ + for (int irq = 0; irq < info->irq_count; irq++) + openpic_write(info, OPENPIC_IDEST(irq), 1 << 0); + + for (int irq = 0; irq < info->irq_count; irq++) { + x = irq; + x |= OPENPIC_IMASK; + x |= OPENPIC_POLARITY_POSITIVE; + x |= OPENPIC_SENSE_LEVEL; + x |= 8 << OPENPIC_PRIORITY_SHIFT; + openpic_write(info, OPENPIC_SRC_VECTOR(irq), x); + } + + /* XXX IPI */ + /* XXX set spurious intr vector */ + + openpic_set_priority(info, 0, 0); + + /* clear all pending interrupts */ + for (int irq = 0; irq < info->irq_count; irq++) { + openpic_read_irq(info, 0); + openpic_eoi(info, 0); + } + + return B_OK; +} + + +// #pragma mark - driver interface + + +static status_t +openpic_std_ops(int32 op, ...) +{ + switch (op) { + case B_MODULE_INIT: + case B_MODULE_UNINIT: + return B_OK; + + default: + return B_ERROR; + } +} + + +static float +openpic_supports_device(device_node_handle parent, bool *_noConnection) +{ + char *bus; + uint16 vendorID; + uint16 deviceID; + + // get the bus (should be PCI) + if (sDeviceManager->get_attr_string(parent, B_DRIVER_BUS, &bus, false) + != B_OK) { + return B_ERROR; + } + MemoryDeleter _(bus); + + // get vendor and device ID + if (sDeviceManager->get_attr_uint16(parent, PCI_DEVICE_VENDOR_ID_ITEM, + &vendorID, false) != B_OK + || sDeviceManager->get_attr_uint16(parent, PCI_DEVICE_DEVICE_ID_ITEM, + &deviceID, false) != B_OK) { + return B_ERROR; + } + + // check, whether bus, vendor and device ID match + if (strcmp(bus, "pci") != 0 + || !openpic_check_supported_device(vendorID, deviceID)) { + return 0.0; + } + + return 0.6; +} + + +static status_t +openpic_register_device(device_node_handle parent) +{ + // get interface to PCI device + pci_device_module_info *pci; + pci_device device; + status_t error = sDeviceManager->init_driver(parent, NULL, + (driver_module_info**)&pci, (void**)&device); + if (error != B_OK) + return error; + + sDeviceManager->uninit_driver(parent); + + device_attr attrs[] = { + // info about ourself + { B_DRIVER_MODULE, B_STRING_TYPE, { string: OPENPIC_MODULE_NAME }}, + { B_DRIVER_DEVICE_TYPE, B_STRING_TYPE, + { string: B_INTERRUPT_CONTROLLER_DRIVER_TYPE }}, + + {} + }; + + return sDeviceManager->register_device(parent, attrs, NULL, NULL); +} + + +static status_t +openpic_init_driver(device_node_handle node, void *user_cookie, + void **cookie) +{ + openpic_info *info = new(nothrow) openpic_info; + if (!info) + return B_NO_MEMORY; + ObjectDeleter infoDeleter(info); + + info->node = node; + + // get interface to PCI device + status_t error = sDeviceManager->init_driver( + sDeviceManager->get_parent(node), NULL, + (driver_module_info**)&info->pci, (void**)&info->device); + if (error != B_OK) + return error; + + // get the pci info for the device + pci_info pciInfo; + error = info->pci->get_pci_info(info->device, &pciInfo); + if (error != B_OK) + return error; + + // find supported device info + info->supported_device = openpic_check_supported_device(pciInfo.vendor_id, + pciInfo.device_id); + if (!info->supported_device) { + dprintf("openpic: device (0x%04hx:0x%04hx) not supported\n", + pciInfo.vendor_id, pciInfo.device_id); + return B_ERROR; + } + dprintf("openpic: found supported device: %s (0x%04hx:0x%04hx)\n", + info->supported_device->name, pciInfo.vendor_id, pciInfo.device_id); + + // get register space + addr_t physicalRegisterBase = pciInfo.u.h0.base_registers[0]; + uint32 registerSpaceSize = pciInfo.u.h0.base_register_sizes[0]; + if (registerSpaceSize < info->supported_device->register_offset + || registerSpaceSize - info->supported_device->register_offset + < OPENPIC_MIN_REGISTER_SPACE_SIZE) { + dprintf("openpic: register space too small\n"); + } + physicalRegisterBase += info->supported_device->register_offset; + registerSpaceSize -= info->supported_device->register_offset; + if (registerSpaceSize > OPENPIC_MAX_REGISTER_SPACE_SIZE) + registerSpaceSize = OPENPIC_MAX_REGISTER_SPACE_SIZE; + + // map register space + void *virtualRegisterBase = NULL; + area_id registerArea = map_physical_memory("openpic registers", + (void*)physicalRegisterBase, registerSpaceSize, B_ANY_KERNEL_ADDRESS, + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, &virtualRegisterBase); + if (registerArea < 0) + return info->register_area; + + info->physical_registers = physicalRegisterBase; + info->register_space_size = registerSpaceSize; + info->register_area = registerArea; + info->virtual_registers = (addr_t)virtualRegisterBase; + + // init the controller + error = openpic_init(info); + if (error != B_OK) + return error; + + // keep the info + infoDeleter.Detach(); + *cookie = info; + + dprintf("openpic_init_driver(): Successfully initialized!\n"); + + return B_OK; +} + + +static status_t +openpic_uninit_driver(void *cookie) +{ + openpic_info *info = (openpic_info*)cookie; + + delete info; + + return B_OK; +} + + +static void +openpic_device_removed(device_node_handle node, void *cookie) +{ + // TODO: ... +} + + +static void +openpic_get_paths(const char ***_bus, const char ***_device) +{ + static const char *kBus[] = { "pci", NULL }; +// static const char *kDevice[] = { "drivers/dev/disk/ide", NULL }; + + *_bus = kBus; +// *_device = kDevice; + *_device = NULL; +} + + +// #pragma mark - interrupt_controller interface + + +static status_t +openpic_get_controller_info(void *cookie, interrupt_controller_info *_info) +{ + if (!_info) + return B_BAD_VALUE; + + openpic_info *info = (openpic_info*)cookie; + + *_info = *info; + + return B_OK; +} + + +static status_t +openpic_enable_io_interrupt(void *cookie, int irq, int type) +{ + openpic_info *info = (openpic_info*)cookie; + + openpic_enable_irq(info, irq, type); + + return B_OK; +} + + +static status_t +openpic_disable_io_interrupt(void *cookie, int irq) +{ + openpic_info *info = (openpic_info*)cookie; + + openpic_disable_irq(info, irq); + + return B_OK; +} + + +static int +openpic_acknowledge_io_interrupt(void *cookie) +{ + openpic_info *info = (openpic_info*)cookie; + + int cpu = 0; + // Note: We direct all I/O interrupts to CPU 0. We could nevertheless + // check against the value of the "Who Am I Register". + + int irq = openpic_read_irq(info, cpu); + if (irq == 255) + return -1; // spurious interrupt + + // signal end of interrupt + openpic_eoi(info, cpu); + + return irq; +} + + +static interrupt_controller_module_info sControllerModuleInfo = { + { + { + OPENPIC_MODULE_NAME, + 0, + openpic_std_ops + }, + + openpic_supports_device, + openpic_register_device, + openpic_init_driver, + openpic_uninit_driver, + openpic_device_removed, + NULL, // cleanup + openpic_get_paths, + }, + + openpic_get_controller_info, + openpic_enable_io_interrupt, + openpic_disable_io_interrupt, + openpic_acknowledge_io_interrupt, +}; + +module_dependency module_dependencies[] = { + { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&sDeviceManager }, + { B_PCI_MODULE_NAME, (module_info**)&sPCIBusManager}, + {} +}; + +module_info *modules[] = { + (module_info *)&sControllerModuleInfo, + NULL +}; diff --git a/src/add-ons/kernel/interrupt_controllers/openpic/openpic.h b/src/add-ons/kernel/interrupt_controllers/openpic/openpic.h new file mode 100644 index 0000000000..66b5684398 --- /dev/null +++ b/src/add-ons/kernel/interrupt_controllers/openpic/openpic.h @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2000 Tsubai Masanari. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 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) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * from NetBSD: openpicreg.h,v 1.3 2001/08/30 03:08:52 briggs Exp + * $FreeBSD$ + */ + +#ifndef OPENPIC_H +#define OPENPIC_H + +/* + * Size of OpenPIC register space + */ +#define OPENPIC_SIZE 0x40000 + +/* + * GLOBAL/TIMER register (IDU base + 0x1000) + */ + +/* feature reporting reg 0 */ +#define OPENPIC_FEATURE 0x1000 +#define OPENPIC_FEATURE_VERSION_MASK 0x000000ff +#define OPENPIC_FEATURE_LAST_CPU_MASK 0x00001f00 +#define OPENPIC_FEATURE_LAST_CPU_SHIFT 8 +#define OPENPIC_FEATURE_LAST_IRQ_MASK 0x07ff0000 +#define OPENPIC_FEATURE_LAST_IRQ_SHIFT 16 + +/* global config reg 0 */ +#define OPENPIC_CONFIG 0x1020 +#define OPENPIC_CONFIG_RESET 0x80000000 +#define OPENPIC_CONFIG_8259_PASSTHRU_DISABLE 0x20000000 + +/* interrupt configuration mode (direct or serial) */ +#define OPENPIC_ICR 0x1030 +#define OPENPIC_ICR_SERIAL_MODE (1 << 27) +#define OPENPIC_ICR_SERIAL_RATIO_MASK (0x7 << 28) +#define OPENPIC_ICR_SERIAL_RATIO_SHIFT 28 + +/* processor initialization reg */ +#define OPENPIC_PROC_INIT 0x1090 + +/* IPI vector/priority reg */ +#define OPENPIC_IPI_VECTOR(ipi) (0x10a0 + (ipi) * 0x10) + +/* spurious intr. vector */ +#define OPENPIC_SPURIOUS_VECTOR 0x10e0 + + +/* + * INTERRUPT SOURCE register (IDU base + 0x10000) + */ + +/* interrupt vector/priority reg */ +#ifndef OPENPIC_SRC_VECTOR +#define OPENPIC_SRC_VECTOR(irq) (0x10000 + (irq) * 0x20) +#endif +#define OPENPIC_SENSE_LEVEL 0x00400000 +#define OPENPIC_SENSE_EDGE 0x00000000 +#define OPENPIC_POLARITY_POSITIVE 0x00800000 +#define OPENPIC_POLARITY_NEGATIVE 0x00000000 +#define OPENPIC_IMASK 0x80000000 +#define OPENPIC_ACTIVITY 0x40000000 +#define OPENPIC_PRIORITY_MASK 0x000f0000 +#define OPENPIC_PRIORITY_SHIFT 16 +#define OPENPIC_VECTOR_MASK 0x000000ff + +/* interrupt destination cpu */ +#ifndef OPENPIC_IDEST +#define OPENPIC_IDEST(irq) (0x10010 + (irq) * 0x20) +#endif + +/* + * PROCESSOR register (IDU base + 0x20000) + */ + +/* IPI command reg */ +#define OPENPIC_IPI(cpu, ipi) (0x20040 + (cpu) * 0x1000 + (ipi)) + +/* current task priority reg */ +#define OPENPIC_CPU_PRIORITY(cpu) (0x20080 + (cpu) * 0x1000) +#define OPENPIC_CPU_PRIORITY_MASK 0x0000000f + +/* interrupt acknowledge reg */ +#define OPENPIC_IACK(cpu) (0x200a0 + (cpu) * 0x1000) + +/* end of interrupt reg */ +#define OPENPIC_EOI(cpu) (0x200b0 + (cpu) * 0x1000) + +#endif // OPENPIC_H