All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [PULL 25/45] hw/arm/bcm2838: Add GIC-400 to BCM2838 SoC
Date: Tue, 27 Feb 2024 13:32:54 +0000	[thread overview]
Message-ID: <20240227133314.1721857-26-peter.maydell@linaro.org> (raw)
In-Reply-To: <20240227133314.1721857-1-peter.maydell@linaro.org>

From: Sergey Kambalin <serg.oker@gmail.com>

Signed-off-by: Sergey Kambalin <sergey.kambalin@auriga.com>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20240226000259.2752893-6-sergey.kambalin@auriga.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
---
 include/hw/arm/bcm2838.h             |   2 +
 include/hw/arm/bcm2838_peripherals.h |  37 ++++++
 hw/arm/bcm2838.c                     | 167 ++++++++++++++++++++++++++-
 hw/arm/trace-events                  |   3 +
 4 files changed, 207 insertions(+), 2 deletions(-)

diff --git a/include/hw/arm/bcm2838.h b/include/hw/arm/bcm2838.h
index bddc25ca9af..e53c7bedf92 100644
--- a/include/hw/arm/bcm2838.h
+++ b/include/hw/arm/bcm2838.h
@@ -10,6 +10,7 @@
 #define BCM2838_H
 
 #include "hw/arm/bcm2836.h"
+#include "hw/intc/arm_gic.h"
 #include "hw/arm/bcm2838_peripherals.h"
 
 #define BCM2838_PERI_LOW_BASE 0xfc000000
@@ -24,6 +25,7 @@ struct BCM2838State {
     BCM283XBaseState parent_obj;
     /*< public >*/
     BCM2838PeripheralState peripherals;
+    GICState gic;
 };
 
 #endif /* BCM2838_H */
diff --git a/include/hw/arm/bcm2838_peripherals.h b/include/hw/arm/bcm2838_peripherals.h
index 7039b67cc96..d07831753ab 100644
--- a/include/hw/arm/bcm2838_peripherals.h
+++ b/include/hw/arm/bcm2838_peripherals.h
@@ -11,6 +11,39 @@
 
 #include "hw/arm/bcm2835_peripherals.h"
 
