Index: sys/mips/broadcom/bcm_machdep.c =================================================================== --- /dev/null +++ sys/mips/broadcom/bcm_machdep.c @@ -0,0 +1,220 @@ +/*- + * Copyright (c) 2007 Bruce M. Simpson. + * 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 "opt_ddb.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "bcm_socinfo.h" + +#ifdef CFE +#include +#endif + +//#define BROADCOM_TRACE 0 + +extern int *edata; +extern int *end; + +void +platform_cpu_init() +{ + /* Nothing special */ +} + +static void +mips_init(void) +{ + int i, j; + + printf("entry: mips_init()\n"); + +#ifdef CFE + /* + * Query DRAM memory map from CFE. + */ + physmem = 0; + for (i = 0; i < 10; i += 2) { + int result; + uint64_t addr, len, type; + + result = cfe_enummem(i / 2, 0, &addr, &len, &type); + if (result < 0) { +#ifdef BROADCOM_TRACE + printf("There is no phys memory for: %d\n", i); +#endif + phys_avail[i] = phys_avail[i + 1] = 0; + break; + } + if (type != CFE_MI_AVAILABLE){ +#ifdef BROADCOM_TRACE + printf("phys memory is not available: %d\n", i); +#endif + continue; + } + + phys_avail[i] = addr; + if (i == 0 && addr == 0) { + /* + * If this is the first physical memory segment probed + * from CFE, omit the region at the start of physical + * memory where the kernel has been loaded. + */ + phys_avail[i] += MIPS_KSEG0_TO_PHYS(kernel_kseg0_end); + } +#ifdef BROADCOM_TRACE + printf("phys memory is available for: %d\n", i); + printf(" => addr = %jx\n", addr); + printf(" => len = %jd\n", len); +#endif + phys_avail[i + 1] = addr + len; + physmem += len; + } + +#ifdef BROADCOM_TRACE + printf("Total phys memory is : %ld\n", physmem); +#endif + + realmem = btoc(physmem); +#endif + + for (j = 0; j < i; j++) + dump_avail[j] = phys_avail[j]; + + physmem = realmem; + + init_param1(); + init_param2(physmem); + mips_cpu_init(); + pmap_bootstrap(); + mips_proc0_init(); + mutex_init(); + kdb_init(); +#ifdef KDB + if (boothowto & RB_KDB) + kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); +#endif +} + +#define BCM_REG_CHIPC 0xb8000000 +#define BCM_REG_CHIPC_PMUWD_OFFS 0x634 + +void +platform_reset(void) +{ + void *pmuwatchdog; + + printf("bcm::platform_reset()\n"); + pmuwatchdog = (void *)(BCM_REG_CHIPC + BCM_REG_CHIPC_PMUWD_OFFS); + intr_disable(); + writel(pmuwatchdog, 2); + for (;;); +} + +void +platform_start(__register_t a0, __register_t a1, __register_t a2, + __register_t a3) +{ + vm_offset_t kernend; + uint64_t platform_counter_freq; + + /* clear the BSS and SBSS segments */ + kernend = (vm_offset_t)&end; + memset(&edata, 0, kernend - (vm_offset_t)(&edata)); + + mips_postboot_fixup(); + + /* Initialize pcpu stuff */ + mips_pcpu0_init(); + + struct bcm_socinfo* socinfo; + bcm_get_socinfo(&socinfo); + platform_counter_freq = socinfo->cpurate * 1000 * 1000; /* BCM4718 is 480MHz */ + + mips_timer_early_init(platform_counter_freq); + +#ifdef CFE + /* + * Initialize CFE firmware trampolines before + * we initialize the low-level console. + * + * CFE passes the following values in registers: + * a0: firmware handle + * a2: firmware entry point + * a3: entry point seal + */ + if (a3 == CFE_EPTSEAL) + cfe_init(a0, a2); +#endif + cninit(); + + mips_init(); + + /* BCM471x timer is 1/2 of Clk */ + mips_timer_init_params(platform_counter_freq, 1); +} Index: sys/mips/broadcom/bcm_socinfo.h =================================================================== --- /dev/null +++ sys/mips/broadcom/bcm_socinfo.h @@ -0,0 +1,24 @@ +/* + * bcm_socinfo.h + * + * Created on: Apr 19, 2016 + * Author: mizhka + */ + +#pragma once + +#include + +struct bcm_socinfo { + uint32_t id; + uint32_t cpurate; //MHz + uint32_t uartrate; //Hz +}; + +struct bcm_socinfo* bcm_lookup_by_socid(uint32_t key); +void bcm_get_socinfo(struct bcm_socinfo** socinfo); + +#define BCM_SOCADDR 0x18000000 +#define BCM_READ_SOCREG(reg) BCM_READ_REG(BCM_SOCADDR, reg) +#define BCM_READ_REG(base, reg) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1((base + reg))) + Index: sys/mips/broadcom/bcm_socinfo.c =================================================================== --- /dev/null +++ sys/mips/broadcom/bcm_socinfo.c @@ -0,0 +1,62 @@ +/* + * bcm_socinfo.c + * + * Created on: Apr 19, 2016 + * Author: mizhka + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include "bcm_socinfo.h" + +// found on https://wireless.wiki.kernel.org/en/users/drivers/b43/soc +struct bcm_socinfo bcm_socinfos[] = { + {0x00005300, 600, 25000000}, // BCM4706 - to check + {0x0022B83A, 300, 20000000}, // BCM4716B0 - ASUS RT-N12 + {0x00914716, 354, 20000000}, // BCM4717A1 - to check + {0x00A14716, 480, 20000000}, // BCM4718A1 - ASUS RT-N16 + {0x00435356, 300, 25000000}, // BCM5356A1 - to check (ASUS RT-N10, WNR1000v3) + {0x00825357, 500, 20000000}, // BCM5358UB0 - ASUS RT-N53A1 + {0x00845357, 300, 20000000}, // BCM5357B0 - to check + {0x00945357, 500, 20000000}, // BCM5358 + {0x00A45357, 500, 20000000}, // BCM47186B0 - Tenda N60 + {0x0085D144, 300, 20000000}, // BCM5356C0 - + {0x00B5D144, 300, 20000000}, // BCM5357C0 + {0,0,0} +}; + +// Most popular BCM SoC info +struct bcm_socinfo BCM_DEFAULT_SOCINFO = {0x0, 300, 20000000}; + +struct bcm_socinfo* bcm_lookup_by_socid(uint32_t key){ + if(!key) + return 0; + struct bcm_socinfo* start = bcm_socinfos; + for(start = bcm_socinfos; start->id > 0; start++){ + if(start->id == key) + return start; + } + return 0; +} + +void bcm_get_socinfo(struct bcm_socinfo** socinfo){ + + /* + * We need Chip ID + Revision + Package + * Chip ID + Mask Usage + 0x0000FFFF Chip ID + 0x000F0000 Chip Revision + 0x00F00000 Package Options + 0x0F000000 Number of Cores (ChipCommon Core Revision >= 4) + 0xF0000000 Chip Type + */ + + uint32_t socid = BCM_READ_SOCREG(0) & 0x00FFFFFF; + *socinfo = bcm_lookup_by_socid(socid); + if(!*socinfo) + *socinfo = &BCM_DEFAULT_SOCINFO; +} + Index: sys/mips/broadcom/files.broadcom =================================================================== --- /dev/null +++ sys/mips/broadcom/files.broadcom @@ -0,0 +1,44 @@ +# $FreeBSD$ + +# TODO: Add attachment elsehwere in the tree +# for USB 1.1 OHCI, Ethernet and IPSEC cores +# which are believed to be devices we have drivers for +# which just need to be tweaked for attachment to an SSB system bus. +mips/broadcom/bcm_machdep.c standard +mips/mips/tick.c standard +mips/mips/mips_pic.c standard +kern/subr_intr.c standard +kern/pic_if.m standard + +mips/broadcom/uart_cpu_chipc.c optional uart +mips/broadcom/uart_bus_chipc.c optional uart +mips/broadcom/bcm_socinfo.c standard + +# +geom/geom_flashmap.c standard +# +dev/bhnd/bhnd.c standard +dev/bhnd/bhnd_subr.c standard +dev/bhnd/bhnd_bus_if.m standard +dev/bhnd/bhndb/bhndb_if.m standard +dev/bhnd/bhndb/bhndb_bus_if.m standard +dev/bhnd/bcma/bcma.c standard +dev/bhnd/bcma/bcma_nexus.c standard +#dev/bhnd/bcma/bcma_bhndb.c standard +dev/bhnd/bcma/bcma_erom.c standard +dev/bhnd/bcma/bcma_subr.c standard +dev/bhnd/cores/chipc/chipc_subr.c standard +dev/bhnd/cores/chipc/chipc_cfi.c optional cfi +dev/bhnd/cores/chipc/chipc_spi.c optional spibus +dev/bhnd/cores/chipc/chipc_slicer.c optional cfi | spibus +dev/bhnd/cores/chipc/chipc.c standard +dev/bhnd/cores/chipc/chipcbus.c standard +dev/bhnd/cores/chipc/bhnd_chipc_if.m standard +dev/bhnd/cores/mips/mipscore.c standard +dev/bhnd/nvram/bhnd_nvram_if.m standard +#dev/bhnd/siba/siba.c standard +#dev/bhnd/siba/siba_bhndb.c standard +#dev/bhnd/siba/siba_nexus.c standard +#dev/bhnd/siba/siba_subr.c standard +dev/bhnd/soc/bhnd_soc.c standard +# \ No newline at end of file Index: sys/mips/broadcom/std.broadcom =================================================================== --- /dev/null +++ sys/mips/broadcom/std.broadcom @@ -0,0 +1,10 @@ +# $FreeBSD$ +# + +machine mips mipsel + +cpu CPU_MIPS74K +options CPU_SENTRY5 # XXX should this be a + # sub-cpu option? +files "../broadcom/files.broadcom" + Index: sys/mips/broadcom/uart_bus_chipc.c =================================================================== --- /dev/null +++ sys/mips/broadcom/uart_bus_chipc.c @@ -0,0 +1,80 @@ +/* + * uart_bus_chipc.c + * + * Created on: Apr 3, 2016 + * Author: mizhka + */ + +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "uart_if.h" + +static int uart_chipc_probe(device_t dev); + +extern SLIST_HEAD(uart_devinfo_list, uart_devinfo) uart_sysdevs; +static int +uart_chipc_probe(device_t dev) +{ + struct uart_softc *sc; + + sc = device_get_softc(dev); + + int rid = 0; + struct resource* res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if(res == NULL){ + device_printf(dev, "can't allocate main resource\n"); + return (ENXIO); + } + + sc->sc_class = &uart_ns8250_class; + sc->sc_sysdev = SLIST_FIRST(&uart_sysdevs); + if (sc->sc_sysdev == NULL){ + device_printf(dev, "missing sysdev\n"); + return (EINVAL); + } + + bcopy(&sc->sc_sysdev->bas, &sc->sc_bas, sizeof(sc->sc_bas)); + + sc->sc_sysdev->bas.bst = rman_get_bustag(res); + sc->sc_sysdev->bas.bsh = rman_get_bushandle(res); + sc->sc_bas.bst = sc->sc_sysdev->bas.bst; + sc->sc_bas.bsh = sc->sc_sysdev->bas.bsh; + + bus_release_resource(dev, SYS_RES_MEMORY, rid, res); + + //We use internal SoC clock generator with non-standart freq MHz + return(uart_bus_probe(dev, 0, sc->sc_sysdev->bas.rclk, 0, 0)); +} + +static device_method_t uart_chipc_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, uart_chipc_probe), + DEVMETHOD(device_attach, uart_bus_attach), + DEVMETHOD(device_detach, uart_bus_detach), + { 0, 0 } +}; + +static driver_t uart_chipc_driver = { + uart_driver_name, + uart_chipc_methods, + sizeof(struct uart_softc), +}; + +DRIVER_MODULE(uart, bhnd_chipcbus, uart_chipc_driver, uart_devclass, 0, 0); Index: sys/mips/broadcom/uart_cpu_chipc.c =================================================================== --- /dev/null +++ sys/mips/broadcom/uart_cpu_chipc.c @@ -0,0 +1,63 @@ +/* + * uart_cpu_chipc.c + * + * Created on: Apr 3, 2016 + * Author: mizhka + */ + + +#include "opt_uart.h" + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +bus_space_tag_t uart_bus_space_io; +bus_space_tag_t uart_bus_space_mem; + +int +uart_cpu_eqres(struct uart_bas *b1, struct uart_bas *b2) +{ + return ((b1->bsh == b2->bsh && b1->bst == b2->bst) ? 1 : 0); +} + +int +uart_cpu_getdev(int devtype, struct uart_devinfo *di) +{ + struct uart_class *class; + +// if(devtype == UART_DEV_CONSOLE) +// return 1; + + class = &uart_ns8250_class; +// if (class->uc_rclk == 0 && at91_master_clock != 0) +// class->uc_rclk = at91_master_clock; + di->ops = uart_getops(class); + di->bas.chan = 0; + di->bas.bst = mips_bus_space_generic; + di->bas.bsh = 0xb8000300;//soc_info.dbgu_base; + di->bas.regshft = 0; + di->bas.rclk = 20000000; // depends on SoC, it can be 20MHz or 25MHz + di->baudrate = 115200; + di->databits = 8; + di->stopbits = 1; + di->parity = UART_PARITY_NONE; + uart_bus_space_io = NULL; + uart_bus_space_mem = mips_bus_space_generic; + /* Check the environment for overrides */ + //uart_getenv(devtype, di, class); + return (0); +} Index: sys/mips/conf/BCM =================================================================== --- /dev/null +++ sys/mips/conf/BCM @@ -0,0 +1,113 @@ +# +# $FreeBSD$ +# +# The Broadcom 471x series of processors and boards is very commonly +# used in COTS hardware including the ASUS RT-N16. +# +# Some tweaks are needed for use with this platform: +# +# * CFE firmware's ELF loader expects an ELF kernel which is linked so as +# not to contain offsets in PT_LOAD which point behind the actual offset +# of that PT header. FreeBSD normally links the first PT_LOAD header to +# begin at offset 0. +# +# * Broadcom's support package for the internal bus, successor to the Sonics +# SiliconBackplane called BCMA, needs to be integrated to detect and probe hardware +# correctly. +# +# * The clock needs to be calibrated correctly, so that DELAY() may work. +# One problem with this is that the low-level printf() routine calls DELAY(), +# which currently causes divide-by-zero trap +# +# * The Broadcom CPUs have no FPU. Attempting to detect one by reading CP1's +# status register causes an unhandled boot-time exception. An FPU emulator +# will be necessary to support multi-user boot. +# + +ident BCM + +hints "BCM.hints" +include "../broadcom/std.broadcom" + +# ships with cfe firmware; use the console for now +options CFE +options ALT_BREAK_TO_DEBUGGER +options BREAK_TO_DEBUGGER +options BOOTVERBOSE=0 + +makeoptions INTRNG +options INTRNG + +makeoptions DEBUG="-g3" #Build kernel with gdb(1) debug symbols +makeoptions MODULES_OVERRIDE="" + +options DDB +options KDB + +options SCHED_4BSD #4BSD scheduler +options INET #InterNETworking +options NFSCL #Network Filesystem Client +#options NFS_ROOT #NFS usable as /, requires NFSCL +options PSEUDOFS #Pseudo-filesystem framework +options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions + +options FFS #Berkeley Fast Filesystem +options SOFTUPDATES #Enable FFS soft updates support +options UFS_ACL #Support for access control lists +options UFS_DIRHASH #Improve performance on big directories + +device geom_uzip +options GEOM_UZIP +options GEOM_LABEL # Providers labelization. +options ROOTDEVNAME=\"ufs:ufs/FBSD\" + +# Debugging for use in -current +#options DEADLKRES +options INVARIANTS +options INVARIANT_SUPPORT + +#options BUS_DEBUG +#makeoptions BUS_DEBUG +#options VERBOSE_SYSINIT +#makeoptions VERBOSE_SYSINIT + +device pci + +#device bgmac # Broadcom GMAC + +device mdio + +#Flash +device spibus +device mx25l # Serial Flash +device cfi # Parallel Flash +device cfid + +#Performance +#options HWPMC_HOOKS +#device hwpmc +#device hwpmc_mips74k + +#Ethernet +# device bfe # XXX will build both pci and siba +device miibus # attachments + + +# pci devices + +# USB is not yet ready +#options USB_DEBUG # enable debug msgs +#device usb # USB Bus (required) +#device uhci # UHCI PCI->USB interface +#device ehci # EHCI PCI->USB interface (USB 2.0) + +# need to teach the code to ignore the bridge.... + + +# XXX notyet; need to be auto probed children of siba_cc. +device uart + +device loop +device ether +device random +device md Index: sys/mips/conf/BCM.hints =================================================================== --- /dev/null +++ sys/mips/conf/BCM.hints @@ -0,0 +1,6 @@ +# $FreeBSD$ +hint.bhnd_soc.0.at="nexus0" +# XXX ? +hint.bhnd_soc.0.maddr="0x00000000" +hint.bhnd_soc.0.msize="0x20000000" +