? sys/arch/evbarm/conf/BLA
? sys/arch/evbarm/conf/EGGHED
? sys/arch/evbarm/conf/EGGHED64
? sys/arch/evbarm/conf/HOPPA
? sys/arch/evbarm/conf/JOWLSON
? sys/arch/evbarm/conf/TWITTY
? sys/arch/evbarm/rpi/pitfthat.c
? sys/arch/evbarm/rpi/rpi_machdep.c.DELETEDBYIDIOT
? sys/arch/evbarm/rpi/rpi_machdep.c.ORIG
? sys/arch/evbarm/rpi/unicornhat.c
? sys/dev/sdmmc/ChangeLog
Index: sys/arch/arm/arm32/arm32_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm32/arm32_machdep.c,v
retrieving revision 1.128
diff -p -u -r1.128 arm32_machdep.c
--- sys/arch/arm/arm32/arm32_machdep.c  10 May 2019 16:43:09 -0000      1.128
+++ sys/arch/arm/arm32/arm32_machdep.c  27 Jul 2019 13:09:18 -0000
@@ -729,7 +729,9 @@ cpu_init_secondary_processor(int cpuinde
       // pmap_kernel has been sucessfully built and we can switch to it

       cpu_domains(DOMAIN_DEFAULT);
+#if 0
       cpu_idcache_wbinv_all();
+#endif

       VPRINTS("index: ");
       VPRINTX(cpuindex);
@@ -754,7 +756,11 @@ cpu_init_secondary_processor(int cpuinde
       cpu_setttb(pmap_kernel()->pm_l1->l1_physaddr, true);
#endif

+#if 0
       cpu_tlb_flushID();
+#else
+       armv7up_tlb_flushID();
+#endif

       VPRINTS(" (TTBR0=");
       VPRINTX(armreg_ttbr_read());
Index: sys/arch/arm/broadcom/bcm2835_cm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_cm.c,v
retrieving revision 1.2
diff -p -u -r1.2 bcm2835_cm.c
--- sys/arch/arm/broadcom/bcm2835_cm.c  10 Dec 2017 21:38:26 -0000      1.2
+++ sys/arch/arm/broadcom/bcm2835_cm.c  27 Jul 2019 13:09:18 -0000
@@ -118,14 +118,15 @@ bcmcm_wait(struct bcm2835cm_softc *sc, i
       int i;
       uint32_t r;

-       for (i=0; i<100; ++i) {
+       for (i=0; i<1000; ++i) {
               r = CM_READ(sc, ctlreg);
               if (((r & CM_CTL_BUSY) != 0) == onoff)
                       break;
               delay(10);
       }
-       if (i >= 100) {
-               device_printf(sc->sc_dev, "busy (addr=%#x)\n", ctlreg);
+       if (i >= 1000) {
+               device_printf(sc->sc_dev, "%s (addr=%#x)\n",
+                       onoff ? "stopped" : "busy", ctlreg);
               return EIO;
       }

@@ -187,7 +188,8 @@ bcm_cm_set(enum bcm_cm_clock clk, uint32
               CM_WRITE(sc, ctlreg, r);
       }

-       bcmcm_wait(sc, ctlreg, 0);
+       if (bcmcm_wait(sc, ctlreg, 0))
+               return EIO;

       /* configure new divider, mode, don't enable */
       CM_WRITE(sc, divreg, div);
Index: sys/arch/arm/broadcom/bcm2835_cm.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_cm.h,v
retrieving revision 1.2
diff -p -u -r1.2 bcm2835_cm.h
--- sys/arch/arm/broadcom/bcm2835_cm.h  19 Oct 2017 05:45:37 -0000      1.2
+++ sys/arch/arm/broadcom/bcm2835_cm.h  27 Jul 2019 13:09:18 -0000
@@ -34,6 +34,7 @@
#define  CM_CTL_MASH           __BITS(9,10)
#define  CM_CTL_FLIP           __BIT(8)
#define  CM_CTL_BUSY           __BIT(7)
+#define  CM_CTL_GATE          __BIT(6)
#define  CM_CTL_KILL           __BIT(5)
#define  CM_CTL_ENAB           __BIT(4)
#define  CM_CTL_SRC            __BIT(0,3)
@@ -51,6 +52,16 @@
#define CM_PWMCTL              0xa0
#define CM_PWMDIV              0xa4

+#define A2W_XOSC_CTRL         0x1190
+#define  A2W_XOSC_CTRL_PLLB   __BIT(7)
+#define  A2W_XOSC_CTRL_PLLA   __BIT(6)
+#define  A2W_XOSC_CTRL_PLLD   __BIT(5)
+#define  A2W_XOSC_CTRL_DDR    __BIT(4)
+#define  A2W_XOSC_CTRL_CPR1   __BIT(3)
+#define  A2W_XOSC_CTRL_USB    __BIT(2)
+#define  A2W_XOSC_CTRL_HDMI   __BIT(1)
+#define  A2W_XOSC_CTRL_PLLC   __BIT(0)
+
#define CM_PASSWD              0x5a

/* clock sources (frequencies for RPI) */
@@ -62,6 +73,8 @@
#define CM_CTL_SRC_PLLC                5       /* 1000MHz (changes with overclock) */
#define CM_CTL_SRC_PLLD                6       /* 500MHz core clock */
#define CM_CTL_SRC_HDMIAUX     7       /* 216MHz HDMI auxiliary */
+#define CM_CTL_SRC_CORE1      8
+#define CM_CTL_SRC_CORE2      9

#if 0
#define CM_GNRICCTL            0x00
@@ -142,6 +155,8 @@
#define CM_OSCCOUNT            0x100
#define CM_PLLA                        0x104
#define CM_PLLB                        0x170
+#define  CM_PLLB_HOLDARM      __BIT(1)
+#define  CM_PLLB_LOADARM      __BIT(0)
#define CM_PLLC                        0x108
#define CM_PLLD                        0x10c
#define CM_PLLH                        0x110
@@ -161,6 +176,56 @@
#define CM_BURSTCTL            0x148
#define CM_BURSTCNT            0x14C

+#define A2W_PLLA_CTRL         0x1100
+#define A2W_PLLC_CTRL         0x1120
+#define A2W_PLLD_CTRL         0x1140
+#define A2W_PLLH_CTRL         0x1160
+#define A2W_PLLB_CTRL         0x11e0
+
+#define A2W_PLLA_ANA0         0x1010
+#define A2W_PLLC_ANA0         0x1030
+#define A2W_PLLD_ANA0         0x1050
+#define A2W_PLLH_ANA0         0x1070
+#define A2W_PLLB_ANA0         0x10f0
+
+#define A2W_PLLA_FRAC         0x1200
+#define A2W_PLLC_FRAC         0x1220
+#define A2W_PLLD_FRAC         0x1240
+#define A2W_PLLH_FRAC         0x1260
+#define A2W_PLLB_FRAC         0x12e0
+
+#define A2W_PLLA_DSI0         0x1300
+#define A2W_PLLA_CORE         0x1400
+#define A2W_PLLA_PER          0x1500
+#define A2W_PLLA_CCP2         0x1600
+
+#define A2W_PLLC_CORE2                0x1320
+#define A2W_PLLC_CORE1                0x1420
+#define A2W_PLLC_PER          0x1520
+#define A2W_PLLC_CORE0                0x1620
+
+#define A2W_PLLD_DSI0         0x1340
+#define A2W_PLLD_CORE         0x1440
+#define A2W_PLLD_PER          0x1540
+#define A2W_PLLD_DSI1         0x1640
+
+#define A2W_PLLH_AUX          0x1360
+#define A2W_PLLH_RCAL         0x1460
+#define A2W_PLLH_PIX          0x1560
+#define A2W_PLLH_STS          0x1660
+
+#define A2W_PLLH_CTRLR                0x1960
+#define A2W_PLLH_FRACR                0x1a60
+#define A2W_PLLH_AUXR         0x1b60
+#define A2W_PLLH_RCALR                0x1c60
+#define A2W_PLLH_PIXR         0x1d60
+#define A2W_PLLH_STSR         0x1e60
+
+#define A2W_PLLB_ARM          0x13e0
+#define A2W_PLLB_SP0          0x14e0
+#define A2W_PLLB_SP1          0x15e0
+#define A2W_PLLB_SP2          0x16e0
+
#endif

enum bcm_cm_clock {
Index: sys/arch/arm/broadcom/bcm2835_cprman.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_cprman.c,v
retrieving revision 1.2
diff -p -u -r1.2 bcm2835_cprman.c
--- sys/arch/arm/broadcom/bcm2835_cprman.c      9 Sep 2018 07:21:17 -0000       1.2
+++ sys/arch/arm/broadcom/bcm2835_cprman.c      27 Jul 2019 13:09:18 -0000
@@ -56,6 +56,7 @@ enum {
       CPRMAN_CLOCK_PERIIMAGE = 29,
       CPRMAN_CLOCK_PWM = 30,
       CPRMAN_CLOCK_PCM = 31,
+       CPRMAN_CLOCK_EMMC2 = 51,
       CPRMAN_NCLOCK
};

@@ -133,6 +134,8 @@ cprman_get_rate(void *priv, struct clk *
               return bcm283x_clk_get_rate_vpu();
       case CPRMAN_CLOCK_EMMC:
               return bcm283x_clk_get_rate_emmc();
+       case CPRMAN_CLOCK_EMMC2:
+               return bcm283x_clk_get_rate_emmc2();
       default:
               panic("unsupported clock id %d\n", clk->id);
       }
@@ -155,7 +158,11 @@ cprman_add_clock(struct cprman_softc *sc
static int
cprman_match(device_t parent, cfdata_t cf, void *aux)
{
-       const char * const compatible[] = { "brcm,bcm2835-cprman", NULL };
+       const char * const compatible[] = {
+               "brcm,bcm2835-cprman",
+               "brcm,bcm2838-cprman",
+               NULL
+       };
       const struct fdt_attach_args *faa = aux;

       return of_match_compatible(faa->faa_phandle, compatible);
@@ -176,6 +183,7 @@ cprman_attach(device_t parent, device_t
       cprman_add_clock(sc, CPRMAN_CLOCK_UART, "uart");
       cprman_add_clock(sc, CPRMAN_CLOCK_VPU, "vpu");
       cprman_add_clock(sc, CPRMAN_CLOCK_EMMC, "emmc");
+       cprman_add_clock(sc, CPRMAN_CLOCK_EMMC2, "emmc2");

       aprint_naive("\n");
       aprint_normal(": BCM283x Clock Controller\n");
Index: sys/arch/arm/broadcom/bcm2835_dmac.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_dmac.c,v
retrieving revision 1.16
diff -p -u -r1.16 bcm2835_dmac.c
--- sys/arch/arm/broadcom/bcm2835_dmac.c        10 Dec 2017 21:38:26 -0000      1.16
+++ sys/arch/arm/broadcom/bcm2835_dmac.c        27 Jul 2019 13:09:18 -0000
@@ -48,7 +48,10 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_dmac

#include <arm/fdt/arm_fdtvar.h>

-#define BCM_DMAC_CHANNELMASK   0x00000fff
+#include "ioconf.h"
+
+#define BCM_DMAC_NCHANNELS     12
+#define BCM_DMAC_CHANNELMASK   __BITS(BCM_DMAC_NCHANNELS-1,0)

struct bcm_dmac_softc;

@@ -77,6 +80,7 @@ struct bcm_dmac_softc {
       struct bcm_dmac_channel *sc_channels;
       int sc_nchannels;
       uint32_t sc_channelmask;
+       int sc_first;
};

#define DMAC_READ(sc, reg)             \
@@ -101,6 +105,7 @@ bcm_dmac_match(device_t parent, cfdata_t
{
       const char * const compatible[] = {
               "brcm,bcm2835-dma",
+               "brcm,bcm2838-dma",
               NULL
       };
       struct fdt_attach_args * const faa = aux;
@@ -137,12 +142,33 @@ bcm_dmac_attach(device_t parent, device_
               return;
       }

+
+       /*
+        * Get combined channel mask from mailbox interface, we
+        * assume that there are two DMA controllers and
+        * brcm,bcm2838-dma is the second.
+        *
+        * The masks are also provided (one per DMA controller)
+        * by fdt property brcm,dma-channel-mask
+        */
+        const char * const second_dmac[] = { "brcm,bcm2838-dma", NULL };
+        if (of_match_compatible(faa->faa_phandle, second_dmac))
+               sc->sc_first = BCM_DMAC_NCHANNELS;
       prop_dictionary_get_uint32(cfg, "chanmask", &sc->sc_channelmask);
+printf(": chanmask=%x", sc->sc_channelmask);
       sc->sc_channelmask &= BCM_DMAC_CHANNELMASK;
+       sc->sc_channelmask >>= sc->sc_first;
+printf(" shifted=%x", sc->sc_channelmask);

       mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SCHED);

-       sc->sc_nchannels = 31 - __builtin_clz(sc->sc_channelmask);
+       sc->sc_nchannels = ffs(sc->sc_channelmask);
+printf(" ffs=%u", sc->sc_nchannels);
+       if (sc->sc_nchannels == 0) {
+               aprint_error(": all channels masked\n");
+               return;
+       }
+
       sc->sc_channels = kmem_alloc(
           sizeof(*sc->sc_channels) * sc->sc_nchannels, KM_SLEEP);

@@ -157,7 +183,8 @@ bcm_dmac_attach(device_t parent, device_
               if ((__BIT(index) & sc->sc_channelmask) == 0)
                       continue;

-               aprint_normal(" DMA%d", index);
+               /* fdt has names for this */
+               aprint_normal(" DMA%d", index + sc->sc_first);

               ch->ch_debug = DMAC_READ(sc, DMAC_DEBUG(index));

@@ -197,29 +224,32 @@ bcm_dmac_alloc(enum bcm_dmac_type type,
{
       struct bcm_dmac_softc *sc;
       struct bcm_dmac_channel *ch = NULL;
-       device_t dev;
-       int index;
+       int index, unit;

-       dev = device_find_by_driver_unit("bcmdmac", 0);
-       if (dev == NULL)
-               return NULL;
-       sc = device_private(dev);
-
-       mutex_enter(&sc->sc_lock);
-       for (index = 0; index < sc->sc_nchannels; index++) {
-               if ((sc->sc_channelmask & __BIT(index)) == 0)
-                       continue;
-               if (DMAC_CHANNEL_TYPE(&sc->sc_channels[index]) != type)
-                       continue;
-               if (DMAC_CHANNEL_USED(&sc->sc_channels[index]))
+       for (unit = 0; unit < bcmdmac_cd.cd_ndevs; ++unit) {
+               sc = device_lookup_private(&bcmdmac_cd, unit);
+               if (sc == NULL)
                       continue;

-               ch = &sc->sc_channels[index];
-               ch->ch_callback = cb;
-               ch->ch_callbackarg = cbarg;
-               break;
+               mutex_enter(&sc->sc_lock);
+               for (index = 0; index < sc->sc_nchannels; index++) {
+                       if ((sc->sc_channelmask & __BIT(index)) == 0)
+                               continue;
+                       if (DMAC_CHANNEL_TYPE(&sc->sc_channels[index]) != type)
+                               continue;
+                       if (DMAC_CHANNEL_USED(&sc->sc_channels[index]))
+                               continue;
+
+                       ch = &sc->sc_channels[index];
+                       ch->ch_callback = cb;
+                       ch->ch_callbackarg = cbarg;
+                       break;
+               }
+               mutex_exit(&sc->sc_lock);
+
+               if (ch != NULL)
+                       break;
       }
-       mutex_exit(&sc->sc_lock);

       if (ch == NULL)
               return NULL;
@@ -253,9 +283,18 @@ bcm_dmac_free(struct bcm_dmac_channel *c
{
       struct bcm_dmac_softc *sc = ch->ch_sc;
       uint32_t val;
+       int i;

       bcm_dmac_halt(ch);

+       /* wait for chip to stop */
+       for (i=0; i<10000; ++i) {
+               val = DMAC_READ(sc, DMAC_CS(ch->ch_index));
+               if (!(val & DMAC_CS_ACTIVE))
+                       break;
+               DELAY(1);
+       }
+
       /* reset chip */
       val = DMAC_READ(sc, DMAC_CS(ch->ch_index));
       val |= DMAC_CS_RESET;
@@ -299,13 +338,23 @@ bcm_dmac_halt(struct bcm_dmac_channel *c
{
       struct bcm_dmac_softc *sc = ch->ch_sc;
       uint32_t val;
+       int i;

       /* pause DMA */
       val = DMAC_READ(sc, DMAC_CS(ch->ch_index));
       val &= ~DMAC_CS_ACTIVE;
       DMAC_WRITE(sc, DMAC_CS(ch->ch_index), val);

-       /* wait for paused state ? */
+       /* wait for paused state to end */
+       for (i=0; i<10000; ++i) {
+               val = DMAC_READ(sc, DMAC_CS(ch->ch_index));
+               if (!(val & DMAC_CS_PAUSED))
+                       break;
+       }
+       if (i >= 10000) {
+               device_printf(sc->sc_dev, "DMA doesn't finish\n");
+               return;
+       }

       /* end descriptor chain */
       DMAC_WRITE(sc, DMAC_NEXTCONBK(ch->ch_index), 0);
@@ -320,23 +369,26 @@ void
bcm_dmac_dump_regs(void)
{
       struct bcm_dmac_softc *sc;
-       device_t dev;
-       int index;
-
-       dev = device_find_by_driver_unit("bcmdmac", 0);
-       if (dev == NULL)
-               return;
-       sc = device_private(dev);
+       int index, unit;
+       const char *prefix;

-       for (index = 0; index < sc->sc_nchannels; index++) {
-               if ((sc->sc_channelmask & __BIT(index)) == 0)
+       for (unit = 0; unit < bcmdmac_cd.cd_ndevs; ++unit) {
+               sc = device_lookup_private(&bcmdmac_cd, unit);
+               if (sc == NULL)
                       continue;
-               printf("%d_CS:        %08X\n", index,
-                   DMAC_READ(sc, DMAC_CS(index)));
-               printf("%d_CONBLK_AD: %08X\n", index,
-                   DMAC_READ(sc, DMAC_CONBLK_AD(index)));
-               printf("%d_DEBUG:     %08X\n", index,
-                   DMAC_READ(sc, DMAC_DEBUG(index)));
+
+               for (index = 0; index < sc->sc_nchannels; index++) {
+                       if ((sc->sc_channelmask & __BIT(index)) == 0)
+                               prefix = "GPU";
+                       else
+                               prefix = "ARM";
+                       printf("%s %d_CS:        %08X\n", prefix, index,
+                           DMAC_READ(sc, DMAC_CS(index)));
+                       printf("%s %d_CONBLK_AD: %08X\n", prefix, index,
+                           DMAC_READ(sc, DMAC_CONBLK_AD(index)));
+                       printf("%s %d_DEBUG:     %08X\n", prefix, index,
+                           DMAC_READ(sc, DMAC_DEBUG(index)));
+               }
       }
}
#endif
Index: sys/arch/arm/broadcom/bcm2835_emmc.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_emmc.c,v
retrieving revision 1.33
diff -p -u -r1.33 bcm2835_emmc.c
--- sys/arch/arm/broadcom/bcm2835_emmc.c        19 Aug 2018 09:18:48 -0000      1.33
+++ sys/arch/arm/broadcom/bcm2835_emmc.c        27 Jul 2019 13:09:18 -0000
@@ -97,6 +97,7 @@ bcmemmc_match(device_t parent, struct cf
{
       const char * const compatible[] = {
           "brcm,bcm2835-sdhci",
+           "brcm,bcm2711-emmc2",
           NULL
       };
       struct fdt_attach_args * const faa = aux;
@@ -155,7 +156,6 @@ bcmemmc_attach(device_t parent, device_t
               if (i == 0)
                       sc->sc.sc_clkbase = clk_get_rate(clk) / 1000;
       }
-       aprint_debug_dev(self, "ref freq %u kHz\n", sc->sc.sc_clkbase);

       error = bus_space_map(sc->sc_iot, addr, size, 0, &sc->sc_ioh);
       if (error) {
@@ -168,6 +168,8 @@ bcmemmc_attach(device_t parent, device_t
       aprint_naive(": SDHC controller\n");
       aprint_normal(": SDHC controller\n");

+       aprint_debug_dev(self, "ref freq %u kHz\n", sc->sc.sc_clkbase);
+
       char intrstr[128];
       if (!fdtbus_intr_str(phandle, 0, intrstr, sizeof(intrstr))) {
               aprint_error(": failed to decode interrupt\n");
Index: sys/arch/arm/broadcom/bcm2835_intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_intr.c,v
retrieving revision 1.20
diff -p -u -r1.20 bcm2835_intr.c
--- sys/arch/arm/broadcom/bcm2835_intr.c        27 Mar 2019 05:47:50 -0000      1.20
+++ sys/arch/arm/broadcom/bcm2835_intr.c        27 Jul 2019 13:09:18 -0000
@@ -59,6 +59,8 @@ __KERNEL_RCSID(0, "$NetBSD: bcm2835_intr

#include <arm/fdt/arm_fdtvar.h>

+#include "ioconf.h"
+
static void bcm2835_irq_handler(void *);
static void bcm2836mp_intr_init(void *, struct cpu_info *);

@@ -170,8 +172,8 @@ struct bcm2835icu_softc {
       int sc_phandle;
};

-struct bcm2835icu_softc *bcml1icu_sc;
-struct bcm2835icu_softc *bcmicu_sc;
+static struct bcm2835icu_softc *bcml1icu_sc;
+static struct bcm2835icu_softc *bcmicu_sc;

#define read_bcm2835reg(o)     \
       bus_space_read_4(bcmicu_sc->sc_iot, bcmicu_sc->sc_ioh, (o))
@@ -277,10 +279,10 @@ bcm2835_icu_attach(device_t parent, devi
                   BCM2836_LOCAL_CONTROL, 0);
               bus_space_write_4(sc->sc_iot, sc->sc_ioh,
                   BCM2836_LOCAL_PRESCALER, 0x80000000);
-
               ifuncs = &bcm2836mpicu_fdt_funcs;
-
+#if !defined(SOC_BCM2838)
               bcm2836mp_intr_init(self, curcpu());
+#endif
               arm_fdt_cpu_hatch_register(self, bcm2836mp_intr_init);
       } else {
               if (bcml1icu_sc == NULL)
@@ -309,6 +311,8 @@ bcm2835_irq_handler(void *frame)
       const uint32_t oldipl_mask = __BIT(oldipl);
       int ipl_mask = 0;

+       KASSERT(cpuid < BCM2836_NCPUS);
+
       ci->ci_data.cpu_nintr++;

       bcm2835_barrier();
@@ -479,6 +483,7 @@ bcm2836mp_pic_unblock_irqs(struct pic_so
       const bus_space_handle_t ioh = bcml1icu_sc->sc_ioh;
       const cpuid_t cpuid = pic - &bcm2836mp_pic[0];

+       KASSERT(cpuid < BCM2836_NCPUS);
       KASSERT(irqbase == 0);

       if (irq_mask & BCM2836MP_TIMER_IRQS) {
@@ -525,6 +530,7 @@ bcm2836mp_pic_block_irqs(struct pic_soft
       const bus_space_handle_t ioh = bcml1icu_sc->sc_ioh;
       const cpuid_t cpuid = pic - &bcm2836mp_pic[0];

+       KASSERT(cpuid < BCM2836_NCPUS);
       KASSERT(irqbase == 0);

       if (irq_mask & BCM2836MP_TIMER_IRQS) {
@@ -547,7 +553,7 @@ bcm2836mp_pic_block_irqs(struct pic_soft
       }
       if (irq_mask & BCM2836MP_PMU_IRQ) {
               bus_space_write_4(iot, ioh, BCM2836_LOCAL_PM_ROUTING_CLR,
-                    __BIT(cpuid));
+                   __BIT(cpuid));
       }

       bcm2835_barrier();
@@ -562,6 +568,7 @@ bcm2836mp_pic_find_pending_irqs(struct p
       uint32_t lpending;
       int ipl = 0;

+       KASSERT(cpuid < BCM2836_NCPUS);
       KASSERT(pic == &bcm2836mp_pic[cpuid]);

       bcm2835_barrier();
@@ -598,10 +605,13 @@ bcm2836mp_pic_source_name(struct pic_sof
#if defined(MULTIPROCESSOR)
static void bcm2836mp_cpu_init(struct pic_softc *pic, struct cpu_info *ci)
{
+       const cpuid_t cpuid = ci->ci_core_id;
+
+       KASSERT(cpuid < BCM2836_NCPUS);

       /* Enable IRQ and not FIQ */
       bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
-           BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(ci->ci_core_id), 1);
+           BCM2836_LOCAL_MAILBOX_IRQ_CONTROLN(cpuid), 1);
}

static void
@@ -612,6 +622,7 @@ bcm2836mp_send_ipi(struct pic_softc *pic
       KASSERT(pic->pic_cpus != NULL);

       const cpuid_t cpuid = pic - &bcm2836mp_pic[0];
+       KASSERT(cpuid < BCM2836_NCPUS);

       bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
           BCM2836_LOCAL_MAILBOX0_SETN(cpuid), __BIT(ipi));
@@ -624,6 +635,8 @@ bcm2836mp_ipi_handler(void *priv)
       const cpuid_t cpuid = ci->ci_core_id;
       uint32_t ipimask, bit;

+       KASSERT(cpuid < BCM2836_NCPUS);
+
       ipimask = bus_space_read_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
           BCM2836_LOCAL_MAILBOX0_CLRN(cpuid));
       bus_space_write_4(bcml1icu_sc->sc_iot, bcml1icu_sc->sc_ioh,
@@ -671,6 +684,8 @@ bcm2836mp_intr_init(void *priv, struct c
       const cpuid_t cpuid = ci->ci_core_id;
       struct pic_softc * const pic = &bcm2836mp_pic[cpuid];

+       KASSERT(cpuid < BCM2836_NCPUS);
+
#if defined(MULTIPROCESSOR)
       pic->pic_cpus = ci->ci_kcpuset;

@@ -705,6 +720,7 @@ bcm2836mp_intr_init(void *priv, struct c
static int
bcm2836mp_icu_fdt_decode_irq(u_int *specifier)
{
+
       if (!specifier)
               return -1;
       return be32toh(specifier[0]);
Index: sys/arch/arm/broadcom/bcm2835_mbox.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_mbox.c,v
retrieving revision 1.13
diff -p -u -r1.13 bcm2835_mbox.c
--- sys/arch/arm/broadcom/bcm2835_mbox.c        19 Aug 2018 09:18:48 -0000      1.13
+++ sys/arch/arm/broadcom/bcm2835_mbox.c        27 Jul 2019 13:09:18 -0000
@@ -75,7 +75,11 @@ CFATTACH_DECL_NEW(bcmmbox, sizeof(struct
static int
bcmmbox_match(device_t parent, cfdata_t match, void *aux)
{
-       const char * const compatible[] = { "brcm,bcm2835-mbox", NULL };
+       const char * const compatible[] = {
+               "brcm,bcm2835-mbox",
+               "brcm,bcm2838-vchiq",
+               NULL
+       };
       struct fdt_attach_args * const faa = aux;

       return of_match_compatible(faa->faa_phandle, compatible);
Index: sys/arch/arm/broadcom/bcm2835_pwm.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_pwm.c,v
retrieving revision 1.3
diff -p -u -r1.3 bcm2835_pwm.c
--- sys/arch/arm/broadcom/bcm2835_pwm.c 10 Dec 2017 21:38:26 -0000      1.3
+++ sys/arch/arm/broadcom/bcm2835_pwm.c 27 Jul 2019 13:09:18 -0000
@@ -234,9 +234,9 @@ bcm_pwm_control(struct bcm_pwm_channel *
       w = PWM_READ(pwm->sc, PWM_CTL);
       ctl = (w & ~pwm->ctlmask) | __SHIFTIN(ctl, pwm->ctlmask);

-       /* when FIFO usage gets enabled but wasn't clear the FIFO */
-       if ((w & (PWM_CTL_USEF1|PWM_CTL_USEF2)) == 0 &&
-           (ctl & (PWM_CTL_USEF1|PWM_CTL_USEF2)) != 0)
+       /* when FIFO usage changes clear the FIFO */
+       if ((w & (PWM_CTL_USEF1|PWM_CTL_USEF2)) !=
+           (ctl & (PWM_CTL_USEF1|PWM_CTL_USEF2)))
               ctl |= PWM_CTL_CLRF1;

       PWM_WRITE(sc, pwm->rng, rng);
@@ -329,19 +329,18 @@ void
bcm_pwm_dma_enable(struct bcm_pwm_channel *pwm, bool enable)
{
       struct bcm2835pwm_softc *sc = pwm->sc;
-       uint32_t w;
+       uint32_t w, dreq, panic;
+
+       /* when to refill */
+       dreq = 7;
+
+       /* when to request bus priority */
+       panic = 7;

-#if 0
-       w = PWM_READ(sc, PWM_DMAC);
-       if (enable)
-               w |= PWM_DMAC_ENAB;
-       else
-               w &= ~PWM_DMAC_ENAB;
-#else
       w = (enable ? PWM_DMAC_ENAB : 0)
-         | __SHIFTIN(7, PWM_DMAC_PANIC)
-         | __SHIFTIN(7, PWM_DMAC_DREQ);
-#endif
+         | __SHIFTIN(panic, PWM_DMAC_PANIC)
+         | __SHIFTIN(dreq, PWM_DMAC_DREQ);
+
       PWM_WRITE(sc, PWM_DMAC, w & ~PWM_DMAC_WRITEZERO);
}

Index: sys/arch/arm/broadcom/bcm2835_sdhost.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835_sdhost.c,v
retrieving revision 1.4
diff -p -u -r1.4 bcm2835_sdhost.c
--- sys/arch/arm/broadcom/bcm2835_sdhost.c      10 Dec 2017 21:38:26 -0000      1.4
+++ sys/arch/arm/broadcom/bcm2835_sdhost.c      27 Jul 2019 13:09:18 -0000
@@ -358,6 +358,8 @@ sdhost_dma_transfer(struct sdhost_softc

       KASSERT(mutex_owned(&sc->sc_intr_lock));

+KASSERT(cmd->c_dmamap->dm_nsegs <= PAGE_SIZE / sizeof(struct bcm_dmac_conblk));
+
       for (seg = 0; seg < cmd->c_dmamap->dm_nsegs; seg++) {
               sc->sc_cblk[seg].cb_ti =
                   __SHIFTIN(13, DMAC_TI_PERMAP); /* SD HOST */
Index: sys/arch/arm/broadcom/bcm2835reg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835reg.h,v
retrieving revision 1.23
diff -p -u -r1.23 bcm2835reg.h
--- sys/arch/arm/broadcom/bcm2835reg.h  10 Sep 2018 11:05:12 -0000      1.23
+++ sys/arch/arm/broadcom/bcm2835reg.h  27 Jul 2019 13:09:18 -0000
@@ -38,17 +38,25 @@
#ifndef        _BCM2835REG_H_
#define        _BCM2835REG_H_

+#ifdef _KERNEL_OPT
#include "opt_bcm283x.h"
+#endif

#if defined(SOC_BCM2835) + defined(SOC_BCM2836) != 1
#error Must define SOC_BCM2835 or SOC_BCM2836, and not both
#endif

+#define        BCM2838_PERIPHERALS_BASE        0xfe000000
#define        BCM2836_PERIPHERALS_BASE        0x3f000000
#define        BCM2835_PERIPHERALS_BASE        0x20000000
#define        BCM2835_PERIPHERALS_SIZE        0x01000000      /* 16MBytes */
#define        BCM2835_PERIPHERALS_BASE_BUS    0x7e000000

+#define        BCM2838_PERIPHERALS_PHYS_TO_BUS(a) \
+    ((a) - BCM2838_PERIPHERALS_BASE + BCM2835_PERIPHERALS_BASE_BUS)
+#define        BCM2838_PERIPHERALS_BUS_TO_PHYS(a) \
+    ((a) - BCM2835_PERIPHERALS_BASE_BUS + BCM2838_PERIPHERALS_BASE)
+
#define        BCM2836_PERIPHERALS_PHYS_TO_BUS(a) \
    ((a) - BCM2836_PERIPHERALS_BASE + BCM2835_PERIPHERALS_BASE_BUS)
#define        BCM2836_PERIPHERALS_BUS_TO_PHYS(a) \
@@ -89,6 +97,7 @@
#define        BCM2835_RNG_SIZE        0x1000
#define        BCM2835_GPIO_SIZE       0x1000
#define        BCM2835_UART0_SIZE      0x90
+#define        BCM2835_SDHOST_SIZE     0x1000
#define        BCM2835_PCM_SIZE        0x1000
#define        BCM2835_SPI0_SIZE       0x1000
#define        BCM2835_BSC_SIZE        0x1000
@@ -134,7 +143,7 @@
#define        BCM2835_INTC_DISABLEBASE        (BCM2835_INTC_BASE + 0x1c)

#if defined(SOC_BCM2836)
-#define        BCM2835_INT_BASE                BCM2836_NIRQ
+#define        BCM2835_INT_BASE                BCM2836_INT_BASECPUN(BCM2836_NCPUS)
#else
#define        BCM2835_INT_BASE                0
#endif /* !BCM2836 */
@@ -142,7 +151,7 @@
#define        BCM2836_NCPUS                   4
#define        BCM2836_NIRQPERCPU              32

-#define        BCM2836_INT_LOCALBASE           0
+#define        BCM2836_INT_LOCALBASE           1024
#define        BCM2836_INT_BASECPUN(n)         (BCM2836_INT_LOCALBASE + ((n) * BCM2836_NIRQPERCPU))
#define        BCM2836_NIRQ                    (BCM2836_NIRQPERCPU * BCM2836_NCPUS)

@@ -206,6 +215,9 @@

#define        BCM2835_UART0_CLK               3000000

+#define        BCM2838_ARM_LOCAL_BASE          0xff800000
+#define        BCM2838_ARM_LOCAL_SIZE          0x00100000      /* 1MByte */
+
#define        BCM2836_ARM_LOCAL_BASE          0x40000000
#define        BCM2836_ARM_LOCAL_SIZE          0x00001000      /* 4KBytes */

Index: sys/arch/arm/broadcom/bcm2835var.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm2835var.h,v
retrieving revision 1.4
diff -p -u -r1.4 bcm2835var.h
--- sys/arch/arm/broadcom/bcm2835var.h  1 Apr 2018 04:35:03 -0000       1.4
+++ sys/arch/arm/broadcom/bcm2835var.h  27 Jul 2019 13:09:18 -0000
@@ -49,5 +49,6 @@ void bcm2836_cpu_hatch(struct cpu_info *
u_int bcm283x_clk_get_rate_uart(void);
u_int bcm283x_clk_get_rate_vpu(void);
u_int bcm283x_clk_get_rate_emmc(void);
+u_int bcm283x_clk_get_rate_emmc2(void);

#endif /* _ARM_BROADCOM_BCM2835_VAR_H_ */
Index: sys/arch/arm/broadcom/bcm283x_platform.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm283x_platform.c,v
retrieving revision 1.23
diff -p -u -r1.23 bcm283x_platform.c
--- sys/arch/arm/broadcom/bcm283x_platform.c    3 Jan 2019 12:52:40 -0000       1.23
+++ sys/arch/arm/broadcom/bcm283x_platform.c    27 Jul 2019 13:09:18 -0000
@@ -113,14 +113,24 @@ __KERNEL_RCSID(0, "$NetBSD: bcm283x_plat
void bcm2835_platform_early_putchar(char c);
void bcm2836_platform_early_putchar(char c);
void bcm2837_platform_early_putchar(char c);
+void bcm2838_platform_early_putchar(char c);

extern void bcmgenfb_set_console_dev(device_t dev);
void bcmgenfb_set_ioctl(int(*)(void *, void *, u_long, void *, int, struct lwp *));
extern void bcmgenfb_ddb_trap_callback(int where);
static int rpi_ioctl(void *, void *, u_long, void *, int, lwp_t *);

+#if defined(__aarch64__)
+extern struct bus_space aarch64_generic_dsb_bs_tag;
+extern struct bus_space aarch64_generic_a4x_dsb_bs_tag;
+#define ARM_GENERIC_BS_TAG aarch64_generic_dsb_bs_tag
+#define ARM_GENERIC_A4X_BS_TAG aarch64_generic_a4x_dsb_bs_tag
+#else
extern struct bus_space arm_generic_bs_tag;
extern struct bus_space arm_generic_a4x_bs_tag;
+#define ARM_GENERIC_BS_TAG arm_generic_bs_tag
+#define ARM_GENERIC_A4X_BS_TAG arm_generic_a4x_bs_tag
+#endif

/* Prototypes for all the bus_space structure functions */
bs_protos(arm_generic);
@@ -129,14 +139,19 @@ bs_protos(bcm2835);
bs_protos(bcm2835_a4x);
bs_protos(bcm2836);
bs_protos(bcm2836_a4x);
+bs_protos(bcm2838);
+bs_protos(bcm2838_a4x);

struct bus_space bcm2835_bs_tag;
struct bus_space bcm2835_a4x_bs_tag;
struct bus_space bcm2836_bs_tag;
struct bus_space bcm2836_a4x_bs_tag;
+struct bus_space bcm2838_bs_tag;
+struct bus_space bcm2838_a4x_bs_tag;

static paddr_t bcm2835_bus_to_phys(bus_addr_t);
static paddr_t bcm2836_bus_to_phys(bus_addr_t);
+static paddr_t bcm2838_bus_to_phys(bus_addr_t);

#ifdef VERBOSE_INIT_ARM
#define VPRINTF(...)   printf(__VA_ARGS__)
@@ -172,13 +187,33 @@ bcm2836_bus_to_phys(bus_addr_t ba)
       return ba & ~BCM2835_BUSADDR_CACHE_MASK;
}

+static paddr_t
+bcm2838_bus_to_phys(bus_addr_t ba)
+{
+
+       /* Attempt to find the PA device mapping */
+       if (ba >= BCM2835_PERIPHERALS_BASE_BUS &&
+           ba < BCM2835_PERIPHERALS_BASE_BUS + BCM2835_PERIPHERALS_SIZE)
+               return BCM2838_PERIPHERALS_BUS_TO_PHYS(ba);
+
+       if (ba >= BCM2838_ARM_LOCAL_BASE &&
+           ba < BCM2838_ARM_LOCAL_BASE + BCM2838_ARM_LOCAL_SIZE)
+               return ba;
+
+       if (ba >= BCM2836_ARM_LOCAL_BASE &&
+           ba < BCM2836_ARM_LOCAL_BASE + BCM2838_ARM_LOCAL_SIZE)
+               return (ba - BCM2836_ARM_LOCAL_BASE) + BCM2838_ARM_LOCAL_BASE;
+
+       return ba & ~BCM2835_BUSADDR_CACHE_MASK;
+}
+
int
bcm2835_bs_map(void *t, bus_addr_t ba, bus_size_t size, int flag,
    bus_space_handle_t *bshp)
{
       const paddr_t pa = bcm2835_bus_to_phys(ba);

-       return bus_space_map(&arm_generic_bs_tag, pa, size, flag, bshp);
+       return bus_space_map(&ARM_GENERIC_BS_TAG, pa, size, flag, bshp);
}

paddr_t
@@ -186,7 +221,7 @@ bcm2835_bs_mmap(void *t, bus_addr_t ba,
{
       const paddr_t pa = bcm2835_bus_to_phys(ba);

-       return bus_space_mmap(&arm_generic_bs_tag, pa, offset, prot, flags);
+       return bus_space_mmap(&ARM_GENERIC_BS_TAG, pa, offset, prot, flags);
}

paddr_t
@@ -202,7 +237,7 @@ bcm2836_bs_map(void *t, bus_addr_t ba, b
{
       const paddr_t pa = bcm2836_bus_to_phys(ba);

-       return bus_space_map(&arm_generic_bs_tag, pa, size, flag, bshp);
+       return bus_space_map(&ARM_GENERIC_BS_TAG, pa, size, flag, bshp);
}

paddr_t
@@ -210,7 +245,7 @@ bcm2836_bs_mmap(void *t, bus_addr_t ba,
{
       const paddr_t pa = bcm2836_bus_to_phys(ba);

-       return bus_space_mmap(&arm_generic_bs_tag, pa, offset, prot, flags);
+       return bus_space_mmap(&ARM_GENERIC_BS_TAG, pa, offset, prot, flags);
}

paddr_t
@@ -220,6 +255,30 @@ bcm2836_a4x_bs_mmap(void *t, bus_addr_t
       return bcm2836_bs_mmap(t, ba, 4 * offset, prot, flags);
}

+int
+bcm2838_bs_map(void *t, bus_addr_t ba, bus_size_t size, int flag,
+    bus_space_handle_t *bshp)
+{
+       const paddr_t pa = bcm2838_bus_to_phys(ba);
+
+       return bus_space_map(&ARM_GENERIC_BS_TAG, pa, size, flag, bshp);
+}
+
+paddr_t
+bcm2838_bs_mmap(void *t, bus_addr_t ba, off_t offset, int prot, int flags)
+{
+       const paddr_t pa = bcm2838_bus_to_phys(ba);
+
+       return bus_space_mmap(&ARM_GENERIC_BS_TAG, pa, offset, prot, flags);
+}
+
+paddr_t
+bcm2838_a4x_bs_mmap(void *t, bus_addr_t ba, off_t offset, int prot, int flags)
+{
+
+       return bcm2838_bs_mmap(t, ba, 4 * offset, prot, flags);
+}
+
struct arm32_dma_range bcm2835_dma_ranges[] = {
       [0] = {
               .dr_sysbase = 0,
@@ -234,6 +293,13 @@ struct arm32_dma_range bcm2836_dma_range
       }
};

+struct arm32_dma_range bcm2838_dma_ranges[] = {
+       [0] = {
+               .dr_sysbase = 0,
+               .dr_busbase = BCM2835_BUSADDR_CACHE_DIRECT,
+       }
+};
+

#if defined(SOC_BCM2835)
static const struct pmap_devmap *
@@ -257,13 +323,31 @@ bcm2836_platform_devmap(void)
       static const struct pmap_devmap devmap[] = {
               DEVMAP_ENTRY(BCM2836_PERIPHERALS_VBASE, BCM2836_PERIPHERALS_BASE,
                   BCM2835_PERIPHERALS_SIZE),  /* 16Mb */
-
               DEVMAP_ENTRY(BCM2836_ARM_LOCAL_VBASE, BCM2836_ARM_LOCAL_BASE,
                   BCM2836_ARM_LOCAL_SIZE),
#if defined(MULTIPROCESSOR) && defined(__aarch64__)
               /* for fdt cpu spin-table */
-               DEVMAP_ENTRY(BCM2836_ARM_SMP_VBASE, BCM2836_ARM_SMP_BASE,
-                   BCM2836_ARM_SMP_SIZE),
+               DEVMAP_ENTRY_PAGES(BCM2836_ARM_SMP_VBASE, BCM2836_ARM_SMP_BASE,
+               BCM2836_ARM_SMP_SIZE),
+#endif
+               DEVMAP_ENTRY_END
+       };
+
+       return devmap;
+}
+
+static const struct pmap_devmap *
+bcm2838_platform_devmap(void)
+{
+       static const struct pmap_devmap devmap[] = {
+               DEVMAP_ENTRY(BCM2838_PERIPHERALS_VBASE, BCM2838_PERIPHERALS_BASE,
+                   BCM2835_PERIPHERALS_SIZE),  /* 16Mb */
+               DEVMAP_ENTRY(BCM2838_ARM_LOCAL_VBASE, BCM2838_ARM_LOCAL_BASE,
+                   BCM2838_ARM_LOCAL_SIZE),
+#if defined(MULTIPROCESSOR) && defined(__aarch64__)
+               /* for fdt cpu spin-table */
+               DEVMAP_ENTRY_PAGES(BCM2836_ARM_SMP_VBASE, BCM2836_ARM_SMP_BASE,
+               BCM2836_ARM_SMP_SIZE),
#endif
               DEVMAP_ENTRY_END
       };
@@ -330,6 +414,7 @@ static struct {
       struct vcprop_tag_clockrate     vbt_emmcclockrate;
       struct vcprop_tag_clockrate     vbt_armclockrate;
       struct vcprop_tag_clockrate     vbt_vpuclockrate;
+       struct vcprop_tag_clockrate     vbt_emmc2clockrate;
       struct vcprop_tag end;
} vb __cacheline_aligned = {
       .vb_hdr = {
@@ -416,6 +501,14 @@ static struct {
               },
               .id = VCPROP_CLK_CORE
       },
+       .vbt_emmc2clockrate = {
+               .tag = {
+                       .vpt_tag = VCPROPTAG_GET_CLOCKRATE,
+                       .vpt_len = VCPROPTAG_LEN(vb.vbt_emmc2clockrate),
+                       .vpt_rcode = VCPROPTAG_REQUEST
+               },
+               .id = VCPROP_CLK_EMMC2
+       },
       .end = {
               .vpt_tag = VCPROPTAG_NULL
       }
@@ -567,6 +660,17 @@ bcm283x_clk_get_rate_emmc(void)
       return 0;
}

+u_int
+bcm283x_clk_get_rate_emmc2(void)
+{
+
+       if (vcprop_tag_success_p(&vb.vbt_emmc2clockrate.tag) &&
+           vb.vbt_emmc2clockrate.rate > 0) {
+               return vb.vbt_emmc2clockrate.rate;
+       }
+       return 0;
+}
+


static void
@@ -607,6 +711,16 @@ bcm2836_uartinit(void)

       bcm283x_uartinit(iot, ioh);
}
+
+static void
+bcm2838_uartinit(void)
+{
+       const paddr_t pa = BCM2838_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE);
+       const bus_space_tag_t iot = &bcm2838_bs_tag;
+       const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa);
+
+       bcm283x_uartinit(iot, ioh);
+}
#endif

#define        BCM283x_MINIMUM_SPLIT   (128U * 1024 * 1024)
@@ -637,10 +751,11 @@ bcm283x_bootparams(bus_space_tag_t iot,
#endif
           0) << 4);

+       cpu_dcache_wbinv_range((vaddr_t)&vb, sizeof(vb));
       bcm2835_mbox_write(iot, ioh, BCMMBOX_CHANARM2VC,
           KERN_VTOPHYS((vaddr_t)&vb));
-
       bcm2835_mbox_read(iot, ioh, BCMMBOX_CHANARM2VC, &res);
+       cpu_dcache_wbinv_range((vaddr_t)&vb, sizeof(vb));

       if (!vcprop_buffer_success_p(&vb.vb_hdr)) {
               bootconfig.dramblocks = 1;
@@ -664,7 +779,8 @@ bcm283x_bootparams(bus_space_tag_t iot,

                       bcm283x_memorysize += vptp_mem->mem[i].size;
               }
-       }
+       } else
+               printf("%s: failed to query memory\n",__func__);

       if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag))
               curcpu()->ci_data.cpu_cc_freq = vb.vbt_armclockrate.rate;
@@ -676,6 +792,12 @@ bcm283x_bootparams(bus_space_tag_t iot,
       if (vcprop_tag_success_p(&vb.vbt_armclockrate.tag))
               printf("%s: arm clock    %d\n", __func__,
                   vb.vbt_armclockrate.rate);
+       if (vcprop_tag_success_p(&vb.vbt_vpuclockrate.tag))
+               printf("%s: vpu clock    %d\n", __func__,
+                   vb.vbt_vpuclockrate.rate);
+       if (vcprop_tag_success_p(&vb.vbt_emmcclockrate.tag))
+               printf("%s: emmc clock   %d\n", __func__,
+                   vb.vbt_emmcclockrate.rate);
       if (vcprop_tag_success_p(&vb.vbt_fwrev.tag))
               printf("%s: firmware rev %x\n", __func__,
                   vb.vbt_fwrev.rev);
@@ -724,6 +846,16 @@ bcm2836_bootparams(void)
       bcm283x_bootparams(iot, ioh);
}

+static void
+bcm2838_bootparams(void)
+{
+       const paddr_t pa = BCM2838_PERIPHERALS_BUS_TO_PHYS(BCM2835_ARMMBOX_BASE);
+       const bus_space_tag_t iot = &bcm2838_bs_tag;
+       const bus_space_handle_t ioh = BCM2835_IOPHYSTOVIRT(pa);
+
+       bcm283x_bootparams(iot, ioh);
+}
+
#if defined(MULTIPROCESSOR)
static int
cpu_enable_bcm2836(int phandle)
@@ -1080,6 +1212,87 @@ rpi_ioctl(void *v, void *vs, u_long cmd,

#endif

+static struct rpi_info {
+        int model, pcbrev, memsize, manufacturer, processor, warranty;
+} revtbl[] = {
+       { -1, },
+       { -1, },
+       { RPI_MODEL_B, 1, RPI_MEMSIZE_256, -1, },
+       { RPI_MODEL_B, 1, RPI_MEMSIZE_256, -1, },
+       { RPI_MODEL_B, 2, RPI_MEMSIZE_256, RPI_MANUF_SONY, },
+       { RPI_MODEL_B, 2, RPI_MEMSIZE_256, RPI_MANUF_QISDA, },
+       { RPI_MODEL_B, 2, RPI_MEMSIZE_256, RPI_MANUF_EGOMAN, },
+       { RPI_MODEL_A, 2, RPI_MEMSIZE_256, RPI_MANUF_EGOMAN, },
+       { RPI_MODEL_A, 2, RPI_MEMSIZE_256, RPI_MANUF_SONY, },
+       { RPI_MODEL_A, 2, RPI_MEMSIZE_256, RPI_MANUF_QISDA, },
+       { -1, },
+       { -1, },
+       { -1, },
+       { RPI_MODEL_B,       2, RPI_MEMSIZE_512, RPI_MANUF_EGOMAN, },
+       { RPI_MODEL_B,       2, RPI_MEMSIZE_512, RPI_MANUF_SONY, },
+       { RPI_MODEL_B,       2, RPI_MEMSIZE_512, RPI_MANUF_QISDA, },
+       { RPI_MODEL_B_PLUS,  1, RPI_MEMSIZE_512, RPI_MANUF_SONY, },
+       { RPI_MODEL_COMPUTE, 1, RPI_MEMSIZE_512, RPI_MANUF_SONY, },
+       { RPI_MODEL_A_PLUS,  1, RPI_MEMSIZE_256, RPI_MANUF_SONY, },
+       { RPI_MODEL_B_PLUS,  1, RPI_MEMSIZE_512, RPI_MANUF_EMBEST, },
+       { RPI_MODEL_COMPUTE, 1, RPI_MEMSIZE_512, RPI_MANUF_SONY, },
+       { RPI_MODEL_A_PLUS,  1, RPI_MEMSIZE_256, RPI_MANUF_SONY, }
+};
+
+static void
+rev2info(unsigned rev, struct rpi_info *info)
+{
+
+       if (rev & VCPROP_REV_ENCFLAG) {
+               info->pcbrev       = __SHIFTOUT(rev, VCPROP_REV_PCBREV),
+               info->model        = __SHIFTOUT(rev, VCPROP_REV_MODEL),
+               info->processor    = __SHIFTOUT(rev, VCPROP_REV_PROCESSOR),
+               info->manufacturer = __SHIFTOUT(rev, VCPROP_REV_MANUF),
+               info->memsize      = __SHIFTOUT(rev, VCPROP_REV_MEMSIZE),
+               info->warranty     = __SHIFTOUT(rev, VCPROP_REV_WARRANTY);
+       } else if (rev < __arraycount(revtbl)) {
+               info->pcbrev       = revtbl[rev].pcbrev;
+               info->model        = revtbl[rev].model;
+               info->processor    = RPI_PROCESSOR_BCM2835;
+               info->manufacturer = revtbl[rev].manufacturer;
+               info->memsize      = revtbl[rev].memsize;
+               info->warranty     = __SHIFTOUT(rev, VCPROP_REV_WARRANTY);
+       } else {
+               info->pcbrev       = -1;
+               info->model        = -1;
+               info->processor    = -1;
+               info->manufacturer = -1;
+               info->memsize      = -1;
+               info->warranty     = __SHIFTOUT(rev, VCPROP_REV_WARRANTY);
+       }
+}
+
+static int
+rpi_boardinfo_helper(SYSCTLFN_ARGS)
+{
+       struct rpi_info info;
+       char buf[100];
+       int error;
+
+       rev2info(vb.vbt_boardrev.rev, &info);
+
+       snprintf(buf, sizeof(buf),
+               "pcbrev:%d model:%d processor:%d manufacturer:%d"
+               " memsize:%d warrantyvoid:%d",
+               info.pcbrev,
+               info.model,
+               info.processor,
+               info.manufacturer,
+               info.memsize,
+               info.warranty);
+
+       if (oldp && (error = copyoutstr(buf, oldp, sizeof(buf), NULL)) != 0)
+               return error;
+
+       *oldlenp = strlen(buf)+1;
+       return 0;
+}
+
SYSCTL_SETUP(sysctl_machdep_rpi, "sysctl machdep subtree setup (rpi)")
{
       sysctl_createv(clog, 0, NULL, NULL,
@@ -1105,6 +1318,12 @@ SYSCTL_SETUP(sysctl_machdep_rpi, "sysctl
           CTLFLAG_PERMANENT|CTLFLAG_READONLY|CTLFLAG_HEX|CTLFLAG_PRIVATE,
           CTLTYPE_QUAD, "serial", NULL, NULL, 0,
           &vb.vbt_serial.sn, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+
+       sysctl_createv(clog, 0, NULL, NULL,
+           CTLFLAG_PERMANENT|CTLFLAG_READONLY,
+           CTLTYPE_STRING, "board_info", "RPI Board Information",
+           rpi_boardinfo_helper, 0,
+           NULL, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
}

#if defined(SOC_BCM2835)
@@ -1112,8 +1331,8 @@ static void
bcm2835_platform_bootstrap(void)
{

-       bcm2835_bs_tag = arm_generic_bs_tag;
-       bcm2835_a4x_bs_tag = arm_generic_a4x_bs_tag;
+       bcm2835_bs_tag = ARM_GENERIC_BS_TAG;
+       bcm2835_a4x_bs_tag = ARM_GENERIC_A4X_BS_TAG;

       bcm2835_bs_tag.bs_map = bcm2835_bs_map;
       bcm2835_bs_tag.bs_mmap = bcm2835_bs_mmap;
@@ -1133,8 +1352,8 @@ static void
bcm2836_platform_bootstrap(void)
{

-       bcm2836_bs_tag = arm_generic_bs_tag;
-       bcm2836_a4x_bs_tag = arm_generic_a4x_bs_tag;
+       bcm2836_bs_tag = ARM_GENERIC_BS_TAG;
+       bcm2836_a4x_bs_tag = ARM_GENERIC_A4X_BS_TAG;

       bcm2836_bs_tag.bs_map = bcm2836_bs_map;
       bcm2836_bs_tag.bs_mmap = bcm2836_bs_mmap;
@@ -1152,6 +1371,30 @@ bcm2836_platform_bootstrap(void)
       arm_fdt_cpu_bootstrap();
#endif
}
+
+static void
+bcm2838_platform_bootstrap(void)
+{
+
+       bcm2838_bs_tag = ARM_GENERIC_BS_TAG;
+       bcm2838_a4x_bs_tag = ARM_GENERIC_A4X_BS_TAG;
+
+       bcm2838_bs_tag.bs_map = bcm2838_bs_map;
+       bcm2838_bs_tag.bs_mmap = bcm2838_bs_mmap;
+       bcm2838_a4x_bs_tag.bs_map = bcm2838_bs_map;
+       bcm2838_a4x_bs_tag.bs_mmap = bcm2838_a4x_bs_mmap;
+
+       fdtbus_set_decoderegprop(false);
+
+       bcm2838_uartinit();
+
+       bcm2838_bootparams();
+
+#ifdef MULTIPROCESSOR
+       arm_cpu_max = RPI_CPU_MAX;
+       arm_fdt_cpu_bootstrap();
+#endif
+}
#endif

#if defined(SOC_BCM2835)
@@ -1182,6 +1425,19 @@ bcm2836_platform_init_attach_args(struct
       bcm2835_bus_dma_tag._nranges = __arraycount(bcm2836_dma_ranges);
       bcm2836_dma_ranges[0].dr_len = bcm283x_memorysize;
}
+
+static void
+bcm2838_platform_init_attach_args(struct fdt_attach_args *faa)
+{
+
+       faa->faa_bst = &bcm2838_bs_tag;
+       faa->faa_a4x_bst = &bcm2838_a4x_bs_tag;
+       faa->faa_dmat = &bcm2835_bus_dma_tag;
+
+       bcm2835_bus_dma_tag._ranges = bcm2838_dma_ranges;
+       bcm2835_bus_dma_tag._nranges = __arraycount(bcm2838_dma_ranges);
+       bcm2838_dma_ranges[0].dr_len = bcm283x_memorysize;
+}
#endif


@@ -1223,6 +1479,24 @@ bcm2836_platform_early_putchar(char c)
#define        BCM283x_REF_FREQ        19200000

void
+bcm2838_platform_early_putchar(char c)
+{
+#define AUCONSADDR_PA  BCM2838_PERIPHERALS_BUS_TO_PHYS(BCM2835_AUX_UART_BASE)
+#define AUCONSADDR_VA  BCM2835_IOPHYSTOVIRT(AUCONSADDR_PA)
+       volatile uint32_t *uartaddr =
+           cpu_earlydevice_va_p() ?
+               (volatile uint32_t *)AUCONSADDR_VA :
+               (volatile uint32_t *)AUCONSADDR_PA;
+
+       while ((uartaddr[com_lsr] & LSR_TXRDY) == 0)
+               ;
+
+       uartaddr[com_data] = c;
+#undef AUCONSADDR_VA
+#undef AUCONSADDR_PA
+}
+
+void
bcm2837_platform_early_putchar(char c)
{
#define AUCONSADDR_PA  BCM2836_PERIPHERALS_BUS_TO_PHYS(BCM2835_AUX_UART_BASE)
@@ -1236,6 +1510,8 @@ bcm2837_platform_early_putchar(char c)
               ;

       uartaddr[com_data] = c;
+#undef AUCONSADDR_VA
+#undef AUCONSADDR_PA
}

static void
@@ -1353,6 +1629,18 @@ static const struct arm_platform bcm2837
       .ap_mpstart = arm_fdt_cpu_mpstart,
};

+static const struct arm_platform bcm2838_platform = {
+       .ap_devmap = bcm2838_platform_devmap,
+       .ap_bootstrap = bcm2838_platform_bootstrap,
+       .ap_init_attach_args = bcm2838_platform_init_attach_args,
+       .ap_device_register = bcm283x_platform_device_register,
+       .ap_reset = bcm2835_system_reset,
+       .ap_delay = gtmr_delay,
+       .ap_uart_freq = bcm2837_platform_uart_freq,
+       .ap_mpstart = arm_fdt_cpu_mpstart,
+};
+
ARM_PLATFORM(bcm2836, "brcm,bcm2836", &bcm2836_platform);
ARM_PLATFORM(bcm2837, "brcm,bcm2837", &bcm2837_platform);
+ARM_PLATFORM(bcm2838, "brcm,bcm2838", &bcm2838_platform);
#endif
Index: sys/arch/arm/broadcom/bcm283x_platform.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/broadcom/bcm283x_platform.h,v
retrieving revision 1.2
diff -p -u -r1.2 bcm283x_platform.h
--- sys/arch/arm/broadcom/bcm283x_platform.h    10 Sep 2018 11:05:12 -0000      1.2
+++ sys/arch/arm/broadcom/bcm283x_platform.h    27 Jul 2019 13:09:18 -0000
@@ -34,8 +34,25 @@

#include <arch/evbarm/fdt/platform.h>

+/*
+ * map physical IO address
+ *
+ * 00xxxxxx -> vbase | 00xxxxxx (SMP page)
+ * 20xxxxxx -> vbase | 02xxxxxx (RPI1 periph)
+ * 30xxxxxx -> vbase | 03xxxxxx (RPI2/3 local)
+ * 7exxxxxx -> vbase | 07xxxxxx (RPI2/3 periph)
+ * fexxxxxx -> vbase | 07xxxxxx (RPI4 periph)
+ * ffxxxxxx -> vbase | 06xxxxxx (RPI4 local)
+ *
+ */
#define        BCM2835_IOPHYSTOVIRT(a) \
-       ((KERNEL_IO_VBASE | (((a) & 0xf0000000) >> 4)) + ((a) & ~0xff000000))
+       ( \
+               KERNEL_IO_VBASE \
+               | ( \
+                       (((a) & 0x70000000) >> 4) \
+                       ^ (((a) & 0x01000000) >> 0) \
+               ) | ((a) & ~0xff000000) \
+       )

#define        BCM2835_PERIPHERALS_VBASE \
       BCM2835_IOPHYSTOVIRT(BCM2835_PERIPHERALS_BASE)
@@ -43,9 +60,15 @@
#define        BCM2836_PERIPHERALS_VBASE \
       BCM2835_IOPHYSTOVIRT(BCM2836_PERIPHERALS_BASE)

+#define        BCM2838_PERIPHERALS_VBASE \
+       BCM2835_IOPHYSTOVIRT(BCM2838_PERIPHERALS_BASE)
+
#define        BCM2836_ARM_LOCAL_VBASE \
       BCM2835_IOPHYSTOVIRT(BCM2836_ARM_LOCAL_BASE)

+#define        BCM2838_ARM_LOCAL_VBASE \
+       BCM2835_IOPHYSTOVIRT(BCM2838_ARM_LOCAL_BASE)
+
#define        BCM2836_ARM_SMP_VBASE   \
       BCM2835_IOPHYSTOVIRT(BCM2836_ARM_SMP_BASE)

Index: sys/arch/arm/cortex/gic.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/cortex/gic.c,v
retrieving revision 1.38
diff -p -u -r1.38 gic.c
--- sys/arch/arm/cortex/gic.c   16 Nov 2018 23:25:09 -0000      1.38
+++ sys/arch/arm/cortex/gic.c   27 Jul 2019 13:09:18 -0000
@@ -320,7 +320,6 @@ armgic_irq_handler(void *tf)
#ifdef DEBUG
       size_t n = 0;
#endif
-
       ci->ci_data.cpu_nintr++;

       for (;;) {
Index: sys/arch/arm/cortex/gtmr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/cortex/gtmr.c,v
retrieving revision 1.40
diff -p -u -r1.40 gtmr.c
--- sys/arch/arm/cortex/gtmr.c  16 Jun 2019 10:57:59 -0000      1.40
+++ sys/arch/arm/cortex/gtmr.c  27 Jul 2019 13:09:18 -0000
@@ -42,6 +42,11 @@ __KERNEL_RCSID(0, "$NetBSD: gtmr.c,v 1.4
#include <sys/systm.h>
#include <sys/timetc.h>

+#include <sys/atomic.h>
+#include <sys/sysctl.h>
+#include <arch/arm/broadcom/bcm2835reg.h>
+#include <arch/arm/broadcom/bcm283x_platform.h>
+
#include <prop/proplib.h>

#include <arm/locore.h>
@@ -250,11 +255,54 @@ gtmr_delay(unsigned int n)
       }
}

+static void
+gtmr_recover(uint32_t *base)
+{
+       struct cpu_info * const ci = curcpu();
+       struct gtmr_softc * const sc = &gtmr_sc;
+       uint64_t now;
+
+       if (base == NULL)
+               return;
+
+       now = gtmr_read_cntvct(sc);
+
+       if (now < ci->ci_lastintr) {
+               printf("cntv was reset to %"PRIx64"\n", now);
+               now = ci->ci_lastintr + sc->sc_autoinc;
+               printf("restoring to %"PRIx64" + %lx = %"PRIx64"\n",
+                       ci->ci_lastintr, sc->sc_autoinc, now);
+
+               /* BCM2836_LOCAL_TIMER_LS */
+               base[7] = now & 0xffffffff;
+               arm_isb();
+               /* BCM2836_LOCAL_TIMER_MS */
+               base[8] = now >> 32;
+               arm_isb();
+
+               now = gtmr_read_cntvct(sc);
+               printf("read 1 value %"PRIx64"\n",now);
+               now = gtmr_read_cntvct(sc);
+               printf("read 2 value %"PRIx64"\n",now);
+               now = gtmr_read_cntvct(sc);
+               printf("read 3 value %"PRIx64"\n",now);
+
+               /* BCM2836_LOCAL_PRESCALER */
+               base[2] = 0x80000000;
+               arm_isb();
+
+               now = gtmr_read_cntvct(sc);
+               printf("read 4 value %"PRIx64"\n",now);
+       }
+}
+
/*
 * gtmr_intr:
 *
 *     Handle the hardclock interrupt.
 */
+volatile unsigned int the_gtmr_interrupts;
+volatile unsigned int the_gtmr_counts;
int
gtmr_intr(void *arg)
{
@@ -262,6 +310,8 @@ gtmr_intr(void *arg)
       struct clockframe * const cf = arg;
       struct gtmr_softc * const sc = &gtmr_sc;

+       atomic_inc_uint(&the_gtmr_interrupts);
+
       arm_isb();

       const uint32_t ctl = gtmr_cntv_ctl_read();
@@ -271,7 +321,10 @@ gtmr_intr(void *arg)
       arm_isb();
       gtmr_cntv_ctl_write(0);

+       atomic_inc_uint(&the_gtmr_counts);
+
       const uint64_t now = gtmr_read_cntvct(sc);
+
       uint64_t delta = now - ci->ci_lastintr;

#ifdef DIAGNOSTIC
@@ -341,3 +394,61 @@ gtmr_get_timecount(struct timecounter *t
       arm_isb();      // we want the time NOW, not some instructions later.
       return (u_int) gtmr_read_cntvct(sc);
}
+
+
+
+static int gtmr_debug_helper(SYSCTLFN_PROTO);
+static bool gtmr_debug_flag = false;
+
+static int
+gtmr_debug_helper(SYSCTLFN_ARGS)
+{
+       struct sysctlnode node;
+       int error;
+       bool t;
+
+       node = *rnode;
+       node.sysctl_data = &t;
+       error = sysctl_lookup(SYSCTLFN_CALL(&node));
+       if (error || newp == NULL)
+               return (error);
+
+       uint32_t *base = (uint32_t *)BCM2836_ARM_LOCAL_VBASE;
+       unsigned i;
+
+       if (pmap_devmap_find_va((vaddr_t)base, 0x100) == NULL)
+               base = NULL;
+
+       gtmr_recover(base);
+
+       printf("cntfrq         %" PRIx32 "\n", gtmr_cntfrq_read());
+       printf("cntk_ctl       %" PRIx32 "\n", gtmr_cntk_ctl_read());
+       printf("cntpct         %" PRIx64 "\n", gtmr_cntpct_read());
+       printf("cntvct         %" PRIx64 "\n", gtmr_cntvct_read());
+       printf("cntvct_ctl     %" PRIx32 "\n", gtmr_cntv_ctl_read());
+       printf("cntvct_tval    %" PRIx32 "\n", gtmr_cntv_tval_read());
+       printf("cntvct_cval    %" PRIx64 "\n", gtmr_cntv_cval_read());
+
+       if (base)
+       for (i=0; i<32; ++i)
+               printf("local[%3u]     %" PRIx32 "\n",i,base[i]);
+
+       printf("ci_nintr[%3u]  %" PRIx64 "\n",
+               curcpu()->ci_data.cpu_index,
+               curcpu()->ci_data.cpu_nintr);
+
+       return 0;
+}
+
+SYSCTL_SETUP(sysctl_gtmr_debug, "GTMR debug trigger")
+{
+       sysctl_createv(clog, 0, NULL, NULL,
+               CTLFLAG_PERMANENT, CTLTYPE_NODE, "machdep", NULL,
+               NULL, 0, NULL, 0, CTL_MACHDEP, CTL_EOL);
+
+       sysctl_createv(clog, 0, NULL, NULL,
+               CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+               CTLTYPE_BOOL, "gtmrdebug", "GTMR Debug Trigger",
+               gtmr_debug_helper, 0,
+               &gtmr_debug_flag, 0, CTL_MACHDEP, CTL_CREATE, CTL_EOL);
+}
Index: sys/arch/arm/include/arm32/pmap.h
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/include/arm32/pmap.h,v
retrieving revision 1.156
diff -p -u -r1.156 pmap.h
--- sys/arch/arm/include/arm32/pmap.h   18 Oct 2018 09:01:52 -0000      1.156
+++ sys/arch/arm/include/arm32/pmap.h   27 Jul 2019 13:09:18 -0000
@@ -215,6 +215,8 @@ struct pmap_devmap {

#define        DEVMAP_ALIGN(a) ((a) & ~L1_S_OFFSET)
#define        DEVMAP_SIZE(s)  roundup2((s), L1_S_SIZE)
+#define        DEVMAP_ALIGNPG(a)       ((a) & ~L2_S_OFFSET)
+#define        DEVMAP_PGSZ(s)  roundup2((s), L2_S_SIZE)
#define        DEVMAP_ENTRY(va, pa, sz)                        \
       {                                               \
               .pd_va = DEVMAP_ALIGN(va),              \
@@ -223,6 +225,14 @@ struct pmap_devmap {
               .pd_prot = VM_PROT_READ|VM_PROT_WRITE,  \
               .pd_cache = PTE_NOCACHE                 \
       }
+#define        DEVMAP_ENTRY_PAGES(va, pa, sz)                  \
+       {                                               \
+               .pd_va = DEVMAP_ALIGNPG(va),            \
+               .pd_pa = DEVMAP_ALIGNPG(pa),            \
+               .pd_size = DEVMAP_PGSZ(sz),     \
+               .pd_prot = VM_PROT_READ|VM_PROT_WRITE,  \
+               .pd_cache = PTE_NOCACHE                 \
+       }
#define        DEVMAP_ENTRY_END        { 0 }

/*
Index: sys/arch/arm/pic/pic.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/pic/pic.c,v
retrieving revision 1.48
diff -p -u -r1.48 pic.c
--- sys/arch/arm/pic/pic.c      16 Nov 2018 15:06:22 -0000      1.48
+++ sys/arch/arm/pic/pic.c      27 Jul 2019 13:09:18 -0000
@@ -813,9 +813,9 @@ pic_establish_intr(struct pic_softc *pic
       is->is_iplidx = off - pic_ipl_offset[ipl];
       pic__iplsources[off] = is;

+unblock:
       (*pic->pic_ops->pic_establish_irq)(pic, is);

-unblock:
       (*pic->pic_ops->pic_unblock_irqs)(pic, is->is_irq & ~0x1f,
           __BIT(is->is_irq & 0x1f));

Index: sys/arch/evbarm/conf/GENERIC64
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/conf/GENERIC64,v
retrieving revision 1.103
diff -p -u -r1.103 GENERIC64
--- sys/arch/evbarm/conf/GENERIC64      25 Jul 2019 00:30:45 -0000      1.103
+++ sys/arch/evbarm/conf/GENERIC64      27 Jul 2019 13:09:18 -0000
@@ -506,4 +506,8 @@ vioscsi*    at virtio?              # Virtio SCSI devic
scsibus*       at scsi?
sd*            at scsibus? target ? lun ?      # SCSI disk drives

+# IPMI device
+ipmi_acpi*     at acpi?
+ipmi0          at ipmi_acpi?
+
cinclude "arch/evbarm/conf/GENERIC64.local"
Index: sys/arch/evbarm/rpi/vcprop.h
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/rpi/vcprop.h,v
retrieving revision 1.16
diff -p -u -r1.16 vcprop.h
--- sys/arch/evbarm/rpi/vcprop.h        17 Jun 2017 17:03:40 -0000      1.16
+++ sys/arch/evbarm/rpi/vcprop.h        27 Jul 2019 13:09:19 -0000
@@ -71,10 +71,19 @@ struct vcprop_tag {
#define VCPROPTAG_GET_TEMPERATURE      0x00030006
#define VCPROPTAG_GET_MAX_TEMPERATURE  0x0003000a

+#define VCPROPTAG_GET_DOMAINSTATE      0x00030030
+#define VCPROPTAG_SET_DOMAINSTATE      0x00038030
+
+#define VCPROPTAG_GET_OTP              0x00030021
+#define VCPROPTAG_SET_OTP              0x00038021
+
+#define VCPROPTAG_SET_SDHOST_CLOCK     0x00038042
+
#define        VCPROPTAG_GET_CMDLINE           0x00050001
#define        VCPROPTAG_GET_DMACHAN           0x00060001

#define        VCPROPTAG_ALLOCATE_BUFFER       0x00040001
+#define        VCPROPTAG_RELEASE_BUFFER        0x00048001
#define        VCPROPTAG_BLANK_SCREEN          0x00040002
#define        VCPROPTAG_GET_FB_RES            0x00040003
#define        VCPROPTAG_SET_FB_RES            0x00048003
@@ -87,6 +96,18 @@ struct vcprop_tag {
#define        VCPROPTAG_GET_FB_ALPHA_MODE     0x00040007
#define        VCPROPTAG_SET_FB_ALPHA_MODE     0x00048007
#define        VCPROPTAG_GET_FB_PITCH          0x00040008
+#define        VCPROPTAG_GET_VIRTUAL_OFFSET    0x00040009
+#define        VCPROPTAG_SET_VIRTUAL_OFFSET    0x00048009
+#define        VCPROPTAG_GET_OVERSCAN          0x0004000a
+#define        VCPROPTAG_SET_OVERSCAN          0x0004800a
+#define        VCPROPTAG_GET_PALETTE           0x0004000b
+#define        VCPROPTAG_SET_PALETTE           0x0004800b
+#define        VCPROPTAG_SET_VSYNC             0x0004800e
+#define        VCPROPTAG_GET_TOUCHBUF          0x0004000f
+#define        VCPROPTAG_GET_SET_BACKLIGHT     0x0004800f
+#define        VCPROPTAG_GET_GPIOVIRTBUF       0x00040010
+
+#define        VCPROPTAG_VCHIQ_INIT            0x00048010

#define        VCPROPTAG_GET_EDID_BLOCK        0x00030020

@@ -146,16 +167,25 @@ struct vcprop_tag_boardrev {
#define         RPI_MODEL_B_PI2        4
#define         RPI_MODEL_ALPHA        5
#define         RPI_MODEL_COMPUTE      6
-#define         RPI_MODEL_ZERO         7
#define         RPI_MODEL_B_PI3        8
-#define         RPI_MODEL_COMPUTE_PI3  9
-#define         RPI_MODEL_ZERO_W       10
+#define         RPI_MODEL_ZERO         9
+#define         RPI_MODEL_COMPUTE_PI3  10
+#define         RPI_MODEL_ZERO_W       12
+#define         RPI_MODEL_B_PLUS_PI3   13
#define        VCPROP_REV_PROCESSOR    __BITS(15,12)
#define         RPI_PROCESSOR_BCM2835  0
#define         RPI_PROCESSOR_BCM2836  1
#define         RPI_PROCESSOR_BCM2837  2
#define        VCPROP_REV_MANUF        __BITS(19,16)
+#define         RPI_MANUF_SONY         0
+#define         RPI_MANUF_EGOMAN       1
+#define         RPI_MANUF_QISDA        16
+#define         RPI_MANUF_EMBEST       2
+#define         RPI_MANUF_SONYJAPAN    3
#define        VCPROP_REV_MEMSIZE      __BITS(22,20)
+#define         RPI_MEMSIZE_256        0
+#define         RPI_MEMSIZE_512        1
+#define         RPI_MEMSIZE_1024       2
#define        VCPROP_REV_ENCFLAG      __BIT(23)
#define        VCPROP_REV_WARRANTY     __BITS(25,24)

@@ -179,6 +209,7 @@ struct vcprop_tag_boardserial {
#define        VCPROP_CLK_SDRAM        8
#define        VCPROP_CLK_PIXEL        9
#define        VCPROP_CLK_PWM          10
+#define        VCPROP_CLK_EMMC2        12

struct vcprop_clock {
       uint32_t pclk;
@@ -217,6 +248,13 @@ struct vcprop_tag_clockrate {
       uint32_t noturbo;
};

+struct vcprop_tag_sdhostclock {
+       struct vcprop_tag tag;
+       uint32_t clock;
+       uint32_t clock1;
+       uint32_t clock2;
+};
+
#define VCPROP_VOLTAGE_CORE    1
#define VCPROP_VOLTAGE_SDRAM_C 2
#define VCPROP_VOLTAGE_SDRAM_P 3
@@ -246,6 +284,30 @@ struct vcprop_tag_temperature {
#define        VCPROP_POWER_SPI        7
#define        VCPROP_POWER_CCP2TX     8

+#define VCPROP_DOMAIN_I2C0           1
+#define VCPROP_DOMAIN_I2C1           2
+#define VCPROP_DOMAIN_I2C2           3
+#define VCPROP_DOMAIN_VIDEO_SCALER   4
+#define VCPROP_DOMAIN_VPU1           5
+#define VCPROP_DOMAIN_HDMI           6
+#define VCPROP_DOMAIN_USB            7
+#define VCPROP_DOMAIN_VEC            8
+#define VCPROP_DOMAIN_JPEG           9
+#define VCPROP_DOMAIN_H264           10
+#define VCPROP_DOMAIN_V3D            11
+#define VCPROP_DOMAIN_ISP            12
+#define VCPROP_DOMAIN_UNICAM0        13
+#define VCPROP_DOMAIN_UNICAM1        14
+#define VCPROP_DOMAIN_CCP2RX         15
+#define VCPROP_DOMAIN_CSI2           16
+#define VCPROP_DOMAIN_CPI            17
+#define VCPROP_DOMAIN_DSI0           18
+#define VCPROP_DOMAIN_DSI1           19
+#define VCPROP_DOMAIN_TRANSPOSER     20
+#define VCPROP_DOMAIN_CCP2TX         21
+#define VCPROP_DOMAIN_CDP            22
+#define VCPROP_DOMAIN_ARM            23
+
struct vcprop_tag_powertiming {
       struct vcprop_tag tag;
       uint32_t id;
@@ -395,3 +457,6 @@ int rpi_fb_set_video(int);

int rpi_fb_movecursor(int, int, int);
int rpi_fb_initcursor(bus_addr_t, int, int);
+
+int rpi_set_domain(uint32_t, uint32_t);
+int rpi_get_domain(uint32_t, uint32_t *);
Index: sys/arch/evbarm/rpi/vcprop_subr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/rpi/vcprop_subr.c,v
retrieving revision 1.5
diff -p -u -r1.5 vcprop_subr.c
--- sys/arch/evbarm/rpi/vcprop_subr.c   1 Jan 2018 17:03:25 -0000       1.5
+++ sys/arch/evbarm/rpi/vcprop_subr.c   27 Jul 2019 13:09:19 -0000
@@ -391,3 +391,132 @@ rpi_fb_initcursor(bus_addr_t pixels, int

       return 0;
}
+
+int
+rpi_set_domain(uint32_t domain, uint32_t state)
+{
+       int error;
+       uint32_t tag, res;
+
+       tag = VCPROPTAG_SET_DOMAINSTATE;
+       if (domain == VCPROP_DOMAIN_USB) {
+               /* use old interface */
+               tag = VCPROPTAG_SET_POWERSTATE;
+               domain = VCPROP_POWER_USB;
+       }
+
+       /*
+        * might as well put it here since we need to re-init it every time
+        * and it's not like this is going to be called very often anyway
+        */
+       struct __aligned(16) {
+               struct vcprop_buffer_hdr        vb_hdr;
+               struct vcprop_tag_powerstate    vbt_power;
+               struct vcprop_tag end;
+       } vb_setpower =
+       {
+               .vb_hdr = {
+                       .vpb_len = sizeof(vb_setpower),
+                       .vpb_rcode = VCPROP_PROCESS_REQUEST,
+               },
+               .vbt_power = {
+                       .tag = {
+                               .vpt_tag = tag,
+                               .vpt_len = VCPROPTAG_LEN(vb_setpower.vbt_power),
+                               .vpt_rcode = VCPROPTAG_REQUEST,
+                       },
+                       .id = domain,
+                       .state = state
+               },
+               .end = {
+                       .vpt_tag = VCPROPTAG_NULL,
+               },
+       };
+
+       error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setpower,
+           sizeof(vb_setpower), &res);
+#ifdef RPI_IOCTL_DEBUG
+       printf("%s: %08x %08x %d %08x %08x %d %d %08x %08x\n", __func__,
+           tag, domain, state,
+           vb_setpower.vbt_power.tag.vpt_tag,
+           vb_setpower.vbt_power.id,
+           vb_setpower.vbt_power.state,
+           error, res,
+           vb_setpower.vbt_power.tag.vpt_rcode);
+#endif
+       if (error)
+               return error;
+
+       if (!vcprop_buffer_success_p(&vb_setpower.vb_hdr) ||
+           !vcprop_tag_success_p(&vb_setpower.vbt_power.tag)) {
+               return EIO;
+       }
+
+       return 0;
+}
+
+int
+rpi_get_domain(uint32_t domain, uint32_t *statep)
+{
+       int error;
+       uint32_t tag, res;
+
+       tag = VCPROPTAG_GET_DOMAINSTATE;
+       if (domain == VCPROP_DOMAIN_USB) {
+               /* use old interface */
+               tag = VCPROPTAG_GET_POWERSTATE;
+               domain = VCPROP_POWER_USB;
+       }
+
+       /*
+        * might as well put it here since we need to re-init it every time
+        * and it's not like this is going to be called very often anyway
+        */
+       struct __aligned(16) {
+               struct vcprop_buffer_hdr        vb_hdr;
+               struct vcprop_tag_powerstate    vbt_power;
+               struct vcprop_tag end;
+       } vb_setpower =
+       {
+               .vb_hdr = {
+                       .vpb_len = sizeof(vb_setpower),
+                       .vpb_rcode = VCPROP_PROCESS_REQUEST,
+               },
+               .vbt_power = {
+                       .tag = {
+                               .vpt_tag = tag,
+                               .vpt_len = VCPROPTAG_LEN(vb_setpower.vbt_power),
+                               .vpt_rcode = VCPROPTAG_REQUEST,
+                       },
+                       .id = domain,
+                       .state = ~0
+               },
+               .end = {
+                       .vpt_tag = VCPROPTAG_NULL,
+               },
+       };
+
+       error = bcmmbox_request(BCMMBOX_CHANARM2VC, &vb_setpower,
+           sizeof(vb_setpower), &res);
+#ifdef RPI_IOCTL_DEBUG
+       printf("%s: %08x %08x %d %08x %08x %d %d %08x %08x\n", __func__,
+           tag, domain, *statep,
+           vb_setpower.vbt_power.tag.vpt_tag,
+           vb_setpower.vbt_power.id,
+           vb_setpower.vbt_power.state,
+           error, res,
+           vb_setpower.vbt_power.tag.vpt_rcode);
+#endif
+       if (error)
+               return error;
+
+       if (!vcprop_buffer_success_p(&vb_setpower.vb_hdr) ||
+           !vcprop_tag_success_p(&vb_setpower.vbt_power.tag)) {
+               return EIO;
+       }
+
+       *statep = vb_setpower.vbt_power.state;
+
+       return 0;
+}
+
Index: sys/arch/aarch64/aarch64/aarch64_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/aarch64_machdep.c,v
retrieving revision 1.28
diff -p -u -r1.28 aarch64_machdep.c
--- sys/arch/aarch64/aarch64/aarch64_machdep.c  27 Jan 2019 02:08:36 -0000      1.28
+++ sys/arch/aarch64/aarch64/aarch64_machdep.c  27 Jul 2019 13:09:19 -0000
@@ -149,8 +149,10 @@ cpu_kernel_vm_init(uint64_t memory_start
        *
        * kernel image has mapped by L2 block. (2Mbyte)
        */
+printf("write protect %p .. %p\n", (void*)kernstart, (void*)data_start);
       pmapboot_protect(L2_TRUNC_BLOCK(kernstart),
           L2_TRUNC_BLOCK(data_start), VM_PROT_WRITE);
+printf("exec  protect %p .. %p\n", (void*)rodata_start, (void*)(kernend + kernend_extra));
       pmapboot_protect(L2_ROUND_BLOCK(rodata_start),
           L2_ROUND_BLOCK(kernend + kernend_extra), VM_PROT_EXECUTE);

Index: sys/arch/aarch64/aarch64/bus_space.c
===================================================================
RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/bus_space.c,v
retrieving revision 1.8
diff -p -u -r1.8 bus_space.c
--- sys/arch/aarch64/aarch64/bus_space.c        27 Jan 2019 02:08:36 -0000      1.8
+++ sys/arch/aarch64/aarch64/bus_space.c        27 Jul 2019 13:09:19 -0000
@@ -562,7 +562,7 @@ generic_bs_map(void *t, bus_addr_t bpa,
       else if ((flag & BUS_SPACE_MAP_CACHEABLE) != 0)
               pmapflags = PMAP_WRITE_BACK;
       else
-               pmapflags = PMAP_DEV;
+               pmapflags = PMAP_NOCACHE | PMAP_DEV;

       for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) {
               pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE, pmapflags);
Index: sys/arch/aarch64/aarch64/pmap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/pmap.c,v
retrieving revision 1.41
diff -p -u -r1.41 pmap.c
--- sys/arch/aarch64/aarch64/pmap.c     17 May 2019 06:05:07 -0000      1.41
+++ sys/arch/aarch64/aarch64/pmap.c     27 Jul 2019 13:09:19 -0000
@@ -279,10 +279,16 @@ pmap_map_chunk(vaddr_t va, paddr_t pa, v
       psize_t blocksize;
       int rc;

-       /* devmap always use L2 mapping */
-       blocksize = L2_SIZE;
+       /* devmap use L2 mapping when possible */
+       if (size % L2_SIZE == 0) {
+               blocksize = L2_SIZE;
+               attr = L2_BLOCK;
+       } else {
+               blocksize = L3_SIZE;
+               attr = L3_PAGE;
+       }

-       attr = _pmap_pte_adjust_prot(L2_BLOCK, prot, VM_PROT_ALL, false);
+       attr = _pmap_pte_adjust_prot(attr, prot, VM_PROT_ALL, false);
       attr = _pmap_pte_adjust_cacheflags(attr, flags | PMAP_DEV);
       /* user cannot execute, and kernel follows the prot */
       attr |= (LX_BLKPAG_UXN|LX_BLKPAG_PXN);
@@ -338,6 +344,7 @@ pmap_devmap_bootstrap(vaddr_t l0pt, cons
                   table[i].pd_prot,
                   table[i].pd_flags);
       }
+       VPRINTF("%s: done\n", __func__);
}

const struct pmap_devmap *
Index: sys/arch/aarch64/aarch64/pmapboot.c
===================================================================
RCS file: /cvsroot/src/sys/arch/aarch64/aarch64/pmapboot.c,v
retrieving revision 1.4
diff -p -u -r1.4 pmapboot.c
--- sys/arch/aarch64/aarch64/pmapboot.c 18 Jul 2019 06:47:36 -0000      1.4
+++ sys/arch/aarch64/aarch64/pmapboot.c 27 Jul 2019 13:09:19 -0000
@@ -87,6 +87,7 @@ pmapboot_protect(vaddr_t sva, vaddr_t ev
               else
                       pa = (reg_ttbr0_el1_read() & TTBR_BADDR);
               l0 = (pd_entry_t *)AARCH64_PA_TO_KVA(pa);
+printf("va %016lx -> pa %016lx -> l0 %016lx\n", (uint64_t)va, (uint64_t)pa, (uintptr_t)l0);

               idx = l0pde_index(va);
               if (!l0pde_valid(l0[idx]))
Index: sys/arch/aarch64/include/pmap.h
===================================================================
RCS file: /cvsroot/src/sys/arch/aarch64/include/pmap.h,v
retrieving revision 1.24
diff -p -u -r1.24 pmap.h
--- sys/arch/aarch64/include/pmap.h     8 Apr 2019 21:18:22 -0000       1.24
+++ sys/arch/aarch64/include/pmap.h     27 Jul 2019 13:09:19 -0000
@@ -196,18 +196,32 @@ paddr_t pmap_alloc_pdp(struct pmap *, st
#define L1_ROUND_BLOCK(x)      L1_TRUNC_BLOCK((x) + L1_SIZE - 1)
#define L2_TRUNC_BLOCK(x)      ((x) & L2_FRAME)
#define L2_ROUND_BLOCK(x)      L2_TRUNC_BLOCK((x) + L2_SIZE - 1)
+#define L3_TRUNC_BLOCK(x)      ((x) & L3_FRAME)
+#define L3_ROUND_BLOCK(x)      L3_TRUNC_BLOCK((x) + L3_SIZE - 1)

/* devmap use L2 blocks. (2Mbyte) */
#define DEVMAP_TRUNC_ADDR(x)   L2_TRUNC_BLOCK((x))
#define DEVMAP_ROUND_SIZE(x)   L2_ROUND_BLOCK((x))

+/* or L3 blocks. (pages) */
+#define DEVMAP_TRUNC_PAGE(x)   L3_TRUNC_BLOCK((x))
+#define DEVMAP_ROUND_PGSZ(x)   L3_ROUND_BLOCK((x))
+
#define        DEVMAP_ENTRY(va, pa, sz)                        \
       {                                               \
               .pd_va = DEVMAP_TRUNC_ADDR(va),         \
               .pd_pa = DEVMAP_TRUNC_ADDR(pa),         \
               .pd_size = DEVMAP_ROUND_SIZE(sz),       \
               .pd_prot = VM_PROT_READ|VM_PROT_WRITE,  \
-               .pd_flags = PMAP_NOCACHE                \
+               .pd_flags = PMAP_NOCACHE|PMAP_DEV       \
+       }
+#define        DEVMAP_ENTRY_PAGES(va, pa, sz)                  \
+       {                                               \
+               .pd_va = DEVMAP_TRUNC_PAGE(va),         \
+               .pd_pa = DEVMAP_TRUNC_PAGE(pa),         \
+               .pd_size = DEVMAP_ROUND_PGSZ(sz),       \
+               .pd_prot = VM_PROT_READ|VM_PROT_WRITE,  \
+               .pd_flags = PMAP_NOCACHE|PMAP_DEV       \
       }
#define        DEVMAP_ENTRY_END        { 0 }

@@ -247,7 +261,7 @@ aarch64_mmap_flags(paddr_t mdpgno)
       nflag = (mdpgno >> AARCH64_MMAP_FLAG_SHIFT) & AARCH64_MMAP_FLAG_MASK;
       switch (nflag) {
       case AARCH64_MMAP_DEVICE:
-               pflag = PMAP_DEV;
+               pflag = PMAP_NOCACHE | PMAP_DEV;
               break;
       case AARCH64_MMAP_WRITECOMBINE:
               pflag = PMAP_WRITE_COMBINE;
Index: sys/dev/sdmmc/sdhc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sdmmc/sdhc.c,v
retrieving revision 1.103
diff -p -u -r1.103 sdhc.c
--- sys/dev/sdmmc/sdhc.c        3 Jul 2019 23:10:08 -0000       1.103
+++ sys/dev/sdmmc/sdhc.c        27 Jul 2019 13:09:19 -0000
@@ -52,7 +52,7 @@ void  sdhc_dump_regs(struct sdhc_host *);
#define DPRINTF(n,s)   do {} while (0)
#endif

-#define SDHC_COMMAND_TIMEOUT   hz
+#define SDHC_COMMAND_TIMEOUT   (hz*3)
#define SDHC_BUFFER_TIMEOUT    hz
#define SDHC_TRANSFER_TIMEOUT  hz
#define SDHC_DMA_TIMEOUT       (hz*3)
Index: sys/dev/sdmmc/sdmmc.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sdmmc/sdmmc.c,v
retrieving revision 1.36
diff -p -u -r1.36 sdmmc.c
--- sys/dev/sdmmc/sdmmc.c       6 Nov 2018 16:01:38 -0000       1.36
+++ sys/dev/sdmmc/sdmmc.c       27 Jul 2019 13:09:19 -0000
@@ -246,7 +246,7 @@ sdmmc_doattach(device_t dev)
{
       struct sdmmc_softc *sc = device_private(dev);

-       if (kthread_create(PRI_SOFTBIO, 0, NULL,
+       if (kthread_create(PRI_BIO, 0, NULL,
           sdmmc_task_thread, sc, &sc->sc_tskq_lwp, "%s", device_xname(dev))) {
               aprint_error_dev(dev, "couldn't create task thread\n");
       }
Index: sys/dev/sdmmc/sdmmc_cis.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sdmmc/sdmmc_cis.c,v
retrieving revision 1.5
diff -p -u -r1.5 sdmmc_cis.c
--- sys/dev/sdmmc/sdmmc_cis.c   28 Jan 2018 14:34:06 -0000      1.5
+++ sys/dev/sdmmc/sdmmc_cis.c   27 Jul 2019 13:09:21 -0000
@@ -259,6 +259,11 @@ sdmmc_read_cis(struct sdmmc_function *sf
                       reg += tpllen;
                       break;

+               case PCMCIA_CISTPL_SDIO:
+                       aprint_normal_dev(dev, "SDIO function\n");
+                       reg += tpllen;
+                       break;
+
               default:
                       /*
                        * Tuple codes between 80h-8Fh are vendor unique.
Index: sys/dev/sdmmc/sdmmc_mem.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sdmmc/sdmmc_mem.c,v
retrieving revision 1.68
diff -p -u -r1.68 sdmmc_mem.c
--- sys/dev/sdmmc/sdmmc_mem.c   6 Jun 2019 20:50:46 -0000       1.68
+++ sys/dev/sdmmc/sdmmc_mem.c   27 Jul 2019 13:09:22 -0000
@@ -201,12 +201,14 @@ mmc_mode:

       /* Set the lowest voltage supported by the card and host. */
       host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch);
+#if 0
       error = sdmmc_set_bus_power(sc, host_ocr, card_ocr);
       if (error) {
               DPRINTF(("%s: couldn't supply voltage requested by card\n",
                   SDMMCDEVNAME(sc)));
               goto out;
       }
+#endif

       DPRINTF(("%s: host_ocr 0x%08x\n", SDMMCDEVNAME(sc), host_ocr));
       DPRINTF(("%s: card_ocr 0x%08x\n", SDMMCDEVNAME(sc), card_ocr));