+/* SPI */
+#define GIC_SPI_INTERRUPT_MBOX         33
+#define GIC_SPI_INTERRUPT_MPHI         40
+#define GIC_SPI_INTERRUPT_DWC2         73
+#define GIC_SPI_INTERRUPT_DMA_0        80
+#define GIC_SPI_INTERRUPT_DMA_6        86
+#define GIC_SPI_INTERRUPT_DMA_7_8      87
+#define GIC_SPI_INTERRUPT_DMA_9_10     88
+#define GIC_SPI_INTERRUPT_AUX_UART1    93
+#define GIC_SPI_INTERRUPT_SDHOST       120
+#define GIC_SPI_INTERRUPT_UART0        121
+#define GIC_SPI_INTERRUPT_RNG200       125
+#define GIC_SPI_INTERRUPT_EMMC_EMMC2   126
+#define GIC_SPI_INTERRUPT_PCI_INT_A    143
+#define GIC_SPI_INTERRUPT_GENET_A      157
+#define GIC_SPI_INTERRUPT_GENET_B      158
+
+
+/* GPU (legacy) DMA interrupts */
+#define GPU_INTERRUPT_DMA0      16
+#define GPU_INTERRUPT_DMA1      17
+#define GPU_INTERRUPT_DMA2      18
+#define GPU_INTERRUPT_DMA3      19
+#define GPU_INTERRUPT_DMA4      20
+#define GPU_INTERRUPT_DMA5      21
+#define GPU_INTERRUPT_DMA6      22
+#define GPU_INTERRUPT_DMA7_8    23
+#define GPU_INTERRUPT_DMA9_10   24
+#define GPU_INTERRUPT_DMA11     25
+#define GPU_INTERRUPT_DMA12     26
+#define GPU_INTERRUPT_DMA13     27
+#define GPU_INTERRUPT_DMA14     28
+#define GPU_INTERRUPT_DMA15     31
 
 #define TYPE_BCM2838_PERIPHERALS "bcm2838-peripherals"
 OBJECT_DECLARE_TYPE(BCM2838PeripheralState, BCM2838PeripheralClass,
@@ -24,6 +57,10 @@ struct BCM2838PeripheralState {
     MemoryRegion peri_low_mr;
     MemoryRegion peri_low_mr_alias;
     MemoryRegion mphi_mr_alias;
+
+    OrIRQState mmc_irq_orgate;
+    OrIRQState dma_7_8_irq_orgate;
+    OrIRQState dma_9_10_irq_orgate;
 };
 
 struct BCM2838PeripheralClass {
diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c
index 05281e247fe..332e906a84f 100644
--- a/hw/arm/bcm2838.c
+++ b/hw/arm/bcm2838.c
@@ -14,8 +14,36 @@
 #include "hw/arm/bcm2838.h"
 #include "trace.h"
 
+#define GIC400_MAINTENANCE_IRQ      9
+#define GIC400_TIMER_NS_EL2_IRQ     10
+#define GIC400_TIMER_VIRT_IRQ       11
+#define GIC400_LEGACY_FIQ           12
+#define GIC400_TIMER_S_EL1_IRQ      13
+#define GIC400_TIMER_NS_EL1_IRQ     14
+#define GIC400_LEGACY_IRQ           15
+
+/* Number of external interrupt lines to configure the GIC with */
+#define GIC_NUM_IRQS                192
+
+#define PPI(cpu, irq) (GIC_NUM_IRQS + (cpu) * GIC_INTERNAL + GIC_NR_SGIS + irq)
+
+#define GIC_BASE_OFS                0x0000
+#define GIC_DIST_OFS                0x1000
+#define GIC_CPU_OFS                 0x2000
+#define GIC_VIFACE_THIS_OFS         0x4000
+#define GIC_VIFACE_OTHER_OFS(cpu)  (0x5000 + (cpu) * 0x200)
+#define GIC_VCPU_OFS                0x6000
+
 #define VIRTUAL_PMU_IRQ 7
 
+static void bcm2838_gic_set_irq(void *opaque, int irq, int level)
+{
+    BCM2838State *s = (BCM2838State *)opaque;
+
+    trace_bcm2838_gic_set_irq(irq, level);
+    qemu_set_irq(qdev_get_gpio_in(DEVICE(&s->gic), irq), level);
+}
+
 static void bcm2838_init(Object *obj)
 {
     BCM2838State *s = BCM2838(obj);
@@ -28,11 +56,12 @@ static void bcm2838_init(Object *obj)
                               "vcram-size");
     object_property_add_alias(obj, "command-line", OBJECT(&s->peripherals),
                               "command-line");
+
+    object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GIC);
 }
 
 static void bcm2838_realize(DeviceState *dev, Error **errp)
 {
-    int n;
     BCM2838State *s = BCM2838(dev);
     BCM283XBaseState *s_base = BCM283X_BASE(dev);
     BCM283XBaseClass *bc_base = BCM283X_BASE_GET_CLASS(dev);
@@ -40,6 +69,8 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
     BCMSocPeripheralBaseState *ps_base =
         BCM_SOC_PERIPHERALS_BASE(&s->peripherals);
 
+    DeviceState *gicdev = NULL;
+
     if (!bcm283x_common_realize(dev, ps_base, errp)) {
         return;
     }
@@ -52,11 +83,15 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s_base->control), 0, bc_base->ctrl_base);
 
     /* Create cores */
