aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arm/allwinner/a10_machdep.c11
-rw-r--r--sys/arm/arm/machdep.c11
-rw-r--r--sys/arm/arm/platform.c179
-rw-r--r--sys/arm/arm/platform_if.m116
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_machdep.c36
-rw-r--r--sys/arm/conf/RPI-B1
-rw-r--r--sys/arm/freescale/imx/imx51_machdep.c11
-rw-r--r--sys/arm/freescale/imx/imx53_machdep.c12
-rw-r--r--sys/arm/freescale/imx/imx6_machdep.c11
-rw-r--r--sys/arm/freescale/vybrid/vf_machdep.c11
-rw-r--r--sys/arm/include/machdep.h34
-rw-r--r--sys/arm/include/platform.h38
-rw-r--r--sys/arm/include/platformvar.h104
-rw-r--r--sys/arm/lpc/lpc_machdep.c11
-rw-r--r--sys/arm/mv/mv_machdep.c13
-rw-r--r--sys/arm/rockchip/rk30xx_machdep.c11
-rw-r--r--sys/arm/samsung/exynos/exynos5_machdep.c11
-rw-r--r--sys/arm/tegra/tegra2_machdep.c11
-rw-r--r--sys/arm/ti/ti_machdep.c11
-rw-r--r--sys/arm/versatile/versatile_machdep.c11
-rw-r--r--sys/arm/xilinx/zy7_machdep.c11
-rw-r--r--sys/conf/files.arm3
-rw-r--r--sys/conf/options.arm1
-rw-r--r--sys/dev/fdt/fdt_arm_platform.c72
24 files changed, 619 insertions, 122 deletions
diff --git a/sys/arm/allwinner/a10_machdep.c b/sys/arm/allwinner/a10_machdep.c
index c0a6ac86ab4a..718ced77dba2 100644
--- a/sys/arm/allwinner/a10_machdep.c
+++ b/sys/arm/allwinner/a10_machdep.c
@@ -45,30 +45,31 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <dev/fdt/fdt_common.h>
#include <arm/allwinner/a10_wdog.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -83,7 +84,7 @@ initarm_late_init(void)
* perhaps a 1MB block would be more appropriate.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(0x01C00000, 0x00400000); /* 4MB */
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 51c3028805b7..b61d5552ff73 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -98,6 +98,7 @@ __FBSDID("$FreeBSD$");
#include <machine/metadata.h>
#include <machine/pcb.h>
#include <machine/physmem.h>
+#include <machine/platform.h>
#include <machine/reg.h>
#include <machine/trap.h>
#include <machine/undefined.h>
@@ -1091,7 +1092,7 @@ initarm(struct arm_boot_params *abp)
EXFLAG_NODUMP | EXFLAG_NOALLOC);
/* Platform-specific initialisation */
- initarm_early_init();
+ platform_probe_and_attach();
pcpu0_init();
@@ -1207,9 +1208,9 @@ initarm(struct arm_boot_params *abp)
VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, PTE_CACHE);
/* Establish static device mappings. */
- err_devmap = initarm_devmap_init();
+ err_devmap = platform_devmap_init();
arm_devmap_bootstrap(l1pagetable, NULL);
- vm_max_kernel_address = initarm_lastaddr();
+ vm_max_kernel_address = platform_lastaddr();
cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT);
pmap_pa = kernel_l1pt.pv_pa;
@@ -1229,7 +1230,7 @@ initarm(struct arm_boot_params *abp)
*/
OF_interpret("perform-fixup", 0);
- initarm_gpio_init();
+ platform_gpio_init();
cninit();
@@ -1247,7 +1248,7 @@ initarm(struct arm_boot_params *abp)
printf("WARNING: could not fully configure devmap, error=%d\n",
err_devmap);
- initarm_late_init();
+ platform_late_init();
/*
* Pages were allocated during the secondary bootstrap for the
diff --git a/sys/arm/arm/platform.c b/sys/arm/arm/platform.c
new file mode 100644
index 000000000000..c744d7ec654e
--- /dev/null
+++ b/sys/arm/arm/platform.c
@@ -0,0 +1,179 @@
+/*-
+ * Copyright (c) 2005 Peter Grehan
+ * Copyright (c) 2009 Nathan Whitehorn
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/*
+ * Dispatch platform calls to the appropriate platform implementation
+ * through a previously registered kernel object.
+ */
+
+#define _ARM32_BUS_DMA_PRIVATE
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/ktr.h>
+#include <sys/mutex.h>
+#include <sys/rman.h>
+#include <sys/systm.h>
+#include <sys/smp.h>
+#include <sys/sysctl.h>
+#include <sys/types.h>
+
+#include <vm/vm.h>
+#include <vm/vm_page.h>
+
+#include <machine/bus_dma.h>
+#include <machine/cpu.h>
+#include <machine/intr.h>
+#include <machine/md_var.h>
+#include <machine/platform.h>
+#include <machine/platformvar.h>
+#include <machine/smp.h>
+
+#include "platform_if.h"
+
+static platform_def_t *plat_def_impl;
+static platform_t plat_obj;
+static struct kobj_ops plat_kernel_kops;
+static struct platform_kobj plat_kernel_obj;
+
+static char plat_name[64] = "";
+SYSCTL_STRING(_hw, OID_AUTO, platform, CTLFLAG_RDTUN, plat_name, 0,
+ "Platform currently in use");
+
+/*
+ * Platform install routines. Highest priority wins, using the same
+ * algorithm as bus attachment.
+ */
+SET_DECLARE(platform_set, platform_def_t);
+
+void
+platform_probe_and_attach(void)
+{
+ platform_def_t **platpp, *platp;
+ int prio, best_prio;
+
+ plat_obj = &plat_kernel_obj;
+ best_prio = 0;
+
+ /*
+ * We are unable to use TUNABLE_STR as the read will happen
+ * well after this function has returned.
+ */
+ TUNABLE_STR_FETCH("hw.platform", plat_name, sizeof(plat_name));
+
+ /*
+ * Try to locate the best platform kobj
+ */
+ SET_FOREACH(platpp, platform_set) {
+ platp = *platpp;
+
+ /*
+ * Take care of compiling the selected class, and
+ * then statically initialise the MMU object
+ */
+ kobj_class_compile_static(platp, &plat_kernel_kops);
+ kobj_init_static((kobj_t)plat_obj, platp);
+
+ plat_obj->cls = platp;
+
+ prio = PLATFORM_PROBE(plat_obj);
+
+ /* Check for errors */
+ if (prio > 0)
+ continue;
+
+ /*
+ * Check if this module was specifically requested through
+ * the loader tunable we provide.
+ */
+ if (strcmp(platp->name,plat_name) == 0) {
+ plat_def_impl = platp;
+ break;
+ }
+
+ /* Otherwise, see if it is better than our current best */
+ if (plat_def_impl == NULL || prio > best_prio) {
+ best_prio = prio;
+ plat_def_impl = platp;
+ }
+
+ /*
+ * We can't free the KOBJ, since it is static. Reset the ops
+ * member of this class so that we can come back later.
+ */
+ platp->ops = NULL;
+ }
+
+ if (plat_def_impl == NULL)
+ panic("No platform module found!");
+
+ /*
+ * Recompile to make sure we ended with the
+ * correct one, and then attach.
+ */
+
+ kobj_class_compile_static(plat_def_impl, &plat_kernel_kops);
+ kobj_init_static((kobj_t)plat_obj, plat_def_impl);
+
+ strlcpy(plat_name,plat_def_impl->name,sizeof(plat_name));
+
+ PLATFORM_ATTACH(plat_obj);
+}
+
+int
+platform_devmap_init(void)
+{
+
+ return PLATFORM_DEVMAP_INIT(plat_obj);
+}
+
+vm_offset_t
+platform_lastaddr(void)
+{
+
+ return PLATFORM_LASTADDR(plat_obj);
+}
+
+void
+platform_gpio_init(void)
+{
+
+ PLATFORM_GPIO_INIT(plat_obj);
+}
+
+void
+platform_late_init(void)
+{
+
+ PLATFORM_LATE_INIT(plat_obj);
+}
+
diff --git a/sys/arm/arm/platform_if.m b/sys/arm/arm/platform_if.m
new file mode 100644
index 000000000000..8eaa3d3031b6
--- /dev/null
+++ b/sys/arm/arm/platform_if.m
@@ -0,0 +1,116 @@
+#-
+# Copyright (c) 2009 Nathan Whitehorn
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+# $FreeBSD$
+#
+
+#include <sys/param.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/systm.h>
+#include <sys/smp.h>
+
+#include <machine/machdep.h>
+#include <machine/platform.h>
+#include <machine/platformvar.h>
+#include <machine/smp.h>
+#include <machine/vmparam.h>
+
+/**
+ * @defgroup PLATFORM platform - KObj methods for ARM platform
+ * implementations
+ * @brief A set of methods required by all platform implementations.
+ * These are used to bring up secondary CPUs, supply the physical memory
+ * map, etc.
+ *@{
+ */
+
+INTERFACE platform;
+
+#
+# Default implementations
+#
+CODE {
+ static void platform_null_attach(platform_t plat)
+ {
+ return;
+ }
+};
+
+/**
+ * @brief Probe for whether we are on this platform, returning the standard
+ * newbus probe codes. If we have Open Firmware or a flattened device tree,
+ * it is guaranteed to be available at this point.
+ */
+METHOD int probe {
+ platform_t _plat;
+};
+
+/**
+ * @brief Attach this platform module. This happens before the MMU is online,
+ * so the platform module can install its own high-priority MMU module at
+ * this point.
+ */
+METHOD int attach {
+ platform_t _plat;
+} DEFAULT platform_null_attach;
+
+/**
+ * @brief Called as one of the last steps of early virtual memory
+ * initialization, shortly before the new page tables are installed.
+ */
+METHOD int devmap_init {
+ platform_t _plat;
+};
+
+/**
+ * @brief Called after devmap_init(), and must return the address of the
+ * first byte of unusable KVA space. This allows a platform to carve out
+ * of the top of the KVA space whatever reserves it needs for things like
+ * static device mapping, and this is called to get the value before
+ * calling pmap_bootstrap() which uses the value to size the available KVA.
+ */
+METHOD vm_offset_t lastaddr {
+ platform_t _plat;
+};
+
+/**
+ * @brief Called after the static device mappings are established and just
+ * before cninit(). The intention is that the routine can do any hardware
+ * setup (such as gpio or pinmux) necessary to make the console functional.
+ */
+METHOD void gpio_init {
+ platform_t _plat;
+};
+
+/**
+ * @brief Called just after cninit(). This is the first of the init
+ * routines that can use printf() and expect the output to appear on
+ * a standard console.
+ */
+METHOD void late_init {
+ platform_t _plat;
+};
+
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_machdep.c b/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
index 0f13a79bf93f..0571c55208b3 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_machdep.c
@@ -54,31 +54,24 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
+#include <machine/platformvar.h>
#include <dev/fdt/fdt_common.h>
#include <arm/broadcom/bcm2835/bcm2835_wdog.h>
-vm_offset_t
-initarm_lastaddr(void)
-{
-
- return (arm_devmap_lastaddr());
-}
+#include "platform_if.h"
-void
-initarm_early_init(void)
+static vm_offset_t
+bcm2835_lastaddr(platform_t plat)
{
+ return (arm_devmap_lastaddr());
}
-void
-initarm_gpio_init(void)
-{
-}
-
-void
-initarm_late_init(void)
+static void
+bcm2835_late_init(platform_t plat)
{
phandle_t system;
pcell_t cells[2];
@@ -101,8 +94,8 @@ initarm_late_init(void)
* All on-chip peripherals exist in a 16MB range starting at 0x20000000.
* Map the entire range using 1MB section mappings.
*/
-int
-initarm_devmap_init(void)
+static int
+bcm2835_devmap_init(platform_t plat)
{
arm_devmap_add_entry(0x20000000, 0x01000000);
@@ -129,4 +122,13 @@ cpu_reset()
bcmwd_watchdog_reset();
while (1);
}
+static platform_method_t bcm2835_methods[] = {
+ PLATFORMMETHOD(platform_devmap_init, bcm2835_devmap_init),
+ PLATFORMMETHOD(platform_lastaddr, bcm2835_lastaddr),
+ PLATFORMMETHOD(platform_late_init, bcm2835_late_init),
+
+ PLATFORMMETHOD_END,
+};
+
+FDT_PLATFORM_DEF(bcm2835, "bcm2835", 0, "raspberrypi,model-b");
diff --git a/sys/arm/conf/RPI-B b/sys/arm/conf/RPI-B
index c2b8e0d8ee70..57775d1a71c1 100644
--- a/sys/arm/conf/RPI-B
+++ b/sys/arm/conf/RPI-B
@@ -59,6 +59,7 @@ options KBD_INSTALL_CDEV # install a CDEV entry in /dev
#options ROOTDEVNAME=\"ufs:mmcsd0s2\"
options PREEMPTION
+options PLATFORM
device bpf
device loop
diff --git a/sys/arm/freescale/imx/imx51_machdep.c b/sys/arm/freescale/imx/imx51_machdep.c
index 53a722ada30a..8ab6541e2e43 100644
--- a/sys/arm/freescale/imx/imx51_machdep.c
+++ b/sys/arm/freescale/imx/imx51_machdep.c
@@ -39,18 +39,19 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <arm/freescale/imx/imx_machdep.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
/* XXX - Get rid of this stuff soon. */
@@ -59,13 +60,13 @@ initarm_early_init(void)
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -78,7 +79,7 @@ initarm_late_init(void)
* Notably missing are entries for GPU, IPU, in general anything video related.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(0x70000000, 0x00100000);
diff --git a/sys/arm/freescale/imx/imx53_machdep.c b/sys/arm/freescale/imx/imx53_machdep.c
index 50d8d5240ba0..ebf09d9af8b9 100644
--- a/sys/arm/freescale/imx/imx53_machdep.c
+++ b/sys/arm/freescale/imx/imx53_machdep.c
@@ -39,17 +39,19 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
+
#include <arm/freescale/imx/imx_machdep.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
/* XXX - Get rid of this stuff soon. */
@@ -58,13 +60,13 @@ initarm_early_init(void)
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -77,7 +79,7 @@ initarm_late_init(void)
* Notably missing are entries for GPU, IPU, in general anything video related.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(0x50000000, 0x00100000);
diff --git a/sys/arm/freescale/imx/imx6_machdep.c b/sys/arm/freescale/imx/imx6_machdep.c
index c1074d02e954..eb69eda0f2c3 100644
--- a/sys/arm/freescale/imx/imx6_machdep.c
+++ b/sys/arm/freescale/imx/imx6_machdep.c
@@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <arm/arm/mpcore_timervar.h>
#include <arm/freescale/imx/imx6_anatopreg.h>
@@ -46,14 +47,14 @@ __FBSDID("$FreeBSD$");
#include <arm/freescale/imx/imx_machdep.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
/* Inform the MPCore timer driver that its clock is variable. */
@@ -61,13 +62,13 @@ initarm_early_init(void)
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -89,7 +90,7 @@ initarm_late_init(void)
* as OCRAM that probably shouldn't be mapped as PTE_DEVICE memory.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
const uint32_t IMX6_ARMMP_PHYS = 0x00a00000;
const uint32_t IMX6_ARMMP_SIZE = 0x00100000;
diff --git a/sys/arm/freescale/vybrid/vf_machdep.c b/sys/arm/freescale/vybrid/vf_machdep.c
index 29e7355ada13..76018dd7d7b9 100644
--- a/sys/arm/freescale/vybrid/vf_machdep.c
+++ b/sys/arm/freescale/vybrid/vf_machdep.c
@@ -41,36 +41,37 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <dev/fdt/fdt_common.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(0x40000000, 0x100000);
diff --git a/sys/arm/include/machdep.h b/sys/arm/include/machdep.h
index 8c7aaab3f353..907270ebd2a0 100644
--- a/sys/arm/include/machdep.h
+++ b/sys/arm/include/machdep.h
@@ -34,40 +34,6 @@ vm_offset_t fake_preload_metadata(struct arm_boot_params *abp);
vm_offset_t parse_boot_param(struct arm_boot_params *abp);
void arm_generic_initclocks(void);
-/*
- * Initialization functions called by the common initarm() function in
- * arm/machdep.c (but not necessarily from the custom initarm() functions of
- * older code).
- *
- * - initarm_early_init() is called very early, after parsing the boot params
- * and after physical memory has been located and sized.
- *
- * - initarm_devmap_init() is called as one of the last steps of early virtual
- * memory initialization, shortly before the new page tables are installed.
- *
- * - initarm_lastaddr() is called after initarm_devmap_init(), and must return
- * the address of the first byte of unusable KVA space. This allows a
- * platform to carve out of the top of the KVA space whatever reserves it
- * needs for things like static device mapping, and this is called to get the
- * value before calling pmap_bootstrap() which uses the value to size the
- * available KVA.
- *
- * - initarm_gpio_init() is called after the static device mappings are
- * established and just before cninit(). The intention is that the routine
- * can do any hardware setup (such as gpio or pinmux) necessary to make the
- * console functional.
- *
- * - initarm_late_init() is called just after cninit(). This is the first of
- * the init routines that can use printf() and expect the output to appear on
- * a standard console.
- *
- */
-void initarm_early_init(void);
-int initarm_devmap_init(void);
-vm_offset_t initarm_lastaddr(void);
-void initarm_gpio_init(void);
-void initarm_late_init(void);
-
/* Board-specific attributes */
void board_set_serial(uint64_t);
void board_set_revision(uint32_t);
diff --git a/sys/arm/include/platform.h b/sys/arm/include/platform.h
new file mode 100644
index 000000000000..d4db0e1fd4c7
--- /dev/null
+++ b/sys/arm/include/platform.h
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2014 Andrew Turner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_PLATFORM_H_
+#define _MACHINE_PLATFORM_H_
+
+void platform_probe_and_attach(void);
+int platform_devmap_init(void);
+vm_offset_t platform_lastaddr(void);
+void platform_gpio_init(void);
+void platform_late_init(void);
+
+#endif /* _MACHINE_PLATFORM_H_ */
diff --git a/sys/arm/include/platformvar.h b/sys/arm/include/platformvar.h
new file mode 100644
index 000000000000..a2e1989da644
--- /dev/null
+++ b/sys/arm/include/platformvar.h
@@ -0,0 +1,104 @@
+/*-
+ * Copyright (c) 2005 Peter Grehan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _MACHINE_PLATFORMVAR_H_
+#define _MACHINE_PLATFORMVAR_H_
+
+/*
+ * An ARM platform implementation is declared with a kernel object and
+ * an associated method table, similar to a device driver.
+ *
+ * e.g.
+ *
+ * static platform_method_t bcm2835_methods[] = {
+ * PLATFORMMETHOD(platform_probe, bcm2835_probe),
+ * ...
+ * PLATFORMMETHOD_END
+ * };
+ *
+ * static platform_def_t bcm3835_platform = {
+ * "bcm2835",
+ * bcm2835_methods,
+ * sizeof(bcm2835_platform_softc), // or 0 if no softc
+ * };
+ *
+ * PLATFORM_DEF(bcm2835_platform);
+ */
+
+#include <sys/kobj.h>
+#include <sys/linker_set.h>
+
+struct platform_kobj {
+ /*
+ * A platform instance is a kernel object
+ */
+ KOBJ_FIELDS;
+
+ /* Platform class, for access to class specific data */
+ struct kobj_class *cls;
+};
+
+typedef struct platform_kobj *platform_t;
+typedef struct kobj_class platform_def_t;
+#define platform_method_t kobj_method_t
+
+#define PLATFORMMETHOD KOBJMETHOD
+#define PLATFORMMETHOD_END KOBJMETHOD_END
+
+#define PLATFORM_DEF(name) DATA_SET(platform_set, name)
+
+#ifdef FDT
+struct fdt_platform_class {
+ KOBJ_CLASS_FIELDS;
+
+ const char *fdt_compatible;
+};
+
+typedef struct fdt_platform_class fdt_platform_def_t;
+
+extern platform_method_t fdt_platform_methods[];
+
+#define FDT_PLATFORM_DEF(NAME, NAME_STR, size, compatible) \
+static fdt_platform_def_t NAME ## _fdt_platform = { \
+ .name = NAME_STR, \
+ .methods = fdt_platform_methods, \
+ .fdt_compatible = compatible, \
+}; \
+static kobj_class_t NAME ## _baseclasses[] = \
+ { (kobj_class_t)&NAME ## _fdt_platform, NULL }; \
+static platform_def_t NAME ## _platform = { \
+ NAME_STR, \
+ NAME ## _methods, \
+ size, \
+ NAME ## _baseclasses, \
+}; \
+DATA_SET(platform_set, NAME ## _platform)
+
+#endif
+
+#endif /* _MACHINE_PLATFORMVAR_H_ */
diff --git a/sys/arm/lpc/lpc_machdep.c b/sys/arm/lpc/lpc_machdep.c
index 9219c2fe3096..ecef7db5677e 100644
--- a/sys/arm/lpc/lpc_machdep.c
+++ b/sys/arm/lpc/lpc_machdep.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <machine/fdt.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <arm/lpc/lpcreg.h>
#include <arm/lpc/lpcvar.h>
@@ -60,19 +61,19 @@ __FBSDID("$FreeBSD$");
#include <dev/fdt/fdt_common.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
/*
@@ -82,7 +83,7 @@ initarm_gpio_init(void)
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -92,7 +93,7 @@ initarm_late_init(void)
* dts file when this code was converted to arm_devmap_add_entry().
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(LPC_DEV_PHYS_BASE, LPC_DEV_SIZE);
diff --git a/sys/arm/mv/mv_machdep.c b/sys/arm/mv/mv_machdep.c
index 0c3e18db0057..edd08340a104 100644
--- a/sys/arm/mv/mv_machdep.c
+++ b/sys/arm/mv/mv_machdep.c
@@ -53,6 +53,7 @@ __FBSDID("$FreeBSD$");
#include <machine/devmap.h>
#include <machine/fdt.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <arm/mv/mvreg.h> /* XXX */
#include <arm/mv/mvvar.h> /* XXX eventually this should be eliminated */
@@ -201,14 +202,14 @@ moveon:
}
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (fdt_immr_va);
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
if (fdt_immr_addr(MV_BASE) != 0)
@@ -216,7 +217,7 @@ initarm_early_init(void)
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
/*
@@ -228,7 +229,7 @@ initarm_gpio_init(void)
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
/*
* Re-initialise decode windows
@@ -297,7 +298,7 @@ out:
* Supply a default do-nothing implementation of mv_pci_devmap() via a weak
* alias. Many Marvell platforms don't support a PCI interface, but to support
* those that do, we end up with a reference to this function below, in
- * initarm_devmap_init(). If "device pci" appears in the kernel config, the
+ * platform_devmap_init(). If "device pci" appears in the kernel config, the
* real implementation of this function in arm/mv/mv_pci.c overrides the weak
* alias defined here.
*/
@@ -321,7 +322,7 @@ __weak_reference(mv_default_fdt_pci_devmap, mv_pci_devmap);
* Construct pmap_devmap[] with DT-derived config data.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
phandle_t root, child;
pcell_t bank_count;
diff --git a/sys/arm/rockchip/rk30xx_machdep.c b/sys/arm/rockchip/rk30xx_machdep.c
index 43160738b956..8a21883a223d 100644
--- a/sys/arm/rockchip/rk30xx_machdep.c
+++ b/sys/arm/rockchip/rk30xx_machdep.c
@@ -46,31 +46,32 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <dev/fdt/fdt_common.h>
#include <arm/rockchip/rk30xx_wdog.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
/* Enable cache */
@@ -82,7 +83,7 @@ initarm_late_init(void)
* Set up static device mappings.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(0x10000000, 0x00200000);
diff --git a/sys/arm/samsung/exynos/exynos5_machdep.c b/sys/arm/samsung/exynos/exynos5_machdep.c
index c10ccab809e0..24fd3f445464 100644
--- a/sys/arm/samsung/exynos/exynos5_machdep.c
+++ b/sys/arm/samsung/exynos/exynos5_machdep.c
@@ -41,36 +41,37 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <dev/fdt/fdt_common.h>
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
/* UART */
diff --git a/sys/arm/tegra/tegra2_machdep.c b/sys/arm/tegra/tegra2_machdep.c
index bd639aec1e2d..e9c5ae138ce9 100644
--- a/sys/arm/tegra/tegra2_machdep.c
+++ b/sys/arm/tegra/tegra2_machdep.c
@@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <dev/fdt/fdt_common.h>
@@ -99,24 +100,24 @@ tegra2_osc_freq_detect(void)
#endif
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -126,7 +127,7 @@ initarm_late_init(void)
* before conversion to the newer arm_devmap_add_entry() routine.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(0x70000000, 0x00100000);
diff --git a/sys/arm/ti/ti_machdep.c b/sys/arm/ti/ti_machdep.c
index 6b8b2ffad06a..98d92dfd1152 100644
--- a/sys/arm/ti/ti_machdep.c
+++ b/sys/arm/ti/ti_machdep.c
@@ -51,30 +51,31 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <arm/ti/omap4/omap4_reg.h>
void (*ti_cpu_reset)(void) = NULL;
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -83,7 +84,7 @@ initarm_late_init(void)
* peripherals using 1mb section mappings.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
#if defined(SOC_OMAP4)
arm_devmap_add_entry(0x48000000, 0x01000000); /*16mb L4_PER devices */
diff --git a/sys/arm/versatile/versatile_machdep.c b/sys/arm/versatile/versatile_machdep.c
index 0be0ad51027a..ef531e142e51 100644
--- a/sys/arm/versatile/versatile_machdep.c
+++ b/sys/arm/versatile/versatile_machdep.c
@@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <dev/fdt/fdt_common.h>
@@ -58,25 +59,25 @@ __FBSDID("$FreeBSD$");
#define DEVMAP_BOOTSTRAP_MAP_START 0xE0000000
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (DEVMAP_BOOTSTRAP_MAP_START);
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -91,7 +92,7 @@ static struct arm_devmap_entry fdt_devmap[FDT_DEVMAP_MAX] = {
* Construct pmap_devmap[] with DT-derived config data.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
int i = 0;
fdt_devmap[i].pd_va = 0xf0100000;
diff --git a/sys/arm/xilinx/zy7_machdep.c b/sys/arm/xilinx/zy7_machdep.c
index e7ffaa49ca75..5fb5788028cb 100644
--- a/sys/arm/xilinx/zy7_machdep.c
+++ b/sys/arm/xilinx/zy7_machdep.c
@@ -51,31 +51,32 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <machine/devmap.h>
#include <machine/machdep.h>
+#include <machine/platform.h>
#include <arm/xilinx/zy7_reg.h>
void (*zynq7_cpu_reset)(void);
vm_offset_t
-initarm_lastaddr(void)
+platform_lastaddr(void)
{
return (arm_devmap_lastaddr());
}
void
-initarm_early_init(void)
+platform_probe_and_attach(void)
{
}
void
-initarm_gpio_init(void)
+platform_gpio_init(void)
{
}
void
-initarm_late_init(void)
+platform_late_init(void)
{
}
@@ -85,7 +86,7 @@ initarm_late_init(void)
* nice efficient 1MB section mappings.
*/
int
-initarm_devmap_init(void)
+platform_devmap_init(void)
{
arm_devmap_add_entry(ZYNQ7_PSIO_HWBASE, ZYNQ7_PSIO_SIZE);
diff --git a/sys/conf/files.arm b/sys/conf/files.arm
index ef709f3aa5c7..7243c1775882 100644
--- a/sys/conf/files.arm
+++ b/sys/conf/files.arm
@@ -36,6 +36,8 @@ arm/arm/nexus.c standard
arm/arm/physmem.c standard
arm/arm/pl190.c optional pl190
arm/arm/pl310.c optional pl310
+arm/arm/platform.c optional platform
+arm/arm/platform_if.m optional platform
arm/arm/pmap.c optional cpu_arm9 | cpu_arm9e | cpu_fa526 | cpu_xscale_80219 | cpu_xscale_80321 | cpu_xscale_81342 | cpu_xscale_ixp425 | cpu_xscale_ixp435 | cpu_xscale_pxa2x0
arm/arm/pmap-v6.c optional cpu_arm1136 | cpu_arm1176 | cpu_cortexa | cpu_mv_pj4b | cpu_krait
arm/arm/sc_machdep.c optional sc
@@ -61,6 +63,7 @@ cddl/compat/opensolaris/kern/opensolaris_atomic.c optional zfs compile-with "${Z
crypto/blowfish/bf_enc.c optional crypto | ipsec
crypto/des/des_enc.c optional crypto | ipsec | netsmb
dev/fb/fb.c optional sc
+dev/fdt/fdt_arm_platform.c optional platform fdt
dev/hwpmc/hwpmc_arm.c optional hwpmc
dev/kbd/kbd.c optional sc | vt
dev/syscons/scgfbrndr.c optional sc
diff --git a/sys/conf/options.arm b/sys/conf/options.arm
index 4df2b9d11ee2..fd32e52e854d 100644
--- a/sys/conf/options.arm
+++ b/sys/conf/options.arm
@@ -31,6 +31,7 @@ KERNVIRTADDR opt_global.h
LINUX_BOOT_ABI opt_global.h
LOADERRAMADDR opt_global.h
PHYSADDR opt_global.h
+PLATFORM opt_global.h
SOCDEV_PA opt_global.h
SOCDEV_VA opt_global.h
PV_STATS opt_pmap.h
diff --git a/sys/dev/fdt/fdt_arm_platform.c b/sys/dev/fdt/fdt_arm_platform.c
new file mode 100644
index 000000000000..22e935b146f3
--- /dev/null
+++ b/sys/dev/fdt/fdt_arm_platform.c
@@ -0,0 +1,72 @@
+/*-
+ * Copyright (c) 2013 Andrew Turner
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <arm/include/platform.h>
+#include <arm/include/platformvar.h>
+
+#include <dev/ofw/openfirm.h>
+#include <dev/fdt/fdt_common.h>
+
+#include "platform_if.h"
+
+#define FDT_PLATFORM(plat) \
+ ((fdt_platform_def_t *)(plat)->cls->baseclasses[0])
+
+static int
+fdt_platform_probe(platform_t plat)
+{
+ const char *compat;
+ phandle_t root;
+
+ /*
+ * TODO: Make these KASSERTs, we should only be here if we
+ * are using the FDT platform magic.
+ */
+ if (plat->cls == NULL || FDT_PLATFORM(plat) == NULL)
+ return 1;
+
+ /* Is the device is compatible? */
+ root = OF_finddevice("/");
+ compat = FDT_PLATFORM(plat)->fdt_compatible;
+ if (fdt_is_compatible(root, compat) != 0)
+ return 0;
+
+ /* Not compatible, return an error */
+ return 1;
+}
+
+platform_method_t fdt_platform_methods[] = {
+ PLATFORMMETHOD(platform_probe, fdt_platform_probe),
+ PLATFORMMETHOD_END
+};
+