diff --git a/share/man/man4/aw_sid.4 b/share/man/man4/aw_sid.4 index 1ac6c62fcc65..7a55f4168f2f 100644 --- a/share/man/man4/aw_sid.4 +++ b/share/man/man4/aw_sid.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 2, 2018 +.Dd January 6, 2018 .Dt AW_SID 4 .Os .Sh NAME @@ -52,6 +52,8 @@ allwinner,sun7i-a20-sid allwinner,sun50i-a64-sid .It allwinner,sun8i-a83t-sid +.It +allwinner,sun8i-h3-sid .El .Sh SYSCTL VARIABLES The following read-only variables are available via diff --git a/sys/arm/allwinner/aw_sid.c b/sys/arm/allwinner/aw_sid.c index 6bae8e6d55a7..8943818f525a 100644 --- a/sys/arm/allwinner/aw_sid.c +++ b/sys/arm/allwinner/aw_sid.c @@ -67,36 +67,51 @@ __FBSDID("$FreeBSD$"); #define ROOT_KEY_SIZE 4 struct aw_sid_conf { + bus_size_t efuse_size; bus_size_t rootkey_offset; bool has_prctl; bool has_thermal; + bool requires_prctl_read; }; static const struct aw_sid_conf a10_conf = { + .efuse_size = 0x10, .rootkey_offset = 0, }; static const struct aw_sid_conf a20_conf = { + .efuse_size = 0x10, .rootkey_offset = 0, }; static const struct aw_sid_conf a64_conf = { + .efuse_size = 0x100, .rootkey_offset = SID_SRAM, .has_prctl = true, .has_thermal = true, }; static const struct aw_sid_conf a83t_conf = { + .efuse_size = 0x100, .rootkey_offset = SID_SRAM, .has_prctl = true, .has_thermal = true, }; +static const struct aw_sid_conf h3_conf = { + .efuse_size = 0x100, + .rootkey_offset = SID_SRAM, + .has_prctl = true, + .has_thermal = true, + .requires_prctl_read = true, +}; + static struct ofw_compat_data compat_data[] = { { "allwinner,sun4i-a10-sid", (uintptr_t)&a10_conf}, { "allwinner,sun7i-a20-sid", (uintptr_t)&a20_conf}, { "allwinner,sun50i-a64-sid", (uintptr_t)&a64_conf}, { "allwinner,sun8i-a83t-sid", (uintptr_t)&a83t_conf}, + { "allwinner,sun8i-h3-sid", (uintptr_t)&h3_conf}, { NULL, 0 } }; @@ -168,6 +183,8 @@ static int aw_sid_attach(device_t dev) { struct aw_sid_softc *sc; + bus_size_t i; + uint32_t val; sc = device_get_softc(dev); @@ -180,6 +197,19 @@ aw_sid_attach(device_t dev) sc->sid_conf = (struct aw_sid_conf *)ofw_bus_search_compatible(dev, compat_data)->ocd_data; aw_sid_sc = sc; + /* + * This set of reads is solely for working around a silicon bug on some + * SoC that require a prctl read in order for direct register access to + * return a non-garbled value. Hence, the values we read are simply + * ignored. + */ + if (sc->sid_conf->requires_prctl_read) + for (i = 0; i < sc->sid_conf->efuse_size; i += 4) + if (aw_sid_prctl_read(dev, i, &val) != 0) { + device_printf(dev, "failed prctl read\n"); + return (ENXIO); + } + SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "rootkey",