-    for (n = 0; n < bc_base->core_count; n++) {
+    for (int n = 0; n < bc_base->core_count; n++) {
 
         object_property_set_int(OBJECT(&s_base->cpu[n].core), "mp-affinity",
                                 (bc_base->clusterid << 8) | n, &error_abort);
 
+        /* set periphbase/CBAR value for CPU-local registers */
+        object_property_set_int(OBJECT(&s_base->cpu[n].core), "reset-cbar",
+                                bc_base->peri_base, &error_abort);
+
         /* start powered off if not enabled */
         object_property_set_bool(OBJECT(&s_base->cpu[n].core),
                                  "start-powered-off",
@@ -66,6 +101,134 @@ static void bcm2838_realize(DeviceState *dev, Error **errp)
             return;
         }
     }
+
+    if (!object_property_set_uint(OBJECT(&s->gic), "revision", 2, errp)) {
+        return;
+    }
+
+    if (!object_property_set_uint(OBJECT(&s->gic), "num-cpu", BCM283X_NCPUS,
+                                  errp)) {
+        return;
+    }
+
+    if (!object_property_set_uint(OBJECT(&s->gic), "num-irq",
+                                  GIC_NUM_IRQS + GIC_INTERNAL, errp)) {
+        return;
+    }
+
+    if (!object_property_set_bool(OBJECT(&s->gic),
+                                  "has-virtualization-extensions", true,
+                                  errp)) {
+        return;
+    }
+
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
+        return;
+    }
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 0,
+                    bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_DIST_OFS);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1,
+                    bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_CPU_OFS);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 2,
+                    bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_VIFACE_THIS_OFS);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 3,
+                    bc_base->ctrl_base + BCM2838_GIC_BASE + GIC_VCPU_OFS);
+
+    for (int n = 0; n < BCM283X_NCPUS; n++) {
+        sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 4 + n,
+                        bc_base->ctrl_base + BCM2838_GIC_BASE
+                            + GIC_VIFACE_OTHER_OFS(n));
+    }
+
+    gicdev = DEVICE(&s->gic);
+
+    for (int n = 0; n < BCM283X_NCPUS; n++) {
+        DeviceState *cpudev = DEVICE(&s_base->cpu[n]);
+
+        /* Connect the GICv2 outputs to the CPU */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + BCM283X_NCPUS,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + 2 * BCM283X_NCPUS,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + 3 * BCM283X_NCPUS,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), n + 4 * BCM283X_NCPUS,
+                           qdev_get_gpio_in(gicdev,
+                                            PPI(n, GIC400_MAINTENANCE_IRQ)));
+
+        /* Connect timers from the CPU to the interrupt controller */
+        qdev_connect_gpio_out(cpudev, GTIMER_PHYS,
+                    qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_NS_EL1_IRQ)));
+        qdev_connect_gpio_out(cpudev, GTIMER_VIRT,
+                    qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_VIRT_IRQ)));
+        qdev_connect_gpio_out(cpudev, GTIMER_HYP,
+                    qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_NS_EL2_IRQ)));
+        qdev_connect_gpio_out(cpudev, GTIMER_SEC,
+                    qdev_get_gpio_in(gicdev, PPI(n, GIC400_TIMER_S_EL1_IRQ)));
+        /* PMU interrupt */
+        qdev_connect_gpio_out_named(cpudev, "pmu-interrupt", 0,
+                    qdev_get_gpio_in(gicdev, PPI(n, VIRTUAL_PMU_IRQ)));
+    }
+
+    /* Connect UART0 to the interrupt controller */
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->uart0), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_UART0));
+
+    /* Connect AUX / UART1 to the interrupt controller */
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->aux), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_AUX_UART1));
+
+    /* Connect VC mailbox to the interrupt controller */
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->mboxes), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_MBOX));
+
+    /* Connect SD host to the interrupt controller */
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->sdhost), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_SDHOST));
+
+    /* According to DTS, EMMC and EMMC2 share one irq */
+    DeviceState *mmc_irq_orgate = DEVICE(&ps->mmc_irq_orgate);
+
+    /* Connect EMMC and EMMC2 to the interrupt controller */
+    qdev_connect_gpio_out(mmc_irq_orgate, 0,
+                          qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_EMMC_EMMC2));
+
+    /* Connect USB OTG and MPHI to the interrupt controller */
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->mphi), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_MPHI));
+    sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->dwc2), 0,
+                       qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DWC2));
+
+    /* Connect DMA 0-6 to the interrupt controller */
+    for (int n = GIC_SPI_INTERRUPT_DMA_0; n <= GIC_SPI_INTERRUPT_DMA_6; n++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(&ps_base->dma),
+                           n - GIC_SPI_INTERRUPT_DMA_0,
+                           qdev_get_gpio_in(gicdev, n));
+    }
+
+    /* According to DTS, DMA 7 and 8 share one irq */
+    DeviceState *dma_7_8_irq_orgate = DEVICE(&ps->dma_7_8_irq_orgate);
+
+    /* Connect DMA 7-8 to the interrupt controller */
+    qdev_connect_gpio_out(dma_7_8_irq_orgate, 0,
+                          qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DMA_7_8));
+
+    /* According to DTS, DMA 9 and 10 share one irq */
+    DeviceState *dma_9_10_irq_orgate = DEVICE(&ps->dma_9_10_irq_orgate);
+
+    /* Connect DMA 9-10 to the interrupt controller */
+    qdev_connect_gpio_out(dma_9_10_irq_orgate, 0,
+                          qdev_get_gpio_in(gicdev, GIC_SPI_INTERRUPT_DMA_9_10));
+
+    /* Pass through inbound GPIO lines to the GIC */
+    qdev_init_gpio_in(dev, bcm2838_gic_set_irq, GIC_NUM_IRQS);
+
+    /* Pass through outbound IRQ lines from the GIC */
+    qdev_pass_gpios(DEVICE(&s->gic), DEVICE(&s->peripherals), NULL);
 }
 
 static void bcm2838_class_init(ObjectClass *oc, void *data)
