Index: head/sys/arm/annapurna/alpine/alpine_machdep.c =================================================================== --- head/sys/arm/annapurna/alpine/alpine_machdep.c (revision 305522) +++ head/sys/arm/annapurna/alpine/alpine_machdep.c (revision 305523) @@ -1,147 +1,108 @@ /*- * Copyright (c) 2013 Ruslan Bukin * Copyright (c) 2015 Semihalf * 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$"); #define _ARM32_BUS_DMA_PRIVATE #include #include #include #include #include #include #include #include #include #include /* For trapframe_t, used in */ #include #include #include #include #include "opt_ddb.h" #include "opt_platform.h" -struct mtx al_dbg_lock; - #define DEVMAP_MAX_VA_ADDRESS 0xF0000000 bus_addr_t al_devmap_pa; bus_addr_t al_devmap_size; -#define AL_NB_SERVICE_OFFSET 0x70000 -#define AL_NB_CCU_OFFSET 0x90000 -#define AL_CCU_SNOOP_CONTROL_IOFAB_0_OFFSET 0x4000 -#define AL_CCU_SNOOP_CONTROL_IOFAB_1_OFFSET 0x5000 -#define AL_CCU_SPECULATION_CONTROL_OFFSET 0x4 - -#define AL_NB_ACF_MISC_OFFSET 0xD0 -#define AL_NB_ACF_MISC_READ_BYPASS (1 << 30) - int alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size); vm_offset_t platform_lastaddr(void) { return (DEVMAP_MAX_VA_ADDRESS); } void platform_probe_and_attach(void) { } void platform_gpio_init(void) { } void platform_late_init(void) { - bus_addr_t reg_baddr; - uint32_t val; - if (!mtx_initialized(&al_dbg_lock)) - mtx_init(&al_dbg_lock, "ALDBG", "ALDBG", MTX_SPIN); - - /* configure system fabric */ - if (bus_space_map(fdtbus_bs_tag, al_devmap_pa, al_devmap_size, 0, - ®_baddr)) - panic("Couldn't map Register Space area"); - - /* do not allow reads to bypass writes to different addresses */ - val = bus_space_read_4(fdtbus_bs_tag, reg_baddr, - AL_NB_SERVICE_OFFSET + AL_NB_ACF_MISC_OFFSET); - val &= ~AL_NB_ACF_MISC_READ_BYPASS; - bus_space_write_4(fdtbus_bs_tag, reg_baddr, - AL_NB_SERVICE_OFFSET + AL_NB_ACF_MISC_OFFSET, val); - - /* enable cache snoop */ - bus_space_write_4(fdtbus_bs_tag, reg_baddr, - AL_NB_CCU_OFFSET + AL_CCU_SNOOP_CONTROL_IOFAB_0_OFFSET, 1); - bus_space_write_4(fdtbus_bs_tag, reg_baddr, - AL_NB_CCU_OFFSET + AL_CCU_SNOOP_CONTROL_IOFAB_1_OFFSET, 1); - - /* disable speculative fetches from masters */ - bus_space_write_4(fdtbus_bs_tag, reg_baddr, - AL_NB_CCU_OFFSET + AL_CCU_SPECULATION_CONTROL_OFFSET, 7); - - bus_space_unmap(fdtbus_bs_tag, reg_baddr, al_devmap_size); } /* * Construct devmap table with DT-derived config data. */ int platform_devmap_init(void) { alpine_get_devmap_base(&al_devmap_pa, &al_devmap_size); devmap_add_entry(al_devmap_pa, al_devmap_size); return (0); } struct arm32_dma_range * bus_dma_get_range(void) { return (NULL); } int bus_dma_get_range_nb(void) { return (0); } Index: head/sys/arm/annapurna/alpine/alpine_machdep_mp.c =================================================================== --- head/sys/arm/annapurna/alpine/alpine_machdep_mp.c (revision 305522) +++ head/sys/arm/annapurna/alpine/alpine_machdep_mp.c (revision 305523) @@ -1,313 +1,248 @@ /*- * Copyright (c) 2013 Ruslan Bukin * Copyright (c) 2015 Semihalf * 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$"); #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define AL_CPU_RESUME_WATERMARK_REG 0x00 #define AL_CPU_RESUME_FLAGS_REG 0x04 #define AL_CPU_RESUME_PCPU_RADDR_REG(cpu) (0x08 + 0x04 + 8*(cpu)) #define AL_CPU_RESUME_PCPU_FLAGS(cpu) (0x08 + 8*(cpu)) /* Per-CPU flags */ #define AL_CPU_RESUME_FLG_PERCPU_DONT_RESUME (1 << 2) /* The expected magic number for validating the resume addresses */ #define AL_CPU_RESUME_MAGIC_NUM 0xf0e1d200 #define AL_CPU_RESUME_MAGIC_NUM_MASK 0xffffff00 /* The expected minimal version number for validating the capabilities */ #define AL_CPU_RESUME_MIN_VER 0x000000c3 #define AL_CPU_RESUME_MIN_VER_MASK 0x000000ff /* Field controlling the boot-up of companion cores */ #define AL_NB_INIT_CONTROL (0x8) #define AL_NB_CONFIG_STATUS_PWR_CTRL(cpu) (0x2020 + (cpu)*0x100) -#define SERDES_NUM_GROUPS 4 -#define SERDES_GROUP_SIZE 0x400 - extern bus_addr_t al_devmap_pa; extern bus_addr_t al_devmap_size; extern void mpentry(void); -int alpine_serdes_resource_get(uint32_t group, bus_space_tag_t *tag, - bus_addr_t *baddr); static int platform_mp_get_core_cnt(void); static int alpine_get_cpu_resume_base(u_long *pbase, u_long *psize); static int alpine_get_nb_base(u_long *pbase, u_long *psize); -static int alpine_get_serdes_base(u_long *pbase, u_long *psize); -int alpine_serdes_resource_get(uint32_t group, bus_space_tag_t *tag, - bus_addr_t *baddr); static boolean_t alpine_validate_cpu(u_int, phandle_t, u_int, pcell_t *); static boolean_t alpine_validate_cpu(u_int id, phandle_t child, u_int addr_cell, pcell_t *reg) { return fdt_is_compatible(child, "arm,cortex-a15"); } static int platform_mp_get_core_cnt(void) { static int ncores = 0; int nchilds; uint32_t reg; /* Calculate ncores value only once */ if (ncores) return (ncores); reg = cp15_l2ctlr_get(); ncores = CPUV7_L2CTLR_NPROC(reg); nchilds = ofw_cpu_early_foreach(alpine_validate_cpu, false); /* Limit CPUs if DTS has configured less than available */ if ((nchilds > 0) && (nchilds < ncores)) { printf("SMP: limiting number of active CPUs to %d out of %d\n", nchilds, ncores); ncores = nchilds; } return (ncores); } void platform_mp_setmaxid(void) { mp_ncpus = platform_mp_get_core_cnt(); mp_maxid = mp_ncpus - 1; } static int alpine_get_cpu_resume_base(u_long *pbase, u_long *psize) { phandle_t node; u_long base = 0; u_long size = 0; if (pbase == NULL || psize == NULL) return (EINVAL); if ((node = OF_finddevice("/")) == -1) return (EFAULT); if ((node = ofw_bus_find_compatible(node, "annapurna-labs,al-cpu-resume")) == 0) return (EFAULT); if (fdt_regsize(node, &base, &size)) return (EFAULT); *pbase = base; *psize = size; return (0); } static int alpine_get_nb_base(u_long *pbase, u_long *psize) { phandle_t node; u_long base = 0; u_long size = 0; if (pbase == NULL || psize == NULL) return (EINVAL); if ((node = OF_finddevice("/")) == -1) return (EFAULT); if ((node = ofw_bus_find_compatible(node, "annapurna-labs,al-nb-service")) == 0) return (EFAULT); if (fdt_regsize(node, &base, &size)) return (EFAULT); *pbase = base; *psize = size; return (0); } void platform_mp_start_ap(void) { uint32_t physaddr; vm_offset_t vaddr; uint32_t val; uint32_t start_mask; u_long cpu_resume_base; u_long nb_base; u_long cpu_resume_size; u_long nb_size; bus_addr_t cpu_resume_baddr; bus_addr_t nb_baddr; int a; if (alpine_get_cpu_resume_base(&cpu_resume_base, &cpu_resume_size)) panic("Couldn't resolve cpu_resume_base address\n"); if (alpine_get_nb_base(&nb_base, &nb_size)) panic("Couldn't resolve_nb_base address\n"); /* Proceed with start addresses for additional CPUs */ if (bus_space_map(fdtbus_bs_tag, al_devmap_pa + cpu_resume_base, cpu_resume_size, 0, &cpu_resume_baddr)) panic("Couldn't map CPU-resume area"); if (bus_space_map(fdtbus_bs_tag, al_devmap_pa + nb_base, nb_size, 0, &nb_baddr)) panic("Couldn't map NB-service area"); /* Proceed with start addresses for additional CPUs */ val = bus_space_read_4(fdtbus_bs_tag, cpu_resume_baddr, AL_CPU_RESUME_WATERMARK_REG); if (((val & AL_CPU_RESUME_MAGIC_NUM_MASK) != AL_CPU_RESUME_MAGIC_NUM) || ((val & AL_CPU_RESUME_MIN_VER_MASK) < AL_CPU_RESUME_MIN_VER)) { panic("CPU-resume device is not compatible"); } vaddr = (vm_offset_t)mpentry; physaddr = pmap_kextract(vaddr); for (a = 1; a < platform_mp_get_core_cnt(); a++) { /* Power up the core */ bus_space_write_4(fdtbus_bs_tag, nb_baddr, AL_NB_CONFIG_STATUS_PWR_CTRL(a), 0); mb(); /* Enable resume */ val = bus_space_read_4(fdtbus_bs_tag, cpu_resume_baddr, AL_CPU_RESUME_PCPU_FLAGS(a)); val &= ~AL_CPU_RESUME_FLG_PERCPU_DONT_RESUME; bus_space_write_4(fdtbus_bs_tag, cpu_resume_baddr, AL_CPU_RESUME_PCPU_FLAGS(a), val); mb(); /* Set resume physical address */ bus_space_write_4(fdtbus_bs_tag, cpu_resume_baddr, AL_CPU_RESUME_PCPU_RADDR_REG(a), physaddr); mb(); } /* Release cores from reset */ if (bus_space_map(fdtbus_bs_tag, al_devmap_pa + nb_base, nb_size, 0, &nb_baddr)) panic("Couldn't map NB-service area"); start_mask = (1 << platform_mp_get_core_cnt()) - 1; /* Release cores from reset */ val = bus_space_read_4(fdtbus_bs_tag, nb_baddr, AL_NB_INIT_CONTROL); val |= start_mask; bus_space_write_4(fdtbus_bs_tag, nb_baddr, AL_NB_INIT_CONTROL, val); dsb(); bus_space_unmap(fdtbus_bs_tag, nb_baddr, nb_size); bus_space_unmap(fdtbus_bs_tag, cpu_resume_baddr, cpu_resume_size); -} - -static int -alpine_get_serdes_base(u_long *pbase, u_long *psize) -{ - phandle_t node; - u_long base = 0; - u_long size = 0; - - if (pbase == NULL || psize == NULL) - return (EINVAL); - - if ((node = OF_finddevice("/")) == -1) - return (EFAULT); - - if ((node = - ofw_bus_find_compatible(node, "annapurna-labs,al-serdes")) == 0) - return (EFAULT); - - if (fdt_regsize(node, &base, &size)) - return (EFAULT); - - *pbase = base; - *psize = size; - - return (0); -} - -int -alpine_serdes_resource_get(uint32_t group, bus_space_tag_t *tag, bus_addr_t *baddr) -{ - u_long serdes_base, serdes_size; - int ret; - static bus_addr_t baddr_mapped[SERDES_NUM_GROUPS]; - - if (group >= SERDES_NUM_GROUPS) - return (EINVAL); - - if (baddr_mapped[group]) { - *tag = fdtbus_bs_tag; - *baddr = baddr_mapped[group]; - return (0); - } - - ret = alpine_get_serdes_base(&serdes_base, &serdes_size); - if (ret) - return (ret); - - ret = bus_space_map(fdtbus_bs_tag, - al_devmap_pa + serdes_base + group * SERDES_GROUP_SIZE, - (SERDES_NUM_GROUPS - group) * SERDES_GROUP_SIZE, 0, baddr); - if (ret) - return (ret); - - baddr_mapped[group] = *baddr; - - return (0); } Index: head/sys/arm/conf/ALPINE =================================================================== --- head/sys/arm/conf/ALPINE (revision 305522) +++ head/sys/arm/conf/ALPINE (revision 305523) @@ -1,71 +1,75 @@ # Kernel configuration for Alpine Board. # # For more information on this file, please read the config(5) manual page, # and/or the handbook section on Kernel Configuration Files: # # http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html # # The handbook is also available locally in /usr/share/doc/handbook # if you've installed the doc distribution, otherwise always see the # FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the # latest information. # # An exhaustive list of options and more detailed explanations of the # device lines is also present in the ../../conf/NOTES and NOTES files. # If you are in doubt as to the purpose or necessity of a line, check first # in NOTES. # # $FreeBSD$ ident ALPINE include "std.armv6" include "../annapurna/alpine/std.alpine" makeoptions MODULES_OVERRIDE="" makeoptions WERROR="-Werror" options SCHED_4BSD # 4BSD scheduler options SMP # Enable multiple cores # Interrupt controller device gic options INTRNG +# Annapurna Alpine drivers +device al_ccu # Alpine Cache Coherency Unit +device al_nb_service # Alpine North Bridge Service + # Pseudo devices device loop device random device pty device md device gpio # ATA controllers device ahci # AHCI-compatible SATA controllers device ata # Legacy ATA/SATA controllers # ATA/SCSI peripherals device scbus # SCSI bus (required for ATA/SCSI) device ch # SCSI media changers device da # Direct Access (disks) device sa # Sequential Access (tape etc) device cd # CD device pass # Passthrough device (direct ATA/SCSI access) device ses # Enclosure Services (SES and SAF-TE) #device ctl # CAM Target Layer # Serial ports device uart # Ethernet device ether device mii device bpf options DEVICE_POLLING # USB ethernet support, requires miibus device miibus #FDT options FDT options FDT_DTB_STATIC makeoptions FDT_DTS_FILE=annapurna-alpine.dts