Author: manu
Date: Mon Sep  5 21:11:27 2016
New Revision: 305440
URL: https://svnweb.freebsd.org/changeset/base/305440

Log:
  MFC r303087
  
  Add support for the SID (Security ID Module) on Allwinner A10 and A20.
  The rootkey is burnt at production and can't be changed, thus is can be used
  as a device unique ID or to generate a MAC address (This is was u-boot does).
  The rootkey is exposed as a sysctl (dev.aw_sid.<unit>.rootkey).
  
  Reviewed by:  jmcneill
  Differential Revision:        https://reviews.freebsd.org/D6383

Modified:
  stable/11/sys/arm/allwinner/aw_sid.c
  stable/11/sys/arm/allwinner/aw_sid.h
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/arm/allwinner/aw_sid.c
==============================================================================
--- stable/11/sys/arm/allwinner/aw_sid.c        Mon Sep  5 20:46:45 2016        
(r305439)
+++ stable/11/sys/arm/allwinner/aw_sid.c        Mon Sep  5 21:11:27 2016        
(r305440)
@@ -33,12 +33,14 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include <sys/endian.h>
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
 #include <sys/rman.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
+#include <sys/sysctl.h>
 #include <machine/bus.h>
 
 #include <dev/ofw/ofw_bus.h>
@@ -50,13 +52,22 @@ __FBSDID("$FreeBSD$");
 #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 }
 };
 
 struct aw_sid_softc {
        struct resource         *res;
+       int type;
 };
 
 static struct aw_sid_softc *aw_sid_sc;
@@ -66,9 +77,18 @@ static struct resource_spec aw_sid_spec[
        { -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,19 @@ aw_sid_attach(device_t dev)
 
        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);
 }
 
@@ -107,6 +140,8 @@ aw_sid_read_tscalib(uint32_t *calib0, ui
        sc = aw_sid_sc;
        if (sc == NULL)
                return (ENXIO);
+       if (sc->type != A83T_SID)
+               return (ENXIO);
 
        *calib0 = RD4(sc, SID_THERMAL_CALIB0);
        *calib1 = RD4(sc, SID_THERMAL_CALIB1);
@@ -114,6 +149,45 @@ aw_sid_read_tscalib(uint32_t *calib0, ui
        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[] = {
        /* Device interface */
        DEVMETHOD(device_probe,         aw_sid_probe),

Modified: stable/11/sys/arm/allwinner/aw_sid.h
==============================================================================
--- stable/11/sys/arm/allwinner/aw_sid.h        Mon Sep  5 20:46:45 2016        
(r305439)
+++ stable/11/sys/arm/allwinner/aw_sid.h        Mon Sep  5 21:11:27 2016        
(r305440)
@@ -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__ */
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to