diff --git a/hw/arm/trace-events b/hw/arm/trace-events
index fd0d92762e4..f1a54a02dfc 100644
--- a/hw/arm/trace-events
+++ b/hw/arm/trace-events
@@ -70,3 +70,6 @@ z2_aer915_event(int8_t event, int8_t len) "i2c event =0x%x len=%d bytes"
 xen_create_virtio_mmio_devices(int i, int irq, uint64_t base) "Created virtio-mmio device %d: irq %d base 0x%"PRIx64
 xen_init_ram(uint64_t machine_ram_size) "Initialized xen ram with size 0x%"PRIx64
 xen_enable_tpm(uint64_t addr) "Connected tpmdev at address 0x%"PRIx64
+
+# bcm2838.c
+bcm2838_gic_set_irq(int irq, int level) "gic irq:%d lvl:%d"
-- 
2.34.1



  parent reply	other threads:[~2024-02-27 13:44 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-27 13:32 [PULL 00/45] target-arm queue Peter Maydell
2024-02-27 13:32 ` [PULL 01/45] hw/arm/sbsa-ref: Simplify init since PCIe is always enabled Peter Maydell
2024-02-27 13:32 ` [PULL 02/45] target/arm: Advertise Cortex-A53 erratum #843419 fix via REVIDR Peter Maydell
2024-02-27 13:32 ` [PULL 03/45] MAINTAINERS: Cover hw/ide/ahci-allwinner.c with AllWinner A10 machine Peter Maydell
2024-02-27 13:32 ` [PULL 04/45] misc: m48t59: replace qemu_system_reset_request() call with watchdog_perform_action() Peter Maydell
2024-02-27 13:32 ` [PULL 05/45] misc: pxa2xx_timer: " Peter Maydell
2024-02-27 13:32 ` [PULL 06/45] xlnx-versal-ospi: disable reentrancy detection for iomem_dac Peter Maydell
2024-02-27 13:32 ` [PULL 07/45] hw/arm: Use TYPE_OR_IRQ when connecting STM32L4x5 EXTI fan-in IRQs Peter Maydell
2024-02-27 13:32 ` [PULL 08/45] tests/qtest: Check that EXTI fan-in irqs are correctly connected Peter Maydell
2024-02-27 13:32 ` [PULL 09/45] pl031: Update last RTCLR value on write in case it's read back Peter Maydell
2024-02-27 13:32 ` [PULL 10/45] block: m25p80: Add support of mt35xu02gbba Peter Maydell
2024-02-27 13:32 ` [PULL 11/45] arm: xlnx-versal-virt: Add machine property ospi-flash Peter Maydell
2024-02-27 13:32 ` [PULL 12/45] arm/ptw: Handle atomic updates of page tables entries in MMIO during PTW Peter Maydell
2024-02-27 13:32 ` [PULL 13/45] system/bootdevice: Don't unregister reset handler in restore_boot_order() Peter Maydell
2024-02-27 13:32 ` [PULL 14/45] include/qom/object.h: New OBJECT_DEFINE_SIMPLE_TYPE{, _WITH_INTERFACES} macros Peter Maydell
2024-02-27 13:32 ` [PULL 15/45] hw/core: Add documentation and license comments to reset.h Peter Maydell
2024-02-27 13:32 ` [PULL 16/45] hw/core: Add ResetContainer which holds objects implementing Resettable Peter Maydell
2024-02-27 13:32 ` [PULL 17/45] hw/core/reset: Add qemu_{register, unregister}_resettable() Peter Maydell
2024-02-27 13:32 ` [PULL 18/45] hw/core/reset: Implement qemu_register_reset via qemu_register_resettable Peter Maydell
2024-02-27 13:32 ` [PULL 19/45] hw/core/machine: Use qemu_register_resettable for sysbus reset Peter Maydell
2024-02-27 13:32 ` [PULL 20/45] docs/devel/reset: Update to discuss system reset Peter Maydell
2024-02-27 13:32 ` [PULL 21/45] hw/arm/bcm2836: Split out common part of BCM283X classes Peter Maydell
2024-02-27 13:32 ` [PULL 22/45] hw/arm/bcm2853_peripherals: Split out common part of peripherals Peter Maydell
2024-02-27 13:32 ` [PULL 23/45] hw/arm/raspi: Split out raspi machine common part Peter Maydell
2024-02-27 13:32 ` [PULL 24/45] hw/arm: Introduce BCM2838 SoC Peter Maydell
2024-02-27 13:32 ` Peter Maydell [this message]
2024-02-27 13:32 ` [PULL 26/45] hw/gpio: Add BCM2838 GPIO stub Peter Maydell
2024-02-27 13:32 ` [PULL 27/45] hw/gpio: Implement BCM2838 GPIO functionality Peter Maydell
2024-02-27 13:32 ` [PULL 28/45] hw/gpio: Connect SD controller to BCM2838 GPIO Peter Maydell
2024-02-27 13:32 ` [PULL 29/45] hw/arm: Add GPIO and SD to BCM2838 periph Peter Maydell
2024-02-27 13:32 ` [PULL 30/45] hw/arm: Introduce Raspberry PI 4 machine Peter Maydell
2024-02-27 13:33 ` [PULL 31/45] hw/arm/raspi4b: Temporarily disable unimplemented rpi4b devices Peter Maydell
2024-02-27 13:33 ` [PULL 32/45] hw/arm: Add memory region for BCM2837 RPiVid ASB Peter Maydell
2024-02-27 13:33 ` [PULL 33/45] hw/arm/bcm2838_peripherals: Add clock_isp stub Peter Maydell
2024-02-27 13:33 ` [PULL 34/45] tests/avocado/boot_linux_console.py: Add Rpi4b boot tests Peter Maydell
2024-02-27 13:33 ` [PULL 35/45] tests/qtest: Add bcm2838 mailbox test stub Peter Maydell
2024-02-27 13:33 ` [PULL 36/45] tests/qtest/bcm2828-mailbox: Add mailbox test constants Peter Maydell
2024-02-27 13:33 ` [PULL 37/45] tests/qtest/bcm2828-mailbox: Add mailbox tests tags. Part 1 Peter Maydell
2024-02-27 13:33 ` [PULL 38/45] tests/qtest/bcm2828-mailbox: Add mailbox tests tags. Part 2 Peter Maydell
2024-02-27 13:33 ` [PULL 39/45] tests/qtest/bcm2828-mailbox: Add mailbox tests tags. Part 3 Peter Maydell
2024-02-27 13:33 ` [PULL 40/45] tests/qtest/bcm2828-mailbox: Add mailbox property tests. Part 1 Peter Maydell
2024-02-27 13:33 ` [PULL 41/45] tests/qtest/bcm2828-mailbox: Add mailbox property tests. Part 2 Peter Maydell
2024-02-27 13:33 ` [PULL 42/45] tests/qtest/bcm2828-mailbox: Add mailbox property tests. Part 3 Peter Maydell
2024-02-27 13:33 ` [PULL 43/45] hw/misc/bcm2835_property: Add missed BCM2835 properties Peter Maydell
2024-02-27 13:33 ` [PULL 44/45] tests/qtest/bcm2828-mailbox: Append added properties to mailbox test Peter Maydell
2024-02-27 13:33 ` [PULL 45/45] docs/system/arm: Add RPi4B to raspi.rst Peter Maydell

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240227133314.1721857-26-peter.maydell@linaro.org \
    --to=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.