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",