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 #include #include +#include #include #include 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 #include #include +#include #include #include #include @@ -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 +__FBSDID("$FreeBSD$"); + +/* + * Dispatch platform calls to the appropriate platform implementation + * through a previously registered kernel object. + */ + +#define _ARM32_BUS_DMA_PRIVATE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +/** + * @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 #include #include +#include +#include #include #include -vm_offset_t -initarm_lastaddr(void) +#include "platform_if.h" + +static vm_offset_t +bcm2835_lastaddr(platform_t plat) { return (arm_devmap_lastaddr()); } -void -initarm_early_init(void) -{ - -} - -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 #include #include +#include #include 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 #include #include +#include + #include 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 #include #include +#include #include #include @@ -46,14 +47,14 @@ __FBSDID("$FreeBSD$"); #include 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 #include #include +#include #include 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 +#include + +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 #include #include +#include #include #include @@ -60,19 +61,19 @@ __FBSDID("$FreeBSD$"); #include 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 #include #include +#include #include /* XXX */ #include /* XXX eventually this should be eliminated */ @@ -201,14 +202,14 @@ platform_mpp_init(void) } 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 @@ platform_sram_devmap(struct arm_devmap_entry *map) * 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 #include #include +#include #include #include 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 #include #include +#include #include 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 #include #include +#include #include @@ -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 #include #include +#include #include 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 #include #include +#include #include @@ -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 #include #include +#include #include 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 +__FBSDID("$FreeBSD$"); + +#include + +#include +#include + +#include +#include + +#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 +}; +