svn commit: r335007 - in head/sys: conf riscv/conf riscv/include riscv/riscv
Ruslan Bukin
br at FreeBSD.org
Tue Jun 12 17:45:18 UTC 2018
Author: br
Date: Tue Jun 12 17:45:15 2018
New Revision: 335007
URL: https://svnweb.freebsd.org/changeset/base/335007
Log:
o Add driver for PLIC (Platform-Level Interrupt Controller) device.
o Convert interrupt machdep support to use INTRNG code.
Sponsored by: DARPA, AFRL
Added:
head/sys/riscv/riscv/plic.c (contents, props changed)
Modified:
head/sys/conf/files.riscv
head/sys/conf/options.riscv
head/sys/riscv/conf/GENERIC
head/sys/riscv/include/intr.h
head/sys/riscv/include/riscvreg.h
head/sys/riscv/include/smp.h
head/sys/riscv/riscv/intr_machdep.c
head/sys/riscv/riscv/machdep.c
head/sys/riscv/riscv/mp_machdep.c
head/sys/riscv/riscv/nexus.c
head/sys/riscv/riscv/timer.c
Modified: head/sys/conf/files.riscv
==============================================================================
--- head/sys/conf/files.riscv Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/conf/files.riscv Tue Jun 12 17:45:15 2018 (r335007)
@@ -9,8 +9,11 @@ dev/ofw/ofw_cpu.c optional fdt
dev/uart/uart_cpu_fdt.c optional uart fdt
dev/xilinx/axi_quad_spi.c optional xilinx_spi
kern/kern_clocksource.c standard
+kern/msi_if.m standard
+kern/pic_if.m standard
kern/subr_devmap.c standard
kern/subr_dummy_vdso_tc.c standard
+kern/subr_intr.c standard
libkern/bcmp.c standard
libkern/bcopy.c standard
libkern/ffs.c standard
@@ -44,6 +47,7 @@ riscv/riscv/mp_machdep.c optional smp
riscv/riscv/mem.c standard
riscv/riscv/nexus.c standard
riscv/riscv/ofw_machdep.c optional fdt
+riscv/riscv/plic.c standard
riscv/riscv/pmap.c standard
riscv/riscv/riscv_console.c optional rcons
riscv/riscv/soc.c standard
Modified: head/sys/conf/options.riscv
==============================================================================
--- head/sys/conf/options.riscv Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/conf/options.riscv Tue Jun 12 17:45:15 2018 (r335007)
@@ -2,3 +2,4 @@
RISCV opt_global.h
FPE opt_global.h
+INTRNG opt_global.h
Modified: head/sys/riscv/conf/GENERIC
==============================================================================
--- head/sys/riscv/conf/GENERIC Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/conf/GENERIC Tue Jun 12 17:45:15 2018 (r335007)
@@ -76,6 +76,7 @@ options RACCT # Resource accounting framework
options RACCT_DEFAULT_TO_DISABLED # Set kern.racct.enable=0 by default
options RCTL # Resource limits
options SMP
+options INTRNG
# RISC-V SBI console
device rcons
Modified: head/sys/riscv/include/intr.h
==============================================================================
--- head/sys/riscv/include/intr.h Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/include/intr.h Tue Jun 12 17:45:15 2018 (r335007)
@@ -37,11 +37,19 @@
#ifndef _MACHINE_INTR_MACHDEP_H_
#define _MACHINE_INTR_MACHDEP_H_
+#define RISCV_NIRQ 1024
+
+#ifndef NIRQ
+#define NIRQ RISCV_NIRQ
+#endif
+
+#ifdef INTRNG
+#include <sys/intr.h>
+#endif
+
struct trapframe;
-void riscv_init_interrupts(void);
int riscv_teardown_intr(void *);
-int riscv_config_intr(u_int, enum intr_trigger, enum intr_polarity);
int riscv_setup_intr(const char *, driver_filter_t *, driver_intr_t *,
void *, int, int, void **);
void riscv_cpu_intr(struct trapframe *);
@@ -69,12 +77,7 @@ enum {
IRQ_EXTERNAL_SUPERVISOR,
IRQ_EXTERNAL_HYPERVISOR,
IRQ_EXTERNAL_MACHINE,
-#if 0
- /* lowRISC TODO */
- IRQ_COP, /* lowRISC only */
- IRQ_UART, /* lowRISC only */
-#endif
- NIRQS
+ INTC_NIRQS
};
#endif /* !_MACHINE_INTR_MACHDEP_H_ */
Modified: head/sys/riscv/include/riscvreg.h
==============================================================================
--- head/sys/riscv/include/riscvreg.h Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/include/riscvreg.h Tue Jun 12 17:45:15 2018 (r335007)
@@ -137,6 +137,8 @@
#define SIE_SSIE (1 << 1)
#define SIE_UTIE (1 << 4)
#define SIE_STIE (1 << 5)
+#define SIE_UEIE (1 << 8)
+#define SIE_SEIE (1 << 9)
#define MIP_SEIP (1 << 9)
Modified: head/sys/riscv/include/smp.h
==============================================================================
--- head/sys/riscv/include/smp.h Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/include/smp.h Tue Jun 12 17:45:15 2018 (r335007)
@@ -46,6 +46,8 @@
#define IPI_STOP_HARD (1 << 4)
#define IPI_HARDCLOCK (1 << 5)
+#define INTR_IPI_COUNT 1
+
void ipi_all_but_self(u_int ipi);
void ipi_cpu(int cpu, u_int ipi);
void ipi_selected(cpuset_t cpus, u_int ipi);
Modified: head/sys/riscv/riscv/intr_machdep.c
==============================================================================
--- head/sys/riscv/riscv/intr_machdep.c Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/riscv/intr_machdep.c Tue Jun 12 17:45:15 2018 (r335007)
@@ -38,11 +38,13 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
#include <sys/cpuset.h>
#include <sys/interrupt.h>
#include <sys/smp.h>
-#include <sys/vmmeter.h>
+#include <machine/bus.h>
#include <machine/clock.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
@@ -50,45 +52,23 @@ __FBSDID("$FreeBSD$");
#include <machine/intr.h>
#include <machine/sbi.h>
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
#ifdef SMP
#include <machine/smp.h>
#endif
-u_long intrcnt[NIRQS];
-size_t sintrcnt = sizeof(intrcnt);
+void intr_irq_handler(struct trapframe *tf);
-char intrnames[NIRQS * (MAXCOMLEN + 1) * 2];
-size_t sintrnames = sizeof(intrnames);
+struct intc_irqsrc {
+ struct intr_irqsrc isrc;
+ u_int irq;
+};
-static struct intr_event *intr_events[NIRQS];
-static riscv_intrcnt_t riscv_intr_counters[NIRQS];
+struct intc_irqsrc isrcs[INTC_NIRQS];
-static int intrcnt_index;
-
-riscv_intrcnt_t
-riscv_intrcnt_create(const char* name)
-{
- riscv_intrcnt_t counter;
-
- counter = &intrcnt[intrcnt_index++];
- riscv_intrcnt_setname(counter, name);
-
- return (counter);
-}
-
-void
-riscv_intrcnt_setname(riscv_intrcnt_t counter, const char *name)
-{
- int i;
-
- i = (counter - intrcnt);
-
- KASSERT(counter != NULL, ("riscv_intrcnt_setname: NULL counter"));
-
- snprintf(intrnames + (MAXCOMLEN + 1) * i,
- MAXCOMLEN + 1, "%-*s", MAXCOMLEN, name);
-}
-
static void
riscv_mask_irq(void *source)
{
@@ -102,15 +82,10 @@ riscv_mask_irq(void *source)
break;
case IRQ_SOFTWARE_USER:
csr_clear(sie, SIE_USIE);
+ break;
case IRQ_SOFTWARE_SUPERVISOR:
csr_clear(sie, SIE_SSIE);
break;
-#if 0
- /* lowRISC TODO */
- case IRQ_UART:
- machine_command(ECALL_IO_IRQ_MASK, 0);
- break;
-#endif
default:
panic("Unknown irq %d\n", irq);
}
@@ -133,60 +108,37 @@ riscv_unmask_irq(void *source)
case IRQ_SOFTWARE_SUPERVISOR:
csr_set(sie, SIE_SSIE);
break;
-#if 0
- /* lowRISC TODO */
- case IRQ_UART:
- machine_command(ECALL_IO_IRQ_MASK, 1);
- break;
-#endif
default:
panic("Unknown irq %d\n", irq);
}
}
-void
-riscv_init_interrupts(void)
-{
- char name[MAXCOMLEN + 1];
- int i;
-
- for (i = 0; i < NIRQS; i++) {
- snprintf(name, MAXCOMLEN + 1, "int%d:", i);
- riscv_intr_counters[i] = riscv_intrcnt_create(name);
- }
-}
-
int
riscv_setup_intr(const char *name, driver_filter_t *filt,
void (*handler)(void*), void *arg, int irq, int flags, void **cookiep)
{
- struct intr_event *event;
+ struct intr_irqsrc *isrc;
int error;
- if (irq < 0 || irq >= NIRQS)
+ if (irq < 0 || irq >= INTC_NIRQS)
panic("%s: unknown intr %d", __func__, irq);
- event = intr_events[irq];
- if (event == NULL) {
- error = intr_event_create(&event, (void *)(uintptr_t)irq, 0,
- irq, riscv_mask_irq, riscv_unmask_irq,
- NULL, NULL, "int%d", irq);
+ isrc = &isrcs[irq].isrc;
+ if (isrc->isrc_event == NULL) {
+ error = intr_event_create(&isrc->isrc_event, isrc, 0, irq,
+ riscv_mask_irq, riscv_unmask_irq, NULL, NULL, "int%d", irq);
if (error)
return (error);
- intr_events[irq] = event;
riscv_unmask_irq((void*)(uintptr_t)irq);
}
- error = intr_event_add_handler(event, name, filt, handler, arg,
- intr_priority(flags), flags, cookiep);
+ error = intr_event_add_handler(isrc->isrc_event, name,
+ filt, handler, arg, intr_priority(flags), flags, cookiep);
if (error) {
printf("Failed to setup intr: %d\n", irq);
return (error);
}
- riscv_intrcnt_setname(riscv_intr_counters[irq],
- event->ie_fullname);
-
return (0);
}
@@ -199,19 +151,10 @@ riscv_teardown_intr(void *ih)
return (0);
}
-int
-riscv_config_intr(u_int irq, enum intr_trigger trig, enum intr_polarity pol)
-{
-
- /* There is no configuration for interrupts */
-
- return (0);
-}
-
void
riscv_cpu_intr(struct trapframe *frame)
{
- struct intr_event *event;
+ struct intr_irqsrc *isrc;
int active_irq;
critical_enter();
@@ -222,26 +165,20 @@ riscv_cpu_intr(struct trapframe *frame)
active_irq = (frame->tf_scause & EXCP_MASK);
switch (active_irq) {
-#if 0
- /* lowRISC TODO */
- case IRQ_UART:
-#endif
case IRQ_SOFTWARE_USER:
case IRQ_SOFTWARE_SUPERVISOR:
case IRQ_TIMER_SUPERVISOR:
- event = intr_events[active_irq];
- /* Update counters */
- atomic_add_long(riscv_intr_counters[active_irq], 1);
- VM_CNT_INC(v_intr);
+ isrc = &isrcs[active_irq].isrc;
+ if (intr_isrc_dispatch(isrc, frame) != 0)
+ printf("stray interrupt %d\n", active_irq);
break;
+ case IRQ_EXTERNAL_SUPERVISOR:
+ intr_irq_handler(frame);
+ break;
default:
- event = NULL;
+ break;
}
- if (!event || TAILQ_EMPTY(&event->ie_handlers) ||
- (intr_event_handle(event, frame) != 0))
- printf("stray interrupt %d\n", active_irq);
-
critical_exit();
}
@@ -320,5 +257,22 @@ ipi_selected(cpuset_t cpus, u_int ipi)
}
sbi_send_ipi(&mask);
}
-
#endif
+
+/* Interrupt machdep initialization routine. */
+static void
+intc_init(void *dummy __unused)
+{
+ int error;
+ int i;
+
+ for (i = 0; i < INTC_NIRQS; i++) {
+ isrcs[i].irq = i;
+ error = intr_isrc_register(&isrcs[i].isrc, NULL,
+ 0, "intc,%u", i);
+ if (error != 0)
+ printf("Can't register interrupt %d\n", i);
+ }
+}
+
+SYSINIT(intc_init, SI_SUB_INTR, SI_ORDER_MIDDLE, intc_init, NULL);
Modified: head/sys/riscv/riscv/machdep.c
==============================================================================
--- head/sys/riscv/riscv/machdep.c Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/riscv/machdep.c Tue Jun 12 17:45:15 2018 (r335007)
@@ -872,8 +872,6 @@ initriscv(struct riscv_bootparams *rvbp)
init_param2(physmem);
kdb_init();
- riscv_init_interrupts();
-
early_boot = 0;
}
Modified: head/sys/riscv/riscv/mp_machdep.c
==============================================================================
--- head/sys/riscv/riscv/mp_machdep.c Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/riscv/mp_machdep.c Tue Jun 12 17:45:15 2018 (r335007)
@@ -256,6 +256,9 @@ init_secondary(uint64_t cpu)
/* Enable interrupts */
intr_enable();
+ /* Enable external (PLIC) interrupts */
+ csr_set(sie, SIE_SEIE);
+
mtx_lock_spin(&ap_boot_mtx);
atomic_add_rel_32(&smp_cpus, 1);
Modified: head/sys/riscv/riscv/nexus.c
==============================================================================
--- head/sys/riscv/riscv/nexus.c Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/riscv/nexus.c Tue Jun 12 17:45:15 2018 (r335007)
@@ -38,6 +38,7 @@
* ISA code but it's easier to do it here for now), I/O port addresses,
* and I/O memory address space.
*/
+#include "opt_platform.h"
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
@@ -48,22 +49,18 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
-#include <machine/bus.h>
#include <sys/rman.h>
#include <sys/interrupt.h>
-#include <machine/vmparam.h>
-#include <machine/pcb.h>
-#include <vm/vm.h>
-#include <vm/pmap.h>
-
+#include <machine/bus.h>
#include <machine/resource.h>
#include <machine/intr.h>
-#include "opt_platform.h"
-
-#include <dev/fdt/fdt_common.h>
+#ifdef FDT
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
#include "ofw_bus_if.h"
+#endif
extern struct bus_space memmap_bus;
@@ -265,7 +262,7 @@ nexus_config_intr(device_t dev, int irq, enum intr_tri
enum intr_polarity pol)
{
- return (riscv_config_intr(irq, trig, pol));
+ return (EOPNOTSUPP);
}
static int
@@ -282,8 +279,7 @@ nexus_setup_intr(device_t dev, device_t child, struct
if (error)
return (error);
- error = riscv_setup_intr(device_get_nameunit(child), filt, intr,
- arg, rman_get_start(res), flags, cookiep);
+ error = intr_setup_irq(child, res, filt, intr, arg, flags, cookiep);
return (error);
}
@@ -292,7 +288,7 @@ static int
nexus_teardown_intr(device_t dev, device_t child, struct resource *r, void *ih)
{
- return (riscv_teardown_intr(ih));
+ return (intr_teardown_irq(child, r, ih));
}
static int
@@ -321,7 +317,14 @@ nexus_activate_resource(device_t bus, device_t child,
rman_set_bustag(r, &memmap_bus);
rman_set_virtual(r, (void *)vaddr);
rman_set_bushandle(r, vaddr);
+ } else if (type == SYS_RES_IRQ) {
+ err = intr_activate_irq(child, r);
+ if (err != 0) {
+ rman_deactivate_resource(r);
+ return (err);
+ }
}
+
return (0);
}
@@ -375,16 +378,17 @@ static int
nexus_ofw_map_intr(device_t dev, device_t child, phandle_t iparent, int icells,
pcell_t *intr)
{
- int irq;
+ struct intr_map_data_fdt *fdt_data;
+ size_t len;
+ u_int irq;
- if (icells == 3) {
- irq = intr[1];
- if (intr[0] == 0)
- irq += 32; /* SPI */
- else
- irq += 16; /* PPI */
- } else
- irq = intr[0];
+ len = sizeof(*fdt_data) + icells * sizeof(pcell_t);
+ fdt_data = (struct intr_map_data_fdt *)intr_alloc_map_data(
+ INTR_MAP_DATA_FDT, len, M_WAITOK | M_ZERO);
+ fdt_data->iparent = iparent;
+ fdt_data->ncells = icells;
+ memcpy(fdt_data->cells, intr, icells * sizeof(pcell_t));
+ irq = intr_map_irq(NULL, iparent, (struct intr_map_data *)fdt_data);
return (irq);
}
Added: head/sys/riscv/riscv/plic.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/sys/riscv/riscv/plic.c Tue Jun 12 17:45:15 2018 (r335007)
@@ -0,0 +1,254 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2018 Ruslan Bukin <br at bsdpad.com>
+ * All rights reserved.
+ *
+ * This software was developed by SRI International and the University of
+ * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-10-C-0237
+ * ("CTSRD"), as part of the DARPA CRASH research programme.
+ *
+ * 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 THE AUTHOR AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/module.h>
+#include <sys/proc.h>
+#include <sys/rman.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include "pic_if.h"
+
+#define PLIC_NIRQS 32
+#define PLIC_PRIORITY(n) (0x000000 + (n) * 0x4)
+#define PLIC_ENABLE(n, h) (0x002000 + (h) * 0x80 + (n) / 32)
+#define PLIC_THRESHOLD(h) (0x200000 + (h) * 0x1000 + 0x0)
+#define PLIC_CLAIM(h) (0x200000 + (h) * 0x1000 + 0x4)
+
+struct plic_irqsrc {
+ struct intr_irqsrc isrc;
+ u_int irq;
+};
+
+struct plic_softc {
+ device_t dev;
+ struct resource * intc_res;
+ struct plic_irqsrc isrcs[PLIC_NIRQS];
+};
+
+#define RD4(sc, reg) \
+ bus_read_4(sc->intc_res, (reg))
+#define WR4(sc, reg, val) \
+ bus_write_4(sc->intc_res, (reg), (val))
+
+static inline void
+plic_irq_dispatch(struct plic_softc *sc, u_int irq,
+ struct trapframe *tf)
+{
+ struct plic_irqsrc *src;
+
+ src = &sc->isrcs[irq];
+
+ if (intr_isrc_dispatch(&src->isrc, tf) != 0)
+ device_printf(sc->dev, "Stray irq %u detected\n", irq);
+}
+
+static int
+plic_intr(void *arg)
+{
+ struct plic_softc *sc;
+ struct trapframe *tf;
+ uint32_t pending;
+ uint32_t cpu;
+
+ sc = arg;
+ cpu = PCPU_GET(cpuid);
+
+ pending = RD4(sc, PLIC_CLAIM(cpu));
+ if (pending) {
+ tf = curthread->td_intr_frame;
+ plic_irq_dispatch(sc, pending, tf);
+ WR4(sc, PLIC_CLAIM(cpu), pending);
+ }
+
+ return (FILTER_HANDLED);
+}
+
+static void
+plic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+ struct plic_softc *sc;
+ struct plic_irqsrc *src;
+ uint32_t reg;
+ uint32_t cpu;
+
+ sc = device_get_softc(dev);
+ src = (struct plic_irqsrc *)isrc;
+
+ cpu = PCPU_GET(cpuid);
+
+ reg = RD4(sc, PLIC_ENABLE(src->irq, cpu));
+ reg &= ~(1 << (src->irq % 32));
+ WR4(sc, PLIC_ENABLE(src->irq, cpu), reg);
+}
+
+static void
+plic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
+{
+ struct plic_softc *sc;
+ struct plic_irqsrc *src;
+ uint32_t reg;
+ uint32_t cpu;
+
+ sc = device_get_softc(dev);
+ src = (struct plic_irqsrc *)isrc;
+
+ WR4(sc, PLIC_PRIORITY(src->irq), 1);
+
+ cpu = PCPU_GET(cpuid);
+
+ reg = RD4(sc, PLIC_ENABLE(src->irq, cpu));
+ reg |= (1 << (src->irq % 32));
+ WR4(sc, PLIC_ENABLE(src->irq, cpu), reg);
+}
+
+static int
+plic_map_intr(device_t dev, struct intr_map_data *data,
+ struct intr_irqsrc **isrcp)
+{
+ struct intr_map_data_fdt *daf;
+ struct plic_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells != 1 || daf->cells[0] >= PLIC_NIRQS)
+ return (EINVAL);
+
+ *isrcp = &sc->isrcs[daf->cells[0]].isrc;
+
+ return (0);
+}
+
+static int
+plic_probe(device_t dev)
+{
+
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_is_compatible(dev, "riscv,plic0"))
+ return (ENXIO);
+
+ device_set_desc(dev, "RISC-V PLIC");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+plic_attach(device_t dev)
+{
+ struct plic_irqsrc *isrcs;
+ struct plic_softc *sc;
+ struct intr_pic *pic;
+ uint32_t irq;
+ const char *name;
+ phandle_t xref;
+ uint32_t cpu;
+ int error;
+ int rid;
+
+ sc = device_get_softc(dev);
+
+ sc->dev = dev;
+
+ /* Request memory resources */
+ rid = 0;
+ sc->intc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
+ RF_ACTIVE);
+ if (sc->intc_res == NULL) {
+ device_printf(dev,
+ "Error: could not allocate memory resources\n");
+ return (ENXIO);
+ }
+
+ isrcs = sc->isrcs;
+ name = device_get_nameunit(sc->dev);
+ cpu = PCPU_GET(cpuid);
+ for (irq = 0; irq < PLIC_NIRQS; irq++) {
+ isrcs[irq].irq = irq;
+ error = intr_isrc_register(&isrcs[irq].isrc, sc->dev,
+ 0, "%s,%u", name, irq);
+ if (error != 0)
+ return (error);
+
+ WR4(sc, PLIC_ENABLE(irq, cpu), 0);
+ }
+ WR4(sc, PLIC_THRESHOLD(cpu), 0);
+
+ xref = OF_xref_from_node(ofw_bus_get_node(sc->dev));
+ pic = intr_pic_register(sc->dev, xref);
+ if (pic == NULL)
+ return (ENXIO);
+
+ csr_set(sie, SIE_SEIE);
+
+ return (intr_pic_claim_root(sc->dev, xref, plic_intr, sc, 0));
+}
+
+static device_method_t plic_methods[] = {
+ DEVMETHOD(device_probe, plic_probe),
+ DEVMETHOD(device_attach, plic_attach),
+
+ DEVMETHOD(pic_disable_intr, plic_disable_intr),
+ DEVMETHOD(pic_enable_intr, plic_enable_intr),
+ DEVMETHOD(pic_map_intr, plic_map_intr),
+
+ DEVMETHOD_END
+};
+
+static driver_t plic_driver = {
+ "plic",
+ plic_methods,
+ sizeof(struct plic_softc),
+};
+
+static devclass_t plic_devclass;
+
+EARLY_DRIVER_MODULE(plic, simplebus, plic_driver, plic_devclass,
+ 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE);
Modified: head/sys/riscv/riscv/timer.c
==============================================================================
--- head/sys/riscv/riscv/timer.c Tue Jun 12 17:07:30 2018 (r335006)
+++ head/sys/riscv/riscv/timer.c Tue Jun 12 17:45:15 2018 (r335007)
@@ -70,8 +70,6 @@ struct riscv_timer_softc {
void *ih;
uint32_t clkfreq;
struct eventtimer et;
- int intr_rid;
- struct resource *intr_res;
};
static struct riscv_timer_softc *riscv_timer_sc = NULL;
@@ -188,18 +186,9 @@ riscv_timer_attach(device_t dev)
riscv_timer_sc = sc;
- sc->intr_rid = 0;
- sc->intr_res = bus_alloc_resource(dev,
- SYS_RES_IRQ, &sc->intr_rid, IRQ_TIMER_SUPERVISOR,
- IRQ_TIMER_SUPERVISOR, 1, RF_ACTIVE);
- if (sc->intr_res == NULL) {
- device_printf(dev, "failed to allocate irq\n");
- return (ENXIO);
- }
-
/* Setup IRQs handler */
- error = bus_setup_intr(dev, sc->intr_res, INTR_TYPE_CLK,
- riscv_timer_intr, NULL, sc, &sc->ih);
+ error = riscv_setup_intr(device_get_nameunit(dev), riscv_timer_intr,
+ NULL, sc, IRQ_TIMER_SUPERVISOR, INTR_TYPE_CLK, &sc->ih);
if (error) {
device_printf(dev, "Unable to alloc int resource.\n");
return (ENXIO);
More information about the svn-src-all
mailing list