Changeset View
Changeset View
Standalone View
Standalone View
head/sys/arm/allwinner/aw_sid.c
Show All 27 Lines | |||||
/* | /* | ||||
* Allwinner secure ID controller | * Allwinner secure ID controller | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/endian.h> | |||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/bus.h> | #include <sys/bus.h> | ||||
#include <sys/rman.h> | #include <sys/rman.h> | ||||
#include <sys/kernel.h> | #include <sys/kernel.h> | ||||
#include <sys/module.h> | #include <sys/module.h> | ||||
#include <sys/sysctl.h> | |||||
#include <machine/bus.h> | #include <machine/bus.h> | ||||
#include <dev/ofw/ofw_bus.h> | #include <dev/ofw/ofw_bus.h> | ||||
#include <dev/ofw/ofw_bus_subr.h> | #include <dev/ofw/ofw_bus_subr.h> | ||||
#include <arm/allwinner/aw_sid.h> | #include <arm/allwinner/aw_sid.h> | ||||
#define SID_SRAM 0x200 | #define SID_SRAM 0x200 | ||||
#define SID_THERMAL_CALIB0 (SID_SRAM + 0x34) | #define SID_THERMAL_CALIB0 (SID_SRAM + 0x34) | ||||
#define SID_THERMAL_CALIB1 (SID_SRAM + 0x38) | #define SID_THERMAL_CALIB1 (SID_SRAM + 0x38) | ||||
enum sid_type { | |||||
A10_SID = 1, | |||||
A20_SID, | |||||
A83T_SID, | |||||
}; | |||||
static struct ofw_compat_data compat_data[] = { | static struct ofw_compat_data compat_data[] = { | ||||
{ "allwinner,sun8i-a83t-sid", 1 }, | { "allwinner,sun4i-a10-sid", A10_SID}, | ||||
{ "allwinner,sun7i-a20-sid", A20_SID}, | |||||
{ "allwinner,sun8i-a83t-sid", A83T_SID}, | |||||
{ NULL, 0 } | { NULL, 0 } | ||||
}; | }; | ||||
struct aw_sid_softc { | struct aw_sid_softc { | ||||
struct resource *res; | struct resource *res; | ||||
int type; | |||||
}; | }; | ||||
static struct aw_sid_softc *aw_sid_sc; | static struct aw_sid_softc *aw_sid_sc; | ||||
static struct resource_spec aw_sid_spec[] = { | static struct resource_spec aw_sid_spec[] = { | ||||
{ SYS_RES_MEMORY, 0, RF_ACTIVE }, | { SYS_RES_MEMORY, 0, RF_ACTIVE }, | ||||
{ -1, 0 } | { -1, 0 } | ||||
}; | }; | ||||
enum sid_keys { | |||||
AW_SID_ROOT_KEY, | |||||
}; | |||||
#define ROOT_KEY_OFF 0x0 | |||||
#define ROOT_KEY_SIZE 4 | |||||
#define RD4(sc, reg) bus_read_4((sc)->res, (reg)) | #define RD4(sc, reg) bus_read_4((sc)->res, (reg)) | ||||
#define WR4(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) | #define WR4(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) | ||||
static int aw_sid_sysctl(SYSCTL_HANDLER_ARGS); | |||||
static int | static int | ||||
aw_sid_probe(device_t dev) | aw_sid_probe(device_t dev) | ||||
{ | { | ||||
if (!ofw_bus_status_okay(dev)) | if (!ofw_bus_status_okay(dev)) | ||||
return (ENXIO); | return (ENXIO); | ||||
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) | if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) | ||||
return (ENXIO); | return (ENXIO); | ||||
Show All 11 Lines | aw_sid_attach(device_t dev) | ||||
if (bus_alloc_resources(dev, aw_sid_spec, &sc->res) != 0) { | if (bus_alloc_resources(dev, aw_sid_spec, &sc->res) != 0) { | ||||
device_printf(dev, "cannot allocate resources for device\n"); | device_printf(dev, "cannot allocate resources for device\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | } | ||||
aw_sid_sc = sc; | aw_sid_sc = sc; | ||||
sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data; | |||||
switch (sc->type) { | |||||
case A10_SID: | |||||
case A20_SID: | |||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), | |||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), | |||||
OID_AUTO, "rootkey", | |||||
CTLTYPE_STRING | CTLFLAG_RD, | |||||
dev, AW_SID_ROOT_KEY, aw_sid_sysctl, "A", "Root Key"); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
aw_sid_read_tscalib(uint32_t *calib0, uint32_t *calib1) | aw_sid_read_tscalib(uint32_t *calib0, uint32_t *calib1) | ||||
{ | { | ||||
struct aw_sid_softc *sc; | struct aw_sid_softc *sc; | ||||
sc = aw_sid_sc; | sc = aw_sid_sc; | ||||
if (sc == NULL) | if (sc == NULL) | ||||
return (ENXIO); | return (ENXIO); | ||||
if (sc->type != A83T_SID) | |||||
return (ENXIO); | |||||
*calib0 = RD4(sc, SID_THERMAL_CALIB0); | *calib0 = RD4(sc, SID_THERMAL_CALIB0); | ||||
*calib1 = RD4(sc, SID_THERMAL_CALIB1); | *calib1 = RD4(sc, SID_THERMAL_CALIB1); | ||||
return (0); | return (0); | ||||
} | |||||
int | |||||
aw_sid_get_rootkey(u_char *out) | |||||
{ | |||||
struct aw_sid_softc *sc; | |||||
int i; | |||||
u_int tmp; | |||||
sc = aw_sid_sc; | |||||
if (sc == NULL) | |||||
return (ENXIO); | |||||
if (sc->type != A10_SID && sc->type != A20_SID) | |||||
return (ENXIO); | |||||
for (i = 0; i < ROOT_KEY_SIZE ; i++) { | |||||
tmp = RD4(aw_sid_sc, ROOT_KEY_OFF + (i * 4)); | |||||
be32enc(&out[i * 4], tmp); | |||||
} | |||||
return (0); | |||||
} | |||||
static int | |||||
aw_sid_sysctl(SYSCTL_HANDLER_ARGS) | |||||
{ | |||||
enum sid_keys key = arg2; | |||||
u_char rootkey[16]; | |||||
char out[33]; | |||||
if (key != AW_SID_ROOT_KEY) | |||||
return (ENOENT); | |||||
if (aw_sid_get_rootkey(rootkey) != 0) | |||||
return (ENOENT); | |||||
snprintf(out, sizeof(out), | |||||
"%16D", rootkey, ""); | |||||
return sysctl_handle_string(oidp, out, sizeof(out), req); | |||||
} | } | ||||
static device_method_t aw_sid_methods[] = { | static device_method_t aw_sid_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_probe, aw_sid_probe), | DEVMETHOD(device_probe, aw_sid_probe), | ||||
DEVMETHOD(device_attach, aw_sid_attach), | DEVMETHOD(device_attach, aw_sid_attach), | ||||
DEVMETHOD_END | DEVMETHOD_END | ||||
Show All 13 Lines |