Index: sys/arm/allwinner/aw_sid.h =================================================================== --- sys/arm/allwinner/aw_sid.h +++ sys/arm/allwinner/aw_sid.h @@ -30,5 +30,6 @@ #define __AW_SID_H__ int aw_sid_read_tscalib(uint32_t *, uint32_t *); +int aw_sid_get_rootkey(u_char *out); #endif /* !__AW_SID_H__ */ Index: sys/arm/allwinner/aw_sid.c =================================================================== --- sys/arm/allwinner/aw_sid.c +++ sys/arm/allwinner/aw_sid.c @@ -33,25 +33,36 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include #include #include #include +#include #include #include #include +#include #include #define SID_SRAM 0x200 #define SID_THERMAL_CALIB0 (SID_SRAM + 0x34) #define SID_THERMAL_CALIB1 (SID_SRAM + 0x38) +enum sid_type { + A10_SID = 1, + A20_SID, + A83T_SID, +}; + 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 } }; @@ -66,9 +77,18 @@ { -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 WR4(sc, reg, val) bus_write_4((sc)->res, (reg), (val)) +static int aw_sid_sysctl(SYSCTL_HANDLER_ARGS); + static int aw_sid_probe(device_t dev) { @@ -96,6 +116,18 @@ aw_sid_sc = sc; + switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { + 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); } @@ -114,6 +146,47 @@ 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); + + 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), + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + rootkey[0], rootkey[1], rootkey[2], rootkey[3], + rootkey[4], rootkey[5], rootkey[6], rootkey[7], + rootkey[8], rootkey[9], rootkey[10], rootkey[11], + rootkey[12], rootkey[13], rootkey[14], rootkey[15]); + + return sysctl_handle_string(oidp, out, sizeof(out), req); +} + static device_method_t aw_sid_methods[] = { /* Device interface */ DEVMETHOD(device_probe, aw_sid_probe),