o Grab the number of devices supported by PLIC from FDT.
o Fix bug in PLIC_ENABLE macro when irq >= 32. Tested on the real hardware, which is HiFive Unleashed board. Thanks to SiFive, Inc. for the board provided. Reviewed by: markj Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D19775
This commit is contained in:
parent
95a1f0e81c
commit
a8cb655d2e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=345796
@ -52,9 +52,9 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include "pic_if.h"
|
||||
|
||||
#define PLIC_NIRQS 32
|
||||
#define PLIC_MAX_IRQS 2048
|
||||
#define PLIC_PRIORITY(n) (0x000000 + (n) * 0x4)
|
||||
#define PLIC_ENABLE(n, h) (0x002000 + (h) * 0x80 + (n) / 32)
|
||||
#define PLIC_ENABLE(n, h) (0x002000 + (h) * 0x80 + 4 * ((n) / 32))
|
||||
#define PLIC_THRESHOLD(h) (0x200000 + (h) * 0x1000 + 0x0)
|
||||
#define PLIC_CLAIM(h) (0x200000 + (h) * 0x1000 + 0x4)
|
||||
|
||||
@ -66,7 +66,8 @@ struct plic_irqsrc {
|
||||
struct plic_softc {
|
||||
device_t dev;
|
||||
struct resource * intc_res;
|
||||
struct plic_irqsrc isrcs[PLIC_NIRQS];
|
||||
struct plic_irqsrc isrcs[PLIC_MAX_IRQS];
|
||||
int ndev;
|
||||
};
|
||||
|
||||
#define RD4(sc, reg) \
|
||||
@ -158,7 +159,7 @@ plic_map_intr(device_t dev, struct intr_map_data *data,
|
||||
return (ENOTSUP);
|
||||
|
||||
daf = (struct intr_map_data_fdt *)data;
|
||||
if (daf->ncells != 1 || daf->cells[0] >= PLIC_NIRQS)
|
||||
if (daf->ncells != 1 || daf->cells[0] > sc->ndev)
|
||||
return (EINVAL);
|
||||
|
||||
*isrcp = &sc->isrcs[daf->cells[0]].isrc;
|
||||
@ -189,6 +190,7 @@ plic_attach(device_t dev)
|
||||
struct intr_pic *pic;
|
||||
uint32_t irq;
|
||||
const char *name;
|
||||
phandle_t node;
|
||||
phandle_t xref;
|
||||
uint32_t cpu;
|
||||
int error;
|
||||
@ -198,6 +200,20 @@ plic_attach(device_t dev)
|
||||
|
||||
sc->dev = dev;
|
||||
|
||||
node = ofw_bus_get_node(dev);
|
||||
if ((OF_getencprop(node, "riscv,ndev", &sc->ndev,
|
||||
sizeof(sc->ndev))) < 0) {
|
||||
device_printf(dev,
|
||||
"Error: could not get number of devices\n");
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
if (sc->ndev >= PLIC_MAX_IRQS) {
|
||||
device_printf(dev,
|
||||
"Error: invalid ndev (%d)\n", sc->ndev);
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
/* Request memory resources */
|
||||
rid = 0;
|
||||
sc->intc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
|
||||
@ -211,7 +227,7 @@ plic_attach(device_t dev)
|
||||
isrcs = sc->isrcs;
|
||||
name = device_get_nameunit(sc->dev);
|
||||
cpu = PCPU_GET(cpuid);
|
||||
for (irq = 0; irq < PLIC_NIRQS; irq++) {
|
||||
for (irq = 1; irq <= sc->ndev; irq++) {
|
||||
isrcs[irq].irq = irq;
|
||||
error = intr_isrc_register(&isrcs[irq].isrc, sc->dev,
|
||||
0, "%s,%u", name, irq);
|
||||
@ -223,7 +239,7 @@ plic_attach(device_t dev)
|
||||
}
|
||||
WR4(sc, PLIC_THRESHOLD(cpu), 0);
|
||||
|
||||
xref = OF_xref_from_node(ofw_bus_get_node(sc->dev));
|
||||
xref = OF_xref_from_node(node);
|
||||
pic = intr_pic_register(sc->dev, xref);
|
||||
if (pic == NULL)
|
||||
return (ENXIO);
|
||||
|
Loading…
Reference in New Issue
Block a user