Thu Jul 16 18:39:19 2020 UTC ()
Add driver for Cavium Interrupt Bus.
(jmcneill)
diff -r1.3 -r1.4 src/sys/arch/evbmips/conf/OCTEON
diff -r0 -r1.1 src/sys/arch/mips/cavium/dev/octeon_cib.c
diff -r1.10 -r1.11 src/sys/arch/mips/conf/files.octeon
--- src/sys/arch/evbmips/conf/OCTEON 2020/07/16 16:39:54 1.3
+++ src/sys/arch/evbmips/conf/OCTEON 2020/07/16 18:39:18 1.4
| @@ -1,21 +1,21 @@ | | | @@ -1,21 +1,21 @@ |
1 | # $NetBSD: OCTEON,v 1.3 2020/07/16 16:39:54 jmcneill Exp $ | | 1 | # $NetBSD: OCTEON,v 1.4 2020/07/16 18:39:18 jmcneill Exp $ |
2 | | | 2 | |
3 | include "arch/mips/conf/std.octeon" | | 3 | include "arch/mips/conf/std.octeon" |
4 | include "arch/evbmips/conf/files.octeon" | | 4 | include "arch/evbmips/conf/files.octeon" |
5 | | | 5 | |
6 | #options INCLUDE_CONFIG_FILE # embed config file in kernel binary | | 6 | #options INCLUDE_CONFIG_FILE # embed config file in kernel binary |
7 | | | 7 | |
8 | #ident "ERLITE-$Revision: 1.3 $" | | 8 | #ident "ERLITE-$Revision: 1.4 $" |
9 | | | 9 | |
10 | maxusers 32 | | 10 | maxusers 32 |
11 | | | 11 | |
12 | options FDT | | 12 | options FDT |
13 | options FDT_DEFAULT_STDOUT_PATH="\"uart0:115200n8\"" | | 13 | options FDT_DEFAULT_STDOUT_PATH="\"uart0:115200n8\"" |
14 | | | 14 | |
15 | # Options for necessary to use MD | | 15 | # Options for necessary to use MD |
16 | #options MEMORY_DISK_HOOKS | | 16 | #options MEMORY_DISK_HOOKS |
17 | #options MEMORY_DISK_IS_ROOT # force root on memory disk | | 17 | #options MEMORY_DISK_IS_ROOT # force root on memory disk |
18 | #options MEMORY_DISK_SERVER=0 # no userspace memory disk support | | 18 | #options MEMORY_DISK_SERVER=0 # no userspace memory disk support |
19 | #options MEMORY_DISK_ROOT_SIZE=6144 # size of memory disk, in blocks | | 19 | #options MEMORY_DISK_ROOT_SIZE=6144 # size of memory disk, in blocks |
20 | #options MEMORY_DISK_ROOT_SIZE=16384 # size of memory disk, in blocks | | 20 | #options MEMORY_DISK_ROOT_SIZE=16384 # size of memory disk, in blocks |
21 | #options MEMORY_DISK_ROOT_SIZE=7300 | | 21 | #options MEMORY_DISK_ROOT_SIZE=7300 |
| @@ -109,34 +109,35 @@ options NFS_BOOT_DHCP | | | @@ -109,34 +109,35 @@ options NFS_BOOT_DHCP |
109 | config netbsd root on ? type ? | | 109 | config netbsd root on ? type ? |
110 | #config netbsd root on cnmac0 type nfs | | 110 | #config netbsd root on cnmac0 type nfs |
111 | | | 111 | |
112 | mainbus0 at root | | 112 | mainbus0 at root |
113 | cpunode0 at mainbus? | | 113 | cpunode0 at mainbus? |
114 | cpu* at cpunode? core ? | | 114 | cpu* at cpunode? core ? |
115 | wdog0 at cpunode0 flags 0 # flags 1 will enable it on boot | | 115 | wdog0 at cpunode0 flags 0 # flags 1 will enable it on boot |
116 | | | 116 | |
117 | iobus0 at mainbus? | | 117 | iobus0 at mainbus? |
118 | bootbus0 at mainbus? | | 118 | bootbus0 at mainbus? |
119 | simplebus* at fdt? pass 0 | | 119 | simplebus* at fdt? pass 0 |
120 | | | 120 | |
121 | octintc* at fdt? pass 1 | | 121 | octintc* at fdt? pass 1 |
| | | 122 | octcib* at fdt? pass 2 |
122 | | | 123 | |
123 | com* at iobus? | | 124 | com* at iobus? |
124 | com* at fdt? | | 125 | com* at fdt? |
125 | | | 126 | |
126 | octsmi* at iobus? # MDIO controller | | 127 | octsmi* at iobus? # MDIO controller |
127 | octsmi* at fdt? pass 2 | | 128 | octsmi* at fdt? pass 3 |
128 | octpip* at iobus? # PIP packet processing controller | | 129 | octpip* at iobus? # PIP packet processing controller |
129 | octpip* at fdt? pass 3 | | 130 | octpip* at fdt? pass 4 |
130 | | | 131 | |
131 | octgmx* at octpip? | | 132 | octgmx* at octpip? |
132 | cnmac* at octgmx? | | 133 | cnmac* at octgmx? |
133 | | | 134 | |
134 | octrnm* at iobus? # Random Number Memory (and generator) | | 135 | octrnm* at iobus? # Random Number Memory (and generator) |
135 | | | 136 | |
136 | dwctwo* at iobus? | | 137 | dwctwo* at iobus? |
137 | | | 138 | |
138 | usb* at dwctwo? | | 139 | usb* at dwctwo? |
139 | | | 140 | |
140 | uhub* at usb? | | 141 | uhub* at usb? |
141 | | | 142 | |
142 | # USB Mass Storage | | 143 | # USB Mass Storage |
/* $NetBSD: octeon_cib.c,v 1.1 2020/07/16 18:39:19 jmcneill Exp $ */
/*-
* Copyright (c) 2020 Jared D. McNeill <jmcneill@invisible.ca>
* 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 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.
*/
#include "opt_multiprocessor.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: octeon_cib.c,v 1.1 2020/07/16 18:39:19 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/kmem.h>
#include <dev/fdt/fdtvar.h>
#include <arch/mips/cavium/octeonvar.h>
static int octeon_cib_match(device_t, cfdata_t, void *);
static void octeon_cib_attach(device_t, device_t, void *);
static void * octeon_cib_establish(device_t, u_int *, int, int,
int (*)(void *), void *);
static void octeon_cib_disestablish(device_t, void *);
static bool octeon_cib_intrstr(device_t, u_int *, char *, size_t);
static int octeon_cib_intr(void *);
struct fdtbus_interrupt_controller_func octeon_cib_funcs = {
.establish = octeon_cib_establish,
.disestablish = octeon_cib_disestablish,
.intrstr = octeon_cib_intrstr
};
struct octeon_cib_intr {
bool ih_mpsafe;
int ih_type;
int (*ih_func)(void *);
void *ih_arg;
uint64_t ih_mask;
};
struct octeon_cib_softc {
device_t sc_dev;
int sc_phandle;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh_raw;
bus_space_handle_t sc_bsh_en;
struct octeon_cib_intr *sc_intr;
u_int sc_nintr;
};
#define CIB_READ_RAW(sc) \
bus_space_read_8((sc)->sc_bst, (sc)->sc_bsh_raw, 0)
#define CIB_WRITE_RAW(sc, val) \
bus_space_write_8((sc)->sc_bst, (sc)->sc_bsh_raw, 0, (val))
#define CIB_READ_EN(sc) \
bus_space_read_8((sc)->sc_bst, (sc)->sc_bsh_en, 0)
#define CIB_WRITE_EN(sc, val) \
bus_space_write_8((sc)->sc_bst, (sc)->sc_bsh_en, 0, (val))
CFATTACH_DECL_NEW(octcib, sizeof(struct octeon_cib_softc),
octeon_cib_match, octeon_cib_attach, NULL, NULL);
static const struct of_compat_data compat_data[] = {
{ "cavium,octeon-7130-cib", 1 },
{ NULL }
};
static int
octeon_cib_match(device_t parent, cfdata_t cf, void *aux)
{
struct fdt_attach_args * const faa = aux;
return of_match_compat_data(faa->faa_phandle, compat_data);
}
static void
octeon_cib_attach(device_t parent, device_t self, void *aux)
{
struct octeon_cib_softc * const sc = device_private(self);
struct fdt_attach_args * const faa = aux;
const int phandle = faa->faa_phandle;
char intrstr[128];
bus_addr_t addr;
bus_size_t size;
u_int max_bits;
int error;
void *ih;
sc->sc_dev = self;
sc->sc_phandle = phandle;
sc->sc_bst = faa->faa_bst;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0 ||
bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh_raw) != 0) {
aprint_error(": couldn't map RAW register\n");
return;
}
if (fdtbus_get_reg(phandle, 1, &addr, &size) != 0 ||
bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh_en) != 0) {
aprint_error(": couldn't map EN register\n");
return;
}
if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
aprint_error(": failed to decode interrupt\n");
return;
}
if (of_getprop_uint32(phandle, "cavium,max-bits", &max_bits) != 0) {
aprint_error(": missing 'cavium,max-bits' property\n");
return;
}
if (max_bits == 0 || max_bits > 64) {
aprint_error(": 'cavium,max-bits' value out of range\n");
return;
}
sc->sc_intr = kmem_zalloc(sizeof(*sc->sc_intr) * max_bits, KM_SLEEP);
sc->sc_nintr = max_bits;
error = fdtbus_register_interrupt_controller(self, phandle,
&octeon_cib_funcs);
if (error != 0) {
aprint_error(": couldn't register with fdtbus: %d\n", error);
return;
}
aprint_naive("\n");
aprint_normal(": CIB\n");
CIB_WRITE_EN(sc, 0);
CIB_WRITE_RAW(sc, ~0ULL);
ih = fdtbus_intr_establish(phandle, 0, IPL_SCHED, FDT_INTR_MPSAFE,
octeon_cib_intr, sc);
if (ih == NULL) {
aprint_error_dev(self, "couldn't establish interrupt on %s\n",
intrstr);
return;
}
aprint_normal_dev(self, "interrupting on %s\n", intrstr);
}
static void *
octeon_cib_establish(device_t dev, u_int *specifier, int ipl, int flags,
int (*func)(void *), void *arg)
{
struct octeon_cib_softc * const sc = device_private(dev);
struct octeon_cib_intr *ih;
uint64_t val;
/* 1st cell is the bit number in the CIB* registers */
/* 2nd cell is the triggering setting */
const int bit = be32toh(specifier[0]);
const int type = (be32toh(specifier[1]) & 0x3) ? IST_EDGE : IST_LEVEL;
if (bit > sc->sc_nintr) {
aprint_error_dev(dev, "bit %d out of range\n", bit);
return NULL;
}
ih = &sc->sc_intr[bit];
ih->ih_mpsafe = (flags & FDT_INTR_MPSAFE) != 0;
ih->ih_type = type;
ih->ih_func = func;
ih->ih_arg = arg;
ih->ih_mask = __BIT(bit);
val = CIB_READ_EN(sc);
val |= ih->ih_mask;
CIB_WRITE_EN(sc, val);
return ih;
}
static void
octeon_cib_disestablish(device_t dev, void *ih_cookie)
{
struct octeon_cib_softc * const sc = device_private(dev);
struct octeon_cib_intr *ih = ih_cookie;
uint64_t val;
val = CIB_READ_EN(sc);
val &= ~ih->ih_mask;
CIB_WRITE_EN(sc, val);
}
static bool
octeon_cib_intrstr(device_t dev, u_int *specifier, char *buf,
size_t buflen)
{
/* 1st cell is the bit number in the CIB* registers */
const int bit = be32toh(specifier[0]);
snprintf(buf, buflen, "%s intr %d", device_xname(dev), bit);
return true;
}
static int
octeon_cib_intr(void *priv)
{
struct octeon_cib_softc * const sc = priv;
struct octeon_cib_intr *ih;
uint64_t pend;
int n, rv = 0;
pend = CIB_READ_RAW(sc);
pend &= CIB_READ_EN(sc);
while ((n = ffs64(pend)) != 0) {
ih = &sc->sc_intr[n - 1];
KASSERT(ih->ih_mask == __BIT(n - 1));
if (ih->ih_type == IST_EDGE)
CIB_WRITE_RAW(sc, ih->ih_mask); /* ack */
#ifdef MULTIPROCESSOR
if (!ih->ih_mpsafe) {
KERNEL_LOCK(1, NULL);
rv |= ih->ih_func(ih->ih_arg);
KERNEL_UNLOCK_ONE(NULL);
} else
#endif
rv |= ih->ih_func(ih->ih_arg);
pend &= ~ih->ih_mask;
}
return rv;
}
--- src/sys/arch/mips/conf/files.octeon 2020/07/16 11:49:38 1.10
+++ src/sys/arch/mips/conf/files.octeon 2020/07/16 18:39:19 1.11
| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | # $NetBSD: files.octeon,v 1.10 2020/07/16 11:49:38 jmcneill Exp $ | | 1 | # $NetBSD: files.octeon,v 1.11 2020/07/16 18:39:19 jmcneill Exp $ |
2 | | | 2 | |
3 | file arch/mips/mips/locore_octeon.S | | 3 | file arch/mips/mips/locore_octeon.S |
4 | file arch/mips/mips/bus_dma.c | | 4 | file arch/mips/mips/bus_dma.c |
5 | file arch/mips/mips/mips3_clock.c | | 5 | file arch/mips/mips/mips3_clock.c |
6 | file arch/mips/mips/mips3_clockintr.c | | 6 | file arch/mips/mips/mips3_clockintr.c |
7 | | | 7 | |
8 | file arch/mips/cavium/octeon_dma.c | | 8 | file arch/mips/cavium/octeon_dma.c |
9 | file arch/mips/cavium/octeon_intr.c | | 9 | file arch/mips/cavium/octeon_intr.c |
10 | file arch/mips/cavium/octeon_misc.c | | 10 | file arch/mips/cavium/octeon_misc.c |
11 | | | 11 | |
12 | file arch/mips/fdt/fdt_dma_machdep.c | | 12 | file arch/mips/fdt/fdt_dma_machdep.c |
13 | | | 13 | |
14 | device mainbus {}: fdt | | 14 | device mainbus {}: fdt |
| @@ -22,26 +22,30 @@ attach cpunode at mainbus | | | @@ -22,26 +22,30 @@ attach cpunode at mainbus |
22 | device cpu {} | | 22 | device cpu {} |
23 | attach cpu at cpunode with cpu_cpunode | | 23 | attach cpu at cpunode with cpu_cpunode |
24 | | | 24 | |
25 | device wdog: sysmon_wdog | | 25 | device wdog: sysmon_wdog |
26 | attach wdog at cpunode with wdog_cpunode | | 26 | attach wdog at cpunode with wdog_cpunode |
27 | | | 27 | |
28 | file arch/mips/cavium/octeon_cpunode.c cpunode | cpu | wdog needs-flag | | 28 | file arch/mips/cavium/octeon_cpunode.c cpunode | cpu | wdog needs-flag |
29 | | | 29 | |
30 | # FDT | | 30 | # FDT |
31 | device octintc | | 31 | device octintc |
32 | attach octintc at fdt | | 32 | attach octintc at fdt |
33 | file arch/mips/cavium/dev/octeon_intc.c octintc | | 33 | file arch/mips/cavium/dev/octeon_intc.c octintc |
34 | | | 34 | |
| | | 35 | device octcib |
| | | 36 | attach octcib at fdt |
| | | 37 | file arch/mips/cavium/dev/octeon_cib.c octcib |
| | | 38 | |
35 | # I/O Bus | | 39 | # I/O Bus |
36 | | | 40 | |
37 | device iobus {} | | 41 | device iobus {} |
38 | attach iobus at mainbus | | 42 | attach iobus at mainbus |
39 | file arch/mips/cavium/octeon_iobus.c iobus | | 43 | file arch/mips/cavium/octeon_iobus.c iobus |
40 | file arch/mips/cavium/octeon1p_iobus.c iobus | | 44 | file arch/mips/cavium/octeon1p_iobus.c iobus |
41 | file arch/mips/cavium/dev/octeon_fpa.c iobus | | 45 | file arch/mips/cavium/dev/octeon_fpa.c iobus |
42 | file arch/mips/cavium/dev/octeon_pow.c iobus | | 46 | file arch/mips/cavium/dev/octeon_pow.c iobus |
43 | file arch/mips/cavium/dev/octeon_fau.c iobus | | 47 | file arch/mips/cavium/dev/octeon_fau.c iobus |
44 | file arch/mips/cavium/dev/octeon_ipd.c iobus | | 48 | file arch/mips/cavium/dev/octeon_ipd.c iobus |
45 | file arch/mips/cavium/dev/octeon_pko.c iobus | | 49 | file arch/mips/cavium/dev/octeon_pko.c iobus |
46 | file arch/mips/cavium/dev/octeon_asx.c iobus | | 50 | file arch/mips/cavium/dev/octeon_asx.c iobus |
47 | | | 51 | |
| @@ -54,30 +58,26 @@ options COM_REGMAP | | | @@ -54,30 +58,26 @@ options COM_REGMAP |
54 | device octrnm | | 58 | device octrnm |
55 | attach octrnm at iobus | | 59 | attach octrnm at iobus |
56 | file arch/mips/cavium/dev/octeon_rnm.c octrnm & rnd | | 60 | file arch/mips/cavium/dev/octeon_rnm.c octrnm & rnd |
57 | | | 61 | |
58 | device octtwsi: i2cbus | | 62 | device octtwsi: i2cbus |
59 | attach octtwsi at iobus | | 63 | attach octtwsi at iobus |
60 | file arch/mips/cavium/dev/octeon_twsi.c octtwsi | | 64 | file arch/mips/cavium/dev/octeon_twsi.c octtwsi |
61 | | | 65 | |
62 | # XXX rename to octspi? | | 66 | # XXX rename to octspi? |
63 | device octmpi: spibus | | 67 | device octmpi: spibus |
64 | attach octmpi at iobus | | 68 | attach octmpi at iobus |
65 | file arch/mips/cavium/dev/octeon_mpi.c octmpi | | 69 | file arch/mips/cavium/dev/octeon_mpi.c octmpi |
66 | | | 70 | |
67 | device octcib {} | | | |
68 | attach octcib at iobus | | | |
69 | file arch/mips/cavium/dev/octeon_cib.c octcib | | | |
70 | | | | |
71 | device octcit {} | | 71 | device octcit {} |
72 | attach octcit at iobus | | 72 | attach octcit at iobus |
73 | file arch/mips/cavium/dev/octeon_cit.c octcit | | 73 | file arch/mips/cavium/dev/octeon_cit.c octcit |
74 | | | 74 | |
75 | device octciu {} | | 75 | device octciu {} |
76 | attach octciu at iobus | | 76 | attach octciu at iobus |
77 | file arch/mips/cavium/dev/octeon_ciu.c octciu | | 77 | file arch/mips/cavium/dev/octeon_ciu.c octciu |
78 | | | 78 | |
79 | device octsmi {} | | 79 | device octsmi {} |
80 | attach octsmi at iobus with octsmi_iobus | | 80 | attach octsmi at iobus with octsmi_iobus |
81 | attach octsmi at fdt with octsmi_fdt | | 81 | attach octsmi at fdt with octsmi_fdt |
82 | file arch/mips/cavium/dev/octeon_smi.c octsmi_iobus | octsmi_fdt | | 82 | file arch/mips/cavium/dev/octeon_smi.c octsmi_iobus | octsmi_fdt |
83 | | | 83